001/* 002 * Copyright 2011 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.workflow.purge; 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 * Purge contents scheduler: launches a cron which purges contents at a given periodicity. 043 */ 044public class PurgeContentsScheduler extends TimerTask implements Initializable, LogEnabled, Serviceable, Disposable, Contextualizable, Configurable 045{ 046 047 /** The default period, in days. */ 048 private static final long _DEFAULT_PERIOD = 7; 049 050 /** The service manager. */ 051 protected ServiceManager _manager; 052 053 /** The component configuration. */ 054 protected Configuration _configuration; 055 056 /** The avalon context. */ 057 protected Context _context; 058 059 /** The logger. */ 060 protected Logger _logger; 061 062 /** The timer. */ 063 protected Timer _timer; 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 _manager = manager; 069 } 070 071 @Override 072 public void contextualize(Context context) throws ContextException 073 { 074 _context = context; 075 } 076 077 @Override 078 public void configure(Configuration configuration) throws ConfigurationException 079 { 080 _configuration = configuration; 081 } 082 083 @Override 084 public void enableLogging(Logger logger) 085 { 086 _logger = logger; 087 } 088 089 @Override 090 public void initialize() throws Exception 091 { 092 if (_logger.isDebugEnabled()) 093 { 094 _logger.debug("Initializing the alert scheduler..."); 095 } 096 097 Boolean enabled = Config.getInstance().getValueAsBoolean("purge.scheduler.enabled"); 098 099 if (enabled != null && enabled) 100 { 101 Long periodDays = Config.getInstance().getValueAsLong("purge.scheduler.period"); 102 if (periodDays == null) 103 { 104 periodDays = _DEFAULT_PERIOD; 105 } 106 String hourStr = Config.getInstance().getValueAsString("purge.scheduler.hour"); 107 108 // Schedule a timer to run at the given hour, each defined period. 109 int hour = 0; 110 int minute = 0; 111 if (StringUtils.isNotEmpty(hourStr) && hourStr.indexOf(':') > 0) 112 { 113 String[] hourArray = StringUtils.split(hourStr, ':'); 114 hour = Integer.parseInt(hourArray[0]); 115 minute = Integer.parseInt(hourArray[1]); 116 } 117 118 GregorianCalendar calendar = new GregorianCalendar(); 119 calendar.set(Calendar.AM_PM, hour < 12 ? Calendar.AM : Calendar.PM); 120 calendar.set(Calendar.HOUR, hour % 12); 121 calendar.set(Calendar.MINUTE, minute); 122 calendar.set(Calendar.SECOND, 0); 123 calendar.set(Calendar.MILLISECOND, 0); 124 125// calendar.add(Calendar.MINUTE, 1); 126 127 // Each day. 128 long period = periodDays * 24 * 3600 * 1000; 129 Date firstTime = calendar.getTime(); 130 131 Date now = new Date(); 132 133 // If the given time today is past, schedule for tomorrow. 134 if (firstTime.compareTo(now) < 0) 135 { 136 calendar.add(Calendar.DAY_OF_MONTH, 1); 137 firstTime = calendar.getTime(); 138 } 139 140 if (_logger.isInfoEnabled()) 141 { 142 _logger.info("Purge contents scheduler: the purge engine will run every " + periodDays + " days, starting " + firstTime.toString()); 143 } 144 145 _timer = new Timer("PurgeContents", true); 146 _timer.schedule(this, firstTime, period); 147 } 148 } 149 150 @Override 151 public void run() 152 { 153 PurgeContentsEngine purgeContentsEngine = new PurgeContentsEngine(); 154 155 try 156 { 157 // Initialize and configure the engine. 158 purgeContentsEngine.initialize(_manager, _context); 159 purgeContentsEngine.configure(_configuration); 160 } 161 catch (Exception e) 162 { 163 throw new RuntimeException("Unable to initialize the alerts engine", e); 164 } 165 166 // The thread will be started as daemon, as the scheduler is marked daemon itself. 167 new Thread(purgeContentsEngine, "PurgeContentsEngine").start(); 168 } 169 170 @Override 171 public void dispose() 172 { 173 _context = null; 174 _logger = null; 175 _manager = null; 176 _configuration = null; 177 178 cancel(); 179 if (_timer != null) 180 { 181 _timer.cancel(); 182 _timer = null; 183 } 184 } 185 186}