001: /*
002: * Copyright 2002-2006 the original author or authors.
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: */
016:
017: package org.springframework.scheduling.quartz;
018:
019: import java.util.Map;
020:
021: import org.quartz.Job;
022: import org.quartz.JobDetail;
023: import org.quartz.Scheduler;
024:
025: import org.springframework.beans.factory.BeanNameAware;
026: import org.springframework.beans.factory.InitializingBean;
027: import org.springframework.context.ApplicationContext;
028: import org.springframework.context.ApplicationContextAware;
029:
030: /**
031: * Convenience subclass of Quartz' JobDetail class that eases bean-style
032: * usage.
033: *
034: * <p><code>JobDetail</code> itself is already a JavaBean but lacks
035: * sensible defaults. This class uses the Spring bean name as job name,
036: * and the Quartz default group ("DEFAULT") as job group if not specified.
037: *
038: * @author Juergen Hoeller
039: * @since 18.02.2004
040: * @see #setName
041: * @see #setGroup
042: * @see org.springframework.beans.factory.BeanNameAware
043: * @see org.quartz.Scheduler#DEFAULT_GROUP
044: */
045: public class JobDetailBean extends JobDetail implements BeanNameAware,
046: ApplicationContextAware, InitializingBean {
047:
048: private Class actualJobClass;
049:
050: private String beanName;
051:
052: private ApplicationContext applicationContext;
053:
054: private String applicationContextJobDataKey;
055:
056: /**
057: * Overridden to support any job class, to allow a custom JobFactory
058: * to adapt the given job class to the Quartz Job interface.
059: * @see SchedulerFactoryBean#setJobFactory
060: */
061: public void setJobClass(Class jobClass) {
062: if (jobClass != null && !Job.class.isAssignableFrom(jobClass)) {
063: super .setJobClass(DelegatingJob.class);
064: this .actualJobClass = jobClass;
065: } else {
066: super .setJobClass(jobClass);
067: }
068: }
069:
070: /**
071: * Overridden to support any job class, to allow a custom JobFactory
072: * to adapt the given job class to the Quartz Job interface.
073: */
074: public Class getJobClass() {
075: return (this .actualJobClass != null ? this .actualJobClass
076: : super .getJobClass());
077: }
078:
079: /**
080: * Register objects in the JobDataMap via a given Map.
081: * <p>These objects will be available to this Job only,
082: * in contrast to objects in the SchedulerContext.
083: * <p>Note: When using persistent Jobs whose JobDetail will be kept in the
084: * database, do not put Spring-managed beans or an ApplicationContext
085: * reference into the JobDataMap but rather into the SchedulerContext.
086: * @param jobDataAsMap Map with String keys and any objects as values
087: * (for example Spring-managed beans)
088: * @see SchedulerFactoryBean#setSchedulerContextAsMap
089: */
090: public void setJobDataAsMap(Map jobDataAsMap) {
091: getJobDataMap().putAll(jobDataAsMap);
092: }
093:
094: /**
095: * Set a list of JobListener names for this job, referring to
096: * non-global JobListeners registered with the Scheduler.
097: * <p>A JobListener name always refers to the name returned
098: * by the JobListener implementation.
099: * @see SchedulerFactoryBean#setJobListeners
100: * @see org.quartz.JobListener#getName
101: */
102: public void setJobListenerNames(String[] names) {
103: for (int i = 0; i < names.length; i++) {
104: addJobListener(names[i]);
105: }
106: }
107:
108: public void setBeanName(String beanName) {
109: this .beanName = beanName;
110: }
111:
112: public void setApplicationContext(
113: ApplicationContext applicationContext) {
114: this .applicationContext = applicationContext;
115: }
116:
117: /**
118: * Set the key of an ApplicationContext reference to expose in the JobDataMap,
119: * for example "applicationContext". Default is none.
120: * Only applicable when running in a Spring ApplicationContext.
121: * <p>In case of a QuartzJobBean, the reference will be applied to the Job
122: * instance as bean property. An "applicationContext" attribute will correspond
123: * to a "setApplicationContext" method in that scenario.
124: * <p>Note that BeanFactory callback interfaces like ApplicationContextAware
125: * are not automatically applied to Quartz Job instances, because Quartz
126: * itself is responsible for the lifecycle of its Jobs.
127: * <p><b>Note: When using persistent job stores where JobDetail contents will
128: * be kept in the database, do not put an ApplicationContext reference into
129: * the JobDataMap but rather into the SchedulerContext.</b>
130: * @see SchedulerFactoryBean#setApplicationContextSchedulerContextKey
131: * @see org.springframework.context.ApplicationContext
132: */
133: public void setApplicationContextJobDataKey(
134: String applicationContextJobDataKey) {
135: this .applicationContextJobDataKey = applicationContextJobDataKey;
136: }
137:
138: public void afterPropertiesSet() {
139: if (getName() == null) {
140: setName(this .beanName);
141: }
142: if (getGroup() == null) {
143: setGroup(Scheduler.DEFAULT_GROUP);
144: }
145: if (this .applicationContextJobDataKey != null) {
146: if (this .applicationContext == null) {
147: throw new IllegalStateException(
148: "JobDetailBean needs to be set up in an ApplicationContext "
149: + "to be able to handle an 'applicationContextJobDataKey'");
150: }
151: getJobDataMap().put(this.applicationContextJobDataKey,
152: this.applicationContext);
153: }
154: }
155:
156: }
|