Return-Path:
Delivered-To: apmail-cocoon-cvs-archive@www.apache.org
Received: (qmail 72908 invoked from network); 3 Sep 2003 16:23:10 -0000
Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12)
by minotaur-2.apache.org with SMTP; 3 Sep 2003 16:23:10 -0000
Received: (qmail 54081 invoked by uid 500); 3 Sep 2003 16:04:06 -0000
Delivered-To: apmail-cocoon-cvs-archive@cocoon.apache.org
Received: (qmail 53879 invoked by uid 500); 3 Sep 2003 16:04:03 -0000
Mailing-List: contact cvs-help@cocoon.apache.org; run by ezmlm
Precedence: bulk
Reply-To: dev@cocoon.apache.org
list-help:
list-unsubscribe:
list-post:
Delivered-To: mailing list cvs@cocoon.apache.org
Received: (qmail 53728 invoked by uid 500); 3 Sep 2003 16:04:01 -0000
Delivered-To: apmail-cocoon-2.1-cvs@apache.org
Received: (qmail 53589 invoked from network); 3 Sep 2003 16:03:59 -0000
Received: from unknown (HELO minotaur.apache.org) (209.237.227.194)
by daedalus.apache.org with SMTP; 3 Sep 2003 16:03:58 -0000
Received: (qmail 57919 invoked by uid 1041); 3 Sep 2003 16:04:02 -0000
Date: 3 Sep 2003 16:04:02 -0000
Message-ID: <20030903160402.57918.qmail@minotaur.apache.org>
From: giacomo@apache.org
To: cocoon-2.1-cvs@apache.org
Subject: cvs commit: cocoon-2.1/src/blocks/cron/samples cron.xsp docs.xml
samples.xml sitemap.xmap
X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N
X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N
giacomo 2003/09/03 09:04:02
Modified: . blocks.properties gump.xml
lib jars.xml
Added: src/blocks/cron/conf cron-category.xlog cron-target.xlog
cron.xconf cron.xsamples
src/blocks/cron/java/org/apache/cocoon/components/cron
ConfigurableCronJob.java CronJob.java
JobScheduler.java QuartzJobExecutor.java
QuartzJobScheduler.java TestCronJob.java
src/blocks/cron/lib quartz-1.0.7.jar
src/blocks/cron/samples cron.xsp docs.xml samples.xml
sitemap.xmap
Log:
added JobScheduler block
Revision Changes Path
1.26 +1 -0 cocoon-2.1/blocks.properties
Index: blocks.properties
===================================================================
RCS file: /home/cvs/cocoon-2.1/blocks.properties,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -b -u -r1.25 -r1.26
--- blocks.properties 7 Aug 2003 08:56:39 -0000 1.25
+++ blocks.properties 3 Sep 2003 16:04:01 -0000 1.26
@@ -58,6 +58,7 @@
#exclude.block.apples=true
#exclude.block.asciiart=true
#exclude.block.axis=true
+#exclude.block.cron=true
#exclude.block.eventcache=true
#exclude.block.linotype=true
#exclude.block.mail=true
1.77 +20 -1 cocoon-2.1/gump.xml
Index: gump.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/gump.xml,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -b -u -r1.76 -r1.77
--- gump.xml 25 Aug 2003 07:41:18 -0000 1.76
+++ gump.xml 3 Sep 2003 16:04:01 -0000 1.77
@@ -996,6 +996,25 @@
+
+
+ org.apache.cocoon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${context-root}/WEB-INF/logs/cron.log
%7.7{priority} %{time} [%{category}] %{thread}/%{class:short}: %{message}\n%{throwable}
true
1.1 cocoon-2.1/src/blocks/cron/conf/cron.xconf
Index: cron.xconf
===================================================================
false-1-1160000RUNtrue5000I'm here23000
1.1 cocoon-2.1/src/blocks/cron/conf/cron.xsamples
Index: cron.xsamples
===================================================================
Cron block samples.
1.1 cocoon-2.1/src/blocks/cron/java/org/apache/cocoon/components/cron/ConfigurableCronJob.java
Index: ConfigurableCronJob.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi . For more information on the Apache
Software Foundation, please see .
*/
package org.apache.cocoon.components.cron;
import java.util.Map;
import org.apache.avalon.framework.parameters.Parameters;
/**
* This is a configurable cron job. Before the execute/run method is called the setup method is invoked.
*
* @author Giacomo Pati
* @version CVS $Id: ConfigurableCronJob.java,v 1.1 2003/09/03 16:04:02 giacomo Exp $
*
* @since 2.1.1
*/
public interface ConfigurableCronJob
extends CronJob {
/**
* Setup CronJob with additional information first
*
* @param pars Any Parameters
* @param objects Some additional Objects
*/
void setup(Parameters pars, Map objects);
}
1.1 cocoon-2.1/src/blocks/cron/java/org/apache/cocoon/components/cron/CronJob.java
Index: CronJob.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi . For more information on the Apache
Software Foundation, please see .
*/
package org.apache.cocoon.components.cron;
/**
* This is the interface a class has to implement to enable it to be scheduled by a JobScheduler
*
* @author Giacomo Pati
* @version CVS $Id: CronJob.java,v 1.1 2003/09/03 16:04:02 giacomo Exp $
*/
public interface CronJob {
//~ Instance fields ------------------------------------------------------------------------------------------------
/** The component role */
String ROLE = CronJob.class.getName();
//~ Methods --------------------------------------------------------------------------------------------------------
/**
* This methods get called to allow an implementing class to do its supposed job
*
* @param jobname the name given to this job
*/
void execute(String jobname);
}
1.1 cocoon-2.1/src/blocks/cron/java/org/apache/cocoon/components/cron/JobScheduler.java
Index: JobScheduler.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi . For more information on the Apache
Software Foundation, please see .
*/
package org.apache.cocoon.components.cron;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.parameters.Parameters;
/**
* This component schedules jobs.
*
* @author Giacomo Pati
* @version CVS $Id: JobScheduler.java,v 1.1 2003/09/03 16:04:02 giacomo Exp $
*
* @since 2.1.1
*/
public interface JobScheduler {
/** The role of a JobScheduler */
String ROLE = JobScheduler.class.getName();
/**
* Schedule a time based job. Note that if a CronJob already has same name then it is overwritten.
*
* @param name the name of the job
* @param jobrole The Avalon components role name of the job itself
* @param cronSpec the time specification using a cron expression
* @param canRunConcurrently whether this job can run even previous scheduled runs are still running
*/
void addJob(String name, String jobrole, String cronSpec, boolean canRunConcurrently)
throws CascadingException;
/**
* Schedule a time based job. Note that if a CronJob already has same name then it is overwritten.
*
* @param name the name of the job
* @param jobrole The Avalon components role name of the job itself
* @param cronSpec the time specification using a cron expression
* @param canRunConcurrently whether this job can run even previous scheduled runs are still running
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*/
void addJob(String name, String jobrole, String cronSpec, boolean canRunConcurrently, Parameters params, Map objects)
throws CascadingException;
/**
* Schedule a job. Note that if a CronJob already has the same name then it is overwritten.
*
* @param name the name of the job
* @param job The job object itself. It must implement either CronJob, Runnable or might also be an implementation
* specific class (i.e. org.quartz.Job)
* @param cronSpec the time specification using a cron expression
* @param canRunConcurrently whether this job can run even previous scheduled runs are still running
*/
void addJob(String name, Object job, String cronSpec, boolean canRunConcurrently)
throws CascadingException;
/**
* Schedule a job. Note that if a CronJob already has the same name then it is overwritten.
*
* @param name the name of the job
* @param job The job object itself. It must implement either CronJob, Runnable or might also be an implementation
* specific class (i.e. org.quartz.Job)
* @param cronSpec the time specification using a cron expression
* @param canRunConcurrently whether this job can run even previous scheduled runs are still running
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*/
void addJob(String name, Object job, String cronSpec, boolean canRunConcurrently, Parameters params, Map objects)
throws CascadingException;
/**
* Fire a target once immediately
*
* @param jobrole The Avalon components role name of the job itself
*
* @return state of execution successfullness
*/
boolean fireJob(String jobrole);
/**
* Fire a target once immediately
*
* @param jobrole The Avalon components role name of the job itself
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*
* @return state of execution successfullness
*/
boolean fireJob(String jobrole, Parameters params, Map objects)
throws CascadingException;
/**
* Fire a CronJob once immediately
*
* @param job The job object itself. It must implement either CronJob, Runnable or might also be an implementation
* specific class (i.e. org.quartz.Job)
*
* @return state of execution successfullness
*/
boolean fireJob(Object job);
/**
* Fire a target once immediately
*
* @param job The job object itself. It must implement either CronJob, Runnable or might also be an implementation
* specific class (i.e. org.quartz.Job)
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*
* @return state of execution successfullness
*/
boolean fireJob(Object job, Parameters params, Map objects)
throws CascadingException;
/**
* Fire a target once at a specific date
*
* @param date The date this job should be scheduled
* @param name the name of the job
* @param jobrole The Avalon components role name of the job itself
*/
void fireJobAt(Date date, String name, String jobrole)
throws CascadingException;
/**
* Fire a target once immediately
*
* @param date The date this job should be scheduled
* @param name the name of the job
* @param jobrole The Avalon components role name of the job itself
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*/
void fireJobAt(Date date, String name, String jobrole, Parameters params, Map objects)
throws CascadingException;
/**
* Fire a CronJob once immediately
*
* @param date The date this job should be scheduled
* @param name the name of the job
* @param job The job object itself. It must implement either CronJob, Runnable or might also be an implementation
* specific class (i.e. org.quartz.Job)
*/
void fireJobAt(Date date, String name, Object job)
throws CascadingException;
/**
* Fire a target once immediately
*
* @param date The date this job should be scheduled
* @param name the name of the job
* @param job The job object itself. It must implement either CronJob, Runnable or might also be an implementation
* specific class (i.e. org.quartz.Job)
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*/
void fireJobAt(Date date, String name, Object job, Parameters params, Map objects)
throws CascadingException;
/**
* Remove a scheduled job by name.
*
* @param name the name of the job
*/
void removeJob(String name)
throws NoSuchElementException;
}
1.1 cocoon-2.1/src/blocks/cron/java/org/apache/cocoon/components/cron/QuartzJobExecutor.java
Index: QuartzJobExecutor.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi . For more information on the Apache
Software Foundation, please see .
*/
package org.apache.cocoon.components.cron;
import java.util.Map;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceManager;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* This component is resposible to launch a {@link CronJob}s in a Quart Scheduler.
*
* @author Giacomo Pati
* @version CVS $Id: QuartzJobExecutor.java,v 1.1 2003/09/03 16:04:02 giacomo Exp $
*/
public class QuartzJobExecutor
implements Job {
/** Map key for the run status */
private static final String DATA_MAP_KEY_ISRUNNING = "QuartzJobExecutor.isRunning";
/* (non-Javadoc)
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
public void execute(final JobExecutionContext context)
throws JobExecutionException {
final JobDataMap data = context.getJobDetail().getJobDataMap();
final Logger logger = (Logger)data.get(QuartzJobScheduler.DATA_MAP_LOGGER);
final String name = (String)data.get(QuartzJobScheduler.DATA_MAP_NAME);
final Boolean canRunConcurrentlyB = ((Boolean)data.get(QuartzJobScheduler.DATA_MAP_RUN_CONCURRENT));
final boolean canRunConcurrently = (canRunConcurrentlyB == null ? true : canRunConcurrentlyB.booleanValue());
if ( !canRunConcurrently) {
Boolean isRunning = (Boolean)data.get(DATA_MAP_KEY_ISRUNNING);
if ((null != isRunning) && isRunning.booleanValue()) {
logger.warn("Cron job name '" + name +
" already running but configured to not allow concurrent runs. Will discard this scheduled run");
return;
}
}
if (logger.isInfoEnabled()) {
logger.info("Scheduling cron job named '" + name + "'");
}
Object job = null;
String jobrole = null;
ServiceManager manager = null;
try {
jobrole = (String)data.get(QuartzJobScheduler.DATA_MAP_ROLE);
if (null == jobrole) {
job = data.get(QuartzJobScheduler.DATA_MAP_OBJECT);
} else {
manager = (ServiceManager)data.get(QuartzJobScheduler.DATA_MAP_MANAGER);
job = manager.lookup(jobrole);
}
if (job instanceof ConfigurableCronJob) {
final Parameters params = (Parameters)data.get(QuartzJobScheduler.DATA_MAP_PARAMETERS);
final Map objects = (Map)data.get(QuartzJobScheduler.DATA_MAP_OBJECTMAP);
((ConfigurableCronJob)job).setup(params, objects);
}
data.put(DATA_MAP_KEY_ISRUNNING, new Boolean(true));
if (job instanceof Job) {
((Job)job).execute(context);
} else if (job instanceof CronJob) {
((CronJob)job).execute(name);
} else if (job instanceof Runnable) {
((Runnable)job).run();
} else {
logger.error("job named '" + name + "' is of invalid class: " + job.getClass().getName());
}
} catch (final Throwable t) {
logger.error("Cron job name '" + name + " died.", t);
if (t instanceof JobExecutionException) {
throw (JobExecutionException)t;
}
} finally {
data.put(DATA_MAP_KEY_ISRUNNING, new Boolean(false));
if (null != manager) {
manager.release(job);
}
}
}
}
1.1 cocoon-2.1/src/blocks/cron/java/org/apache/cocoon/components/cron/QuartzJobScheduler.java
Index: QuartzJobScheduler.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi . For more information on the Apache
Software Foundation, please see .
*/
/*
* Created on Sep 1, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.apache.cocoon.components.cron;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
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.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.DirectSchedulerFactory;
import org.quartz.simpl.RAMJobStore;
import EDU.oswego.cs.dl.util.concurrent.BoundedBuffer;
import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
/**
* This component can either schedule jobs or directly execute one.
*
* @author giacomo To change the template for this generated type comment go to Window>Preferences>Java>Code
* Generation>Code and Comments
*/
public class QuartzJobScheduler
extends AbstractLogEnabled
implements JobScheduler, Component, ThreadSafe, Serviceable, Configurable, Startable, Disposable {
/** ThreadPool policy RUN */
private static final String POLICY_RUN = "RUN";
/** ThreadPool policy WAIT */
private static final String POLICY_WAIT = "WAIT";
/** ThreadPool policy ABORT */
private static final String POLICY_ABORT = "ABORT";
/** ThreadPool policy DISCARD */
private static final String POLICY_DISCARD = "DISCARD";
/** ThreadPool policy DISCARD-OLDEST */
private static final String POLICY_DISCARD_OLDEST = "DISCARDOLDEST";
/** Map key for the component role */
public static final String DATA_MAP_ROLE = "QuartzJobScheduler.ROLE";
/** Map key for the job object */
public static final String DATA_MAP_OBJECT = "QuartzJobScheduler.Object";
/** Map key for the job name */
public static final String DATA_MAP_NAME = "QuartzJobScheduler.JobName";
/** Map key for the service manager */
public static final String DATA_MAP_MANAGER = "QuartzJobScheduler.ServiceManager";
/** Map key for the logger */
public static final String DATA_MAP_LOGGER = "QuartzJobScheduler.Logger";
/** Map key for the concurrent run property */
public static final String DATA_MAP_RUN_CONCURRENT = "QuartzJobScheduler.RunConcurrently";
/** Map key for additional Parameters */
public static final String DATA_MAP_PARAMETERS = "QuartzJobScheduler.Parameters";
/** Map key for additional Object Map */
public static final String DATA_MAP_OBJECTMAP = "QuartzJobScheduler.Map";
/** The group name */
private static final String DEFAULT_QUARTZ_JOB_GROUP = "Cocoon";
/** The PooledExecutor instance */
private PooledExecutor m_executor;
/** The quartz scheduler */
private Scheduler m_scheduler;
/** The ServiceManager instance */
private ServiceManager m_manager;
/** Should we wait for running jobs to terminate on shutdown ? */
private boolean m_shutdownGraceful;
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#addJob(java.lang.String, java.lang.Object, java.lang.String, boolean, org.apache.avalon.framework.parameters.Parameters, java.util.Map)
*/
public void addJob(final String name, final Object job, final String cronSpec, final boolean canRunConcurrently,
final Parameters params, final Map objects)
throws CascadingException {
final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(DATA_MAP_OBJECT, job);
addJob(name, jobDataMap, cronSpec, canRunConcurrently, params, objects);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#addJob(java.lang.String, java.lang.String, java.lang.String, boolean, org.apache.avalon.framework.parameters.Parameters, java.util.Map)
*/
public void addJob(final String name, final String jobrole, final String cronSpec,
final boolean canRunConcurrently, final Parameters params, final Map objects)
throws CascadingException {
final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(DATA_MAP_ROLE, jobrole);
addJob(name, jobDataMap, cronSpec, canRunConcurrently, params, objects);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#addJob(java.lang.String, java.lang.Object, java.lang.String, boolean)
*/
public void addJob(final String name, final Object job, final String cronSpec, final boolean canRunConcurrently)
throws CascadingException {
if (!(job instanceof CronJob) && !(job instanceof Runnable) && !(job instanceof Job)) {
throw new CascadingException("Job object is neither an instance of " + CronJob.class.getName() + "," +
Runnable.class.getName() + " nor " + Job.class.getName());
}
addJob(name, job, cronSpec, canRunConcurrently, null, null);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#addJob(java.lang.String, java.lang.String, java.lang.String, boolean)
*/
public void addJob(final String name, final String jobrole, final String cronSpec, final boolean canRunConcurrently)
throws CascadingException {
addJob(name, jobrole, cronSpec, canRunConcurrently, null, null);
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
*/
public void configure(final Configuration config)
throws ConfigurationException {
final ThreadPool pool = createThreadPool(config.getChild("thread-pool"));
try {
DirectSchedulerFactory.getInstance().createScheduler(pool, new RAMJobStore());
m_scheduler = DirectSchedulerFactory.getInstance().getScheduler();
} catch (final SchedulerException se) {
throw new ConfigurationException("cannot create a quartz scheduler", se);
}
final Configuration[] triggers = config.getChild("triggers").getChildren("trigger");
createTriggers(triggers);
if (getLogger().isDebugEnabled() && (triggers.length == 0)) {
getLogger().debug("no triggers configured at startup");
}
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.activity.Disposable#dispose()
*/
public void dispose() {
try {
if (getLogger().isInfoEnabled()) {
getLogger().info("shutting down scheduler " +
(m_shutdownGraceful ? "graceful (waiting for running jobs to complete)"
: "immediately (killing running jobs)"));
}
m_scheduler.shutdown(m_shutdownGraceful);
} catch (final SchedulerException se) {
getLogger().error("failure during scheduler shutdown", se);
}
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireTarget(java.lang.Object)
*/
public boolean fireJob(final Object job) {
return fireJob(job.getClass().getName(), job);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireTarget(java.lang.String)
*/
public boolean fireJob(final String jobrole) {
try {
final Object job = m_manager.lookup(jobrole);
return fireJob(jobrole, job);
} catch (final ServiceException se) {
getLogger().error("cannot fire job " + jobrole, se);
}
return false;
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireJob(java.lang.Object, org.apache.avalon.framework.parameters.Parameters, java.util.Map)
*/
public boolean fireJob(final Object job, final Parameters params, final Map objects)
throws CascadingException {
if (job instanceof ConfigurableCronJob) {
((ConfigurableCronJob)job).setup(params, objects);
}
return fireJob(job);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireJob(java.lang.String, org.apache.avalon.framework.parameters.Parameters, java.util.Map)
*/
public boolean fireJob(final String jobrole, final Parameters params, final Map objects)
throws CascadingException {
try {
final Object job = m_manager.lookup(jobrole);
if (job instanceof ConfigurableCronJob) {
((ConfigurableCronJob)job).setup(params, objects);
}
return fireJob(jobrole, job);
} catch (final ServiceException se) {
getLogger().error("cannot fire job " + jobrole, se);
}
return false;
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireJobAt(java.util.Date, java.lang.String, java.lang.Object)
*/
public void fireJobAt(final Date date, final String name, final Object job)
throws CascadingException {
fireJobAt(date, name, job, null, null);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireJobAt(java.util.Date, java.lang.String, java.lang.String)
*/
public void fireJobAt(final Date date, final String name, final String jobrole)
throws CascadingException {
fireJobAt(date, name, jobrole, null, null);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireJobAt(java.util.Date, java.lang.String, java.lang.Object, org.apache.avalon.framework.parameters.Parameters, java.util.Map)
*/
public void fireJobAt(final Date date, final String name, final Object job, final Parameters params,
final Map objects)
throws CascadingException {
final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(DATA_MAP_OBJECT, job);
addJob(name, jobDataMap, date, true, params, objects);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireJobAt(java.util.Date, java.lang.String, java.lang.String, org.apache.avalon.framework.parameters.Parameters, java.util.Map)
*/
public void fireJobAt(final Date date, final String name, final String jobrole, final Parameters params,
final Map objects)
throws CascadingException {
final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(DATA_MAP_ROLE, jobrole);
addJob(name, jobDataMap, date, true, params, objects);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#removeJob(java.lang.String)
*/
public void removeJob(final String name)
throws NoSuchElementException {
try {
m_scheduler.deleteJob(name, DEFAULT_QUARTZ_JOB_GROUP);
} catch (final SchedulerException se) {
throw new NoSuchElementException(se.getMessage());
}
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
*/
public void service(final ServiceManager manager)
throws ServiceException {
m_manager = manager;
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.activity.Startable#start()
*/
public void start()
throws Exception {
m_scheduler.start();
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.activity.Startable#stop()
*/
public void stop()
throws Exception {
m_scheduler.pause();
}
/**
* Add a job to the scheduler
*
* @param name The name of the job to add
* @param jobDataMap The JobDataMap to use for this job
* @param date the date to schedule this job
* @param canRunConcurrently whether this job can be run concurrently
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*
* @throws CascadingException thrown in case of errors
*/
private void addJob(final String name, final JobDataMap jobDataMap, final Date date,
final boolean canRunConcurrently, final Parameters params, final Map objects)
throws CascadingException {
final SimpleTrigger trigger = new SimpleTrigger(name, DEFAULT_QUARTZ_JOB_GROUP, date);
addJob(name, jobDataMap, trigger, canRunConcurrently, params, objects);
}
/**
* Add a job to the scheduler
*
* @param name The name of the job to add
* @param jobDataMap The JobDataMap to use for this job
* @param cronSpec a Cron time expression
* @param canRunConcurrently whether this job can be run concurrently
* @param params Additional Parameters to setup CronJob
* @param objects A Map with additional object to setup CronJob
*
* @throws CascadingException thrown in case of errors
*/
private void addJob(final String name, final JobDataMap jobDataMap, final String cronSpec,
final boolean canRunConcurrently, final Parameters params, final Map objects)
throws CascadingException {
final CronTrigger cronJobEntry = new CronTrigger(name, DEFAULT_QUARTZ_JOB_GROUP);
try {
cronJobEntry.setCronExpression(cronSpec);
} catch (final ParseException pe) {
throw new CascadingException(pe.getMessage(), pe);
}
addJob(name, jobDataMap, cronJobEntry, canRunConcurrently, params, objects);
}
/**
* Add a job to the scheduler
*
* @param name The name of the job to add
* @param jobDataMap The JobDataMap to use for this job
* @param trigger a Trigger
* @param canRunConcurrently whether this job can be run concurrently
* @param params Additional Parameters to setup CronJob (might be null)
* @param objects A Map with additional object to setup CronJob (might be null)
*
* @throws CascadingException thrown in case of errors
*/
private void addJob(final String name, final JobDataMap jobDataMap, final Trigger trigger,
final boolean canRunConcurrently, final Parameters params, final Map objects)
throws CascadingException {
jobDataMap.put(DATA_MAP_NAME, name);
jobDataMap.put(DATA_MAP_LOGGER, getLogger());
jobDataMap.put(DATA_MAP_MANAGER, m_manager);
jobDataMap.put(DATA_MAP_RUN_CONCURRENT, new Boolean(canRunConcurrently));
if (null != params) {
jobDataMap.put(DATA_MAP_PARAMETERS, params);
}
if (null != objects) {
jobDataMap.put(DATA_MAP_OBJECTMAP, objects);
}
final JobDetail detail = new JobDetail(name, DEFAULT_QUARTZ_JOB_GROUP, QuartzJobExecutor.class);
detail.setJobDataMap(jobDataMap);
if (getLogger().isInfoEnabled()) {
getLogger().info("Adding CronJob '" + trigger.getFullName() + "'");
if (getLogger().isDebugEnabled()) {
if (trigger instanceof CronTrigger) {
getLogger().debug("Time schedule summary:\n" + ((CronTrigger)trigger).getExpressionSummary());
} else if (trigger instanceof SimpleTrigger) {
getLogger().debug("Next scheduled time: " + ((SimpleTrigger)trigger).getNextFireTime());
}
}
}
try {
m_scheduler.scheduleJob(detail, trigger);
} catch (final SchedulerException se) {
throw new CascadingException(se.getMessage(), se);
}
}
/**
* Create a ThreadPool
*
* @param poolConfig Configuration element for the thread pool
*
* @return ThreadPool
*/
private ThreadPool createThreadPool(final Configuration poolConfig) {
final boolean useQueueing = poolConfig.getChild("use-queueing").getValueAsBoolean(false);
final int queueSize = poolConfig.getChild("queue-size").getValueAsInteger(-1);
if (useQueueing) {
if (queueSize > 0) {
m_executor = new PooledExecutor(new BoundedBuffer(queueSize));
} else {
m_executor = new PooledExecutor(new LinkedQueue());
}
} else {
m_executor = new PooledExecutor();
}
final int maxPoolSize = poolConfig.getChild("max-pool-size").getValueAsInteger(-1);
if (maxPoolSize > 0) {
m_executor.setMaximumPoolSize(maxPoolSize);
} else {
m_executor.setMaximumPoolSize(PooledExecutor.DEFAULT_MAXIMUMPOOLSIZE);
}
final int minPoolSize = poolConfig.getChild("min-pool-size").getValueAsInteger(-1);
if (minPoolSize > 0) {
m_executor.setMinimumPoolSize(minPoolSize);
} else {
m_executor.setMinimumPoolSize(PooledExecutor.DEFAULT_MINIMUMPOOLSIZE);
}
final int keepAliveTimeMs = poolConfig.getChild("keep-alive-time-ms").getValueAsInteger(-1);
if (keepAliveTimeMs > 0) {
m_executor.setKeepAliveTime(keepAliveTimeMs);
} else {
m_executor.setKeepAliveTime(PooledExecutor.DEFAULT_KEEPALIVETIME);
}
final String blockPolicy = poolConfig.getChild("block-policy").getValue(null);
if (blockPolicy != null) {
if (blockPolicy.equalsIgnoreCase(POLICY_ABORT)) {
m_executor.abortWhenBlocked();
} else if (blockPolicy.equalsIgnoreCase(POLICY_DISCARD)) {
m_executor.discardWhenBlocked();
} else if (blockPolicy.equalsIgnoreCase(POLICY_DISCARD_OLDEST)) {
m_executor.discardOldestWhenBlocked();
} else if (blockPolicy.equalsIgnoreCase(POLICY_RUN)) {
m_executor.runWhenBlocked();
} else if (blockPolicy.equalsIgnoreCase(POLICY_WAIT)) {
m_executor.waitWhenBlocked();
} else {
getLogger().warn("Unknown block-policy configuration '" + blockPolicy + "'. Should be one of '" +
POLICY_ABORT + "','" + POLICY_DISCARD + "','" + POLICY_DISCARD_OLDEST + "','" +
POLICY_RUN + "','" + POLICY_WAIT + "'. Will use '" + POLICY_RUN + "'");
}
}
m_shutdownGraceful = poolConfig.getChild("shutdown-graceful").getValueAsBoolean(true);
final int shutdownWaitTimeMs = poolConfig.getChild("shutdown-wait-time-ms").getValueAsInteger(-1);
final ThreadPool pool = new ThreadPool(m_executor, shutdownWaitTimeMs);
pool.enableLogging(getLogger());
if (getLogger().isInfoEnabled()) {
getLogger().info("using a PooledExecutor as ThreadPool with queueing=" + useQueueing +
(useQueueing ? (",queue-size=" + ((queueSize > 0) ? ("" + queueSize) : "default")) : "") +
",max-pool-size=" + m_executor.getMaximumPoolSize() + ",min-pool-size=" +
m_executor.getMinimumPoolSize() + ",keep-alive-time-ms=" + m_executor.getKeepAliveTime() +
",block-policy='" + blockPolicy + "',shutdown-wait-time-ms=" +
((shutdownWaitTimeMs > 0) ? ("" + shutdownWaitTimeMs) : "default"));
}
return pool;
}
/**
* Create the tiggers
*
* @param tiggers array of tigger configuration elements
*
* @throws ConfigurationException thrown in case of configuration failures
*/
private void createTriggers(final Configuration[] tiggers)
throws ConfigurationException {
for (int i = 0; i < tiggers.length; i++) {
String cron = tiggers[i].getChild("cron").getValue(null);
if (null == cron) {
final String seconds = tiggers[i].getChild("seconds").getValue("0");
final String minutes = tiggers[i].getChild("minutes").getValue("*");
final String hours = tiggers[i].getChild("hours").getValue("*");
final String days = tiggers[i].getChild("days").getValue("*");
final String months = tiggers[i].getChild("months").getValue("*");
final String weekdays = tiggers[i].getChild("weekdays").getValue("?");
final String years = tiggers[i].getChild("years").getValue("*");
cron = seconds + " " + minutes + " " + hours + " " + days + " " + months + " " + weekdays + " " +
years;
}
try {
addJob(tiggers[i].getAttribute("name"), tiggers[i].getAttribute("target"), cron,
tiggers[i].getAttributeAsBoolean("concurrent-runs", true));
} catch (final CascadingException ce) {
throw new ConfigurationException("failed adding trigger to scheduler", ce);
}
}
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.JobScheduler#fireTarget(java.lang.Object)
*/
private boolean fireJob(final String name, final Object job) {
try {
if (job instanceof CronJob) {
m_executor.execute(new Runnable() {
public void run() {
((CronJob)job).execute(name);
}
});
} else if (job instanceof Runnable) {
m_executor.execute((Runnable)job);
} else {
getLogger().error("job named '" + name + "' is of invalid class: " + job.getClass().getName());
return false;
}
return true;
} catch (final InterruptedException ie) {
getLogger().error("job " + name + " interrupted", ie);
}
return false;
}
/**
* A ThreadPool for the Quartz Scheduler based on Doug Leas concurrency utilities PooledExecutor
*
* @author Giacomo Pati
* @version CVS $Id: QuartzJobScheduler.java,v 1.1 2003/09/03 16:04:02 giacomo Exp $
*/
private static class ThreadPool
extends AbstractLogEnabled
implements org.quartz.spi.ThreadPool {
/** Our executor thread pool */
private PooledExecutor m_executor;
/** How long to wait for running jobs to terminate on disposition */
private int m_shutdownWaitTimeMs;
/**
*
*/
public ThreadPool(final PooledExecutor executor, final int shutownWaitTimeMs) {
super();
m_executor = executor;
m_shutdownWaitTimeMs = shutownWaitTimeMs;
}
/* (non-Javadoc)
* @see org.quartz.spi.ThreadPool#getPoolSize()
*/
public int getPoolSize() {
return m_executor.getMaximumPoolSize();
}
/* (non-Javadoc)
* @see org.quartz.spi.ThreadPool#initialize()
*/
public void initialize() {
}
/* (non-Javadoc)
* @see org.quartz.spi.ThreadPool#runInThread(java.lang.Runnable)
*/
public boolean runInThread(final Runnable job) {
try {
m_executor.execute(job);
} catch (final InterruptedException ie) {
getLogger().error("Cronjob failed", ie);
}
return true;
}
/* (non-Javadoc)
* @see org.quartz.spi.ThreadPool#shutdown(boolean)
*/
public void shutdown(final boolean waitForJobsToComplete) {
if (waitForJobsToComplete) {
m_executor.shutdownAfterProcessingCurrentlyQueuedTasks();
} else {
m_executor.shutdownNow();
}
try {
if (m_shutdownWaitTimeMs > 0) {
if (!m_executor.awaitTerminationAfterShutdown(m_shutdownWaitTimeMs)) {
getLogger().warn("scheduled cron jobs are not terminating withing " + m_shutdownWaitTimeMs +
"ms, Will shut them down by interruption");
m_executor.interruptAll();
m_executor.shutdownNow();
}
}
m_executor.awaitTerminationAfterShutdown();
} catch (final InterruptedException ie) {
getLogger().error("cannot shutdown Executor", ie);
}
}
}
}
1.1 cocoon-2.1/src/blocks/cron/java/org/apache/cocoon/components/cron/TestCronJob.java
Index: TestCronJob.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi . For more information on the Apache
Software Foundation, please see .
*/
package org.apache.cocoon.components.cron;
import java.util.Date;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* A simple test CronJob.
*
* @author Giacomo Pati
* @version CVS $Id: TestCronJob.java,v 1.1 2003/09/03 16:04:02 giacomo Exp $
*
* @since 2.1.1
*/
public class TestCronJob
extends AbstractLogEnabled
implements CronJob, Configurable, Component {
//~ Instance fields ------------------------------------------------------------------------------------------------
/** The configured message */
private String m_msg;
/** The configured sleep time */
private int m_sleep;
//~ Methods --------------------------------------------------------------------------------------------------------
/* (non-Javadoc)
* @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
*/
public void configure(final Configuration config)
throws ConfigurationException {
m_msg = config.getChild("msg").getValue("I was not configured");
m_sleep = config.getChild("sleep").getValueAsInteger(11000);
}
/* (non-Javadoc)
* @see org.apache.cocoon.components.cron.CronJob#execute(java.lang.String)
*/
public void execute(String name) {
getLogger().info("CronJob " + name + " launched at " + new Date() + " with message: " + m_msg);
try {
Thread.sleep(m_sleep);
} catch (final InterruptedException ie) {
//getLogger().error("CronJob " + name + " interrupted", ie);
}
getLogger().info("CronJob " + name + " finished at " + new Date() + " with message: " + m_msg);
}
}
1.1 cocoon-2.1/src/blocks/cron/lib/quartz-1.0.7.jar
<>
1.1 cocoon-2.1/src/blocks/cron/samples/cron.xsp
Index: cron.xsp
===================================================================
Cron Job Scheduler Sample
This implementation of the Java interface
JobScheduler
is based on the Quartz
job scheduling project and the
PooledExecutor of
Doug Leas Concurrency Package as a ThreadPool implementation for the Quartz Scheduler.
WARNING: Consider the
JobScheduler interface as beta in terms of defined functionality as it will be
extended with additional requirements in the near future (i.e. getJobList).
This
QuartzJobScheduler implementation is written as a standard
Avalon component. So, its definition you'll find in the
cocoon.xconf file of Cocoon if you've included the cron-block in your build (see
block.properties or local.block.properties file respectively).
The snippet below shows the configuration example of the component itself:
There is nothing special about it. As you could see from the snippet above, inside the job
scheduler component definition there are two parts:
ThreadPool definition
Trigger definitions
ThreadPool
The ThreadPool definition look like this:
As mentioned in the beginning, more information about the thread pool details of the base
PooledExecutor class can be found there.
Triggers
The trigger definition section consists of a single <triggers> element with as much as
needed <trigger> elements inside it. A <trigger> element
looks like:
The <cron> element is simply the concatenation of the values of the elements
<seconds>, <minutes>, <hours>,
<days>, <months>, <weekdays>, and
<year> delimeted with spaces. You can use either form but the
<cron> element will be preferred by the implementation if you use both forms
together in one <trigger> element. A description of the
expressions used inside the <trigger> elements is described in the
CronTrigger class.
Job Components
The
CronJob
object doing your work can be defined in the cocoon.xconf
file as a regular Avalon components. The role attribute given to this component is
refered to by the target attribute in the <trigger> element above.
Below is the sample for the
TestCronJob component.
1.1 cocoon-2.1/src/blocks/cron/samples/samples.xml
Index: samples.xml
===================================================================
Documentation for the Cron component.
1.1 cocoon-2.1/src/blocks/cron/samples/sitemap.xmap
Index: sitemap.xmap
===================================================================