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