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