001/* 002 * Copyright 2014 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.archive; 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 * Archive contents scheduler: launches a cron which archives contents when 043 * necessary. 044 */ 045public class ArchiveContentsScheduler extends TimerTask implements Initializable, LogEnabled, Serviceable, Disposable, Contextualizable, Configurable 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("archive.scheduler.enabled"); 090 if (!enabled) 091 { 092 return; 093 } 094 095 if (_logger.isDebugEnabled()) 096 { 097 _logger.debug("Initializing the archive scheduler..."); 098 } 099 100 String hourStr = Config.getInstance().getValue("archive.scheduler.hour"); 101 102 // Schedule a timer to run at the given hour, each defined period. 103 int hour = 0; 104 int minute = 0; 105 if (StringUtils.isNotEmpty(hourStr) && hourStr.indexOf(':') > 0) 106 { 107 String[] hourArray = StringUtils.split(hourStr, ':'); 108 hour = Integer.parseInt(hourArray[0]); 109 minute = Integer.parseInt(hourArray[1]); 110 } 111 112 GregorianCalendar calendar = new GregorianCalendar(); 113 calendar.set(Calendar.AM_PM, hour < 12 ? Calendar.AM : Calendar.PM); 114 calendar.set(Calendar.HOUR, hour % 12); 115 calendar.set(Calendar.MINUTE, minute); 116 calendar.set(Calendar.SECOND, 0); 117 calendar.set(Calendar.MILLISECOND, 0); 118 119 // Each day. 120 long period = 24 * 3600 * 1000; 121 Date firstTime = calendar.getTime(); 122 123 Date now = new Date(); 124 125 // If the given time today is past, schedule for tomorrow. 126 if (firstTime.compareTo(now) < 0) 127 { 128 calendar.add(Calendar.DAY_OF_MONTH, 1); 129 firstTime = calendar.getTime(); 130 } 131 132 if (_logger.isInfoEnabled()) 133 { 134 _logger.info("Archive contents scheduler: the archive engine will run every day at the hour, starting " + firstTime.toString()); 135 } 136 137 _timer = new Timer("ArchiveContents", true); 138 _timer.schedule(this, firstTime, period); 139 } 140 141 @Override 142 public void run() 143 { 144 ArchiveContentsEngine archiveContentsEngine = new ArchiveContentsEngine(); 145 146 try 147 { 148 // Initialize and configure the engine. 149 archiveContentsEngine.initialize(_manager, _context); 150 archiveContentsEngine.configure(_configuration); 151 } 152 catch (Exception e) 153 { 154 throw new RuntimeException("Unable to initialize the archive engine", e); 155 } 156 157 // The thread will be started as daemon, as the scheduler is marked 158 // daemon itself. 159 new Thread(archiveContentsEngine, "ArchiveContentsEngine").start(); 160 } 161 162 @Override 163 public void dispose() 164 { 165 _context = null; 166 _logger = null; 167 _manager = null; 168 _configuration = null; 169 170 cancel(); 171 if (_timer != null) 172 { 173 _timer.cancel(); 174 _timer = null; 175 } 176 } 177 178}