001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.cms.content.consistency; 017 018import java.util.Calendar; 019import java.util.Date; 020import java.util.GregorianCalendar; 021import java.util.Timer; 022import java.util.TimerTask; 023 024import org.apache.avalon.framework.activity.Disposable; 025import org.apache.avalon.framework.activity.Initializable; 026import org.apache.avalon.framework.configuration.Configurable; 027import org.apache.avalon.framework.configuration.Configuration; 028import org.apache.avalon.framework.configuration.ConfigurationException; 029import org.apache.avalon.framework.context.Context; 030import org.apache.avalon.framework.context.ContextException; 031import org.apache.avalon.framework.context.Contextualizable; 032import org.apache.avalon.framework.logger.LogEnabled; 033import org.apache.avalon.framework.logger.Logger; 034import org.apache.avalon.framework.service.ServiceException; 035import org.apache.avalon.framework.service.ServiceManager; 036import org.apache.avalon.framework.service.Serviceable; 037import org.apache.commons.lang.StringUtils; 038 039import org.ametys.runtime.config.Config; 040 041/** 042 * Content consistency scheduler: launches a cron which generates a content consistency report. 043 */ 044public class ContentConsistencyScheduler extends TimerTask implements Initializable, LogEnabled, Serviceable, Disposable, Contextualizable, Configurable 045{ 046 047 /** The service manager. */ 048 protected ServiceManager _manager; 049 050 /** The component configuration. */ 051 protected Configuration _configuration; 052 053 /** The avalon context. */ 054 protected Context _context; 055 056 /** The logger. */ 057 protected Logger _logger; 058 059 /** The timer. */ 060 protected Timer _timer; 061 062 @Override 063 public void service(ServiceManager manager) throws ServiceException 064 { 065 _manager = manager; 066 } 067 068 @Override 069 public void contextualize(Context context) throws ContextException 070 { 071 _context = context; 072 } 073 074 @Override 075 public void configure(Configuration configuration) throws ConfigurationException 076 { 077 _configuration = configuration; 078 } 079 080 @Override 081 public void enableLogging(Logger logger) 082 { 083 _logger = logger; 084 } 085 086 @Override 087 public void initialize() throws Exception 088 { 089 Boolean enabled = Config.getInstance().getValue("consistency.scheduler.enabled"); 090 091 if (enabled != null && enabled) 092 { 093 if (_logger.isDebugEnabled()) 094 { 095 _logger.debug("Initializing the content consistency scheduler..."); 096 } 097 098 // Schedule a timer to run each night. 099 String hourStr = Config.getInstance().getValue("consistency.scheduler.hour"); 100 int hour = 0; 101 int minute = 0; 102 if (StringUtils.isNotEmpty(hourStr) && hourStr.indexOf(':') > 0) 103 { 104 String[] hourArray = StringUtils.split(hourStr, ':'); 105 hour = Integer.parseInt(hourArray[0]); 106 minute = Integer.parseInt(hourArray[1]); 107 } 108 109 GregorianCalendar calendar = new GregorianCalendar(); 110 calendar.set(Calendar.AM_PM, hour < 12 ? Calendar.AM : Calendar.PM); 111 calendar.set(Calendar.HOUR, hour % 12); 112 calendar.set(Calendar.MINUTE, minute); 113 calendar.set(Calendar.SECOND, 0); 114 calendar.set(Calendar.MILLISECOND, 0); 115 116 // Each day. 117 long period = 24 * 60 * 60 * 1000; 118 Date firstTime = calendar.getTime(); 119 120 Date now = new Date(); 121 122 // If the given time today is past, schedule for tomorrow. 123 if (firstTime.compareTo(now) < 0) 124 { 125 calendar.add(Calendar.DAY_OF_MONTH, 1); 126 firstTime = calendar.getTime(); 127 } 128 129 if (_logger.isInfoEnabled()) 130 { 131 _logger.info("Content consistency scheduler: the engine will run each day, starting " + firstTime.toString()); 132 } 133 134 _timer = new Timer("ContentConsistencyScheduler", true); 135 _timer.schedule(this, firstTime, period); 136 } 137 } 138 139 @Override 140 public void run() 141 { 142 ContentConsistencyEngine contentConsistencyEngine = new ContentConsistencyEngine(); 143 144 try 145 { 146 // Initialize and configure the engine. 147 contentConsistencyEngine.initialize(_manager, _context); 148 contentConsistencyEngine.configure(_configuration); 149 } 150 catch (Exception e) 151 { 152 throw new RuntimeException("Unable to initialize the content consistency engine", e); 153 } 154 155 // The thread will be started as daemon, as the scheduler is marked daemon itself. 156 new Thread(contentConsistencyEngine, "ContentConsistencyEngine").start(); 157 } 158 159 @Override 160 public void dispose() 161 { 162 _context = null; 163 _logger = null; 164 _manager = null; 165 _configuration = null; 166 167 cancel(); 168 if (_timer != null) 169 { 170 _timer.cancel(); 171 _timer = null; 172 } 173 } 174 175}