001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.cron;
018:
019: import java.util.Map;
020:
021: import org.apache.avalon.framework.container.ContainerUtil;
022: import org.apache.avalon.framework.context.Context;
023: import org.apache.avalon.framework.logger.Logger;
024: import org.apache.avalon.framework.parameters.Parameters;
025: import org.apache.avalon.framework.service.ServiceManager;
026: import org.quartz.Job;
027: import org.quartz.JobDataMap;
028: import org.quartz.JobExecutionContext;
029: import org.quartz.JobExecutionException;
030:
031: /**
032: * This component is resposible to launch a {@link CronJob}s in a Quart Scheduler.
033: *
034: * @author <a href="mailto:giacomo@apache.org">Giacomo Pati</a>
035: * @version CVS $Id: QuartzJobExecutor.java 433543 2006-08-22 06:22:54Z crossley $
036: *
037: * @since 2.1.1
038: */
039: public class QuartzJobExecutor implements Job {
040:
041: protected Logger m_logger;
042: protected Context m_context;
043: protected ServiceManager m_manager;
044:
045: /* (non-Javadoc)
046: * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
047: */
048: public void execute(final JobExecutionContext context)
049: throws JobExecutionException {
050:
051: final JobDataMap data = context.getJobDetail().getJobDataMap();
052:
053: final String name = (String) data
054: .get(QuartzJobScheduler.DATA_MAP_NAME);
055:
056: m_logger = (Logger) data
057: .get(QuartzJobScheduler.DATA_MAP_LOGGER);
058: m_context = (Context) data
059: .get(QuartzJobScheduler.DATA_MAP_CONTEXT);
060: m_manager = (ServiceManager) data
061: .get(QuartzJobScheduler.DATA_MAP_MANAGER);
062:
063: final Boolean canRunConcurrentlyB = ((Boolean) data
064: .get(QuartzJobScheduler.DATA_MAP_RUN_CONCURRENT));
065: final boolean canRunConcurrently = ((canRunConcurrentlyB == null) ? true
066: : canRunConcurrentlyB.booleanValue());
067:
068: if (!canRunConcurrently) {
069: Boolean isRunning = (Boolean) data
070: .get(QuartzJobScheduler.DATA_MAP_KEY_ISRUNNING);
071: if (Boolean.TRUE.equals(isRunning)) {
072: m_logger
073: .warn("Cron job name '"
074: + name
075: + " already running but configured to not allow concurrent runs. Will discard this scheduled run");
076: return;
077: }
078: }
079:
080: if (m_logger.isInfoEnabled()) {
081: m_logger.info("Executing cron job named '" + name + "'");
082: }
083:
084: setup(data);
085:
086: Object job = null;
087: String jobrole = null;
088: boolean release = false;
089: boolean dispose = false;
090: try {
091: jobrole = (String) data
092: .get(QuartzJobScheduler.DATA_MAP_ROLE);
093:
094: if (null == jobrole) {
095: job = data.get(QuartzJobScheduler.DATA_MAP_OBJECT);
096: ContainerUtil.enableLogging(job, m_logger);
097: ContainerUtil.contextualize(job, m_context);
098: ContainerUtil.service(job, m_manager);
099: dispose = true;
100: } else {
101: job = m_manager.lookup(jobrole);
102: release = true;
103: }
104:
105: if (job instanceof ConfigurableCronJob) {
106: final Parameters params = (Parameters) data
107: .get(QuartzJobScheduler.DATA_MAP_PARAMETERS);
108: final Map objects = (Map) data
109: .get(QuartzJobScheduler.DATA_MAP_OBJECTMAP);
110: ((ConfigurableCronJob) job).setup(params, objects);
111: }
112:
113: if (job instanceof Job) {
114: ((Job) job).execute(context);
115: } else if (job instanceof CronJob) {
116: ((CronJob) job).execute(name);
117: } else if (job instanceof Runnable) {
118: ((Runnable) job).run();
119: } else {
120: m_logger.error("job named '" + name
121: + "' is of invalid class: "
122: + job.getClass().getName());
123: }
124: } catch (final Throwable t) {
125: m_logger.error("Cron job name '" + name + "' died.", t);
126:
127: if (t instanceof JobExecutionException) {
128: throw (JobExecutionException) t;
129: }
130: } finally {
131:
132: release(data);
133:
134: if (m_manager != null && release) {
135: m_manager.release(job);
136: }
137: if (dispose) {
138: ContainerUtil.dispose(job);
139: }
140: }
141: }
142:
143: protected void setup(JobDataMap data) throws JobExecutionException {
144: data.put(QuartzJobScheduler.DATA_MAP_KEY_ISRUNNING,
145: Boolean.TRUE);
146: }
147:
148: protected void release(JobDataMap data) {
149: data.put(QuartzJobScheduler.DATA_MAP_KEY_ISRUNNING,
150: Boolean.FALSE);
151: }
152:
153: }
|