/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////
package org.projectforge.core;
import java.text.ParseException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.projectforge.database.MyDatabaseUpdateDao;
import org.projectforge.database.MyDatabaseUpdater;
import org.projectforge.meb.MebJobExecutor;
import org.projectforge.meb.MebPollingJob;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
/**
* Setup of the Quartz scheduler.
* @author Kai Reinhard (k.reinhard@micromata.de)
*/
public class CronSetup
{
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(CronSetup.class);
private Scheduler scheduler;
private MyDatabaseUpdater myDatabaseUpdater;
private HibernateSearchReindexer hibernateSearchReindexer;
private MebJobExecutor mebJobExecutor;
/**
* Should be called at the start-up time of the application.<br/>
* Initializes and starts the scheduler.
*/
public void initialize()
{
synchronized (this) {
if (scheduler != null) {
return;
}
try {
// Grab the Scheduler instance from the Factory
scheduler = StdSchedulerFactory.getDefaultScheduler();
// and start it off
scheduler.start();
} catch (final SchedulerException ex) {
log.error(ex.getMessage(), ex);
}
final ConfigXml cfg = ConfigXml.getInstance();
if (cfg.isMebMailAccountConfigured() == false) {
mebJobExecutor = null; // MEB is not configured.
}
final MyDatabaseUpdateDao databaseUpdateDao = myDatabaseUpdater.getDatabaseUpdateDao();
// run every hour at *:00: 0 0 * * * ?
createCron("hourlyJob", CronHourlyJob.class, "0 0 * * * ?", cfg.getCronExpressionHourlyJob(), "databaseUpdateDao", databaseUpdateDao,
"hibernateSearchReindexer", hibernateSearchReindexer);
// run every morning at 2:30 AM (UTC): 0 30 2 * * ?
createCron("nightlyJob", CronNightlyJob.class, "0 30 2 * * ?", cfg.getCronExpressionNightlyJob(), "hibernateSearchReindexer",
hibernateSearchReindexer, "mebJobExecutor", mebJobExecutor);
if (mebJobExecutor != null) {
// run every 10 minutes (5, 15, 25, ...): 0 5/10 * * * ?
createCron("mebPollingJob", MebPollingJob.class, "0 5/10 * * * ?", cfg.getCronExpressionMebPollingJob(), "mebJobExecutor",
mebJobExecutor);
}
}
}
public void registerCronJob(final String givenName, final Class< ? extends Job> jobClass, final String cronExpression,
final Object... params)
{
if (jobClass != null) {
String name = givenName;
if (StringUtils.isBlank(name) == true) {
name = "generatedExternalName " + jobClass.getName() + " " + System.currentTimeMillis();
}
// default is run every 10 minutes
createCron(name, jobClass, "0 */10 * * * ?", cronExpression, params);
}
}
/**
* Should be called at the shutdown of the application.
*/
public void shutdown()
{
if (scheduler == null) {
// Scheduler is null e. g. in maintenance mode.
return;
}
try {
scheduler.shutdown();
} catch (final SchedulerException ex) {
log.error(ex.getMessage(), ex);
}
}
private void createCron(final String name, final Class< ? extends Job> jobClass, final String cronDefaultExpression,
final String cronExpression, final Object... params)
{
// Define job instance (group = "default")
final JobDetail job = new JobDetail(name, "default", jobClass);
if (params != null) {
Validate.isTrue(params.length % 2 == 0);
final JobDataMap map = job.getJobDataMap();
for (int i = 0; i < params.length - 1; i += 2) {
Validate.isTrue(params[i] instanceof String);
map.put(params[i], params[i + 1]);
}
}
final String cronEx;
if (StringUtils.isNotBlank(cronExpression) == true) {
cronEx = cronExpression;
} else {
cronEx = cronDefaultExpression;
}
final Trigger trigger;
try {
trigger = new CronTrigger(name + "Trigger", "default", cronEx);
} catch (final ParseException ex) {
log.error("Could not create cron trigger with expression '" + cronEx + "' (cron job is disabled): " + ex.getMessage(), ex);
return;
}
try {
// Schedule the job with the trigger
scheduler.scheduleJob(job, trigger);
} catch (final SchedulerException ex) {
log.error("Could not create cron job: " + ex.getMessage(), ex);
return;
}
log.info("Cron job '" + name + "' successfully configured: " + cronEx);
}
public void setMyDatabaseUpdater(final MyDatabaseUpdater myDatabaseUpdater)
{
this.myDatabaseUpdater = myDatabaseUpdater;
}
public void setHibernateSearchReindexer(final HibernateSearchReindexer hibernateSearchReindexer)
{
this.hibernateSearchReindexer = hibernateSearchReindexer;
}
public void setMebJobExecutor(final MebJobExecutor mebJobExecutor)
{
this.mebJobExecutor = mebJobExecutor;
}
}