|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2009 the original author or authors. |
| 2 | + * Copyright 2002-2011 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
20 | 20 |
|
21 | 21 | import org.apache.commons.logging.Log;
|
22 | 22 | import org.apache.commons.logging.LogFactory;
|
| 23 | +import org.quartz.JobDataMap; |
23 | 24 | import org.quartz.JobDetail;
|
24 | 25 | import org.quartz.JobExecutionContext;
|
25 | 26 | import org.quartz.JobExecutionException;
|
26 | 27 | import org.quartz.Scheduler;
|
27 | 28 | import org.quartz.StatefulJob;
|
28 | 29 |
|
| 30 | +import org.springframework.beans.BeanUtils; |
| 31 | +import org.springframework.beans.BeanWrapper; |
| 32 | +import org.springframework.beans.PropertyAccessorFactory; |
29 | 33 | import org.springframework.beans.factory.BeanClassLoaderAware;
|
30 | 34 | import org.springframework.beans.factory.BeanFactory;
|
31 | 35 | import org.springframework.beans.factory.BeanFactoryAware;
|
|
61 | 65 | * You need to implement your own Quartz Job as a thin wrapper for each case
|
62 | 66 | * where you want a persistent job to delegate to a specific service method.
|
63 | 67 | *
|
| 68 | + * <p>Compatible with Quartz 1.5+ as well as Quartz 2.0, as of Spring 3.1. |
| 69 | + * |
64 | 70 | * @author Juergen Hoeller
|
65 | 71 | * @author Alef Arendsen
|
66 | 72 | * @since 18.02.2004
|
|
70 | 76 | * @see #setConcurrent
|
71 | 77 | */
|
72 | 78 | public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethodInvoker
|
73 |
| - implements FactoryBean<Object>, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean { |
| 79 | + implements FactoryBean<JobDetail>, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean { |
| 80 | + |
| 81 | + private static Class<?> jobDetailImplClass; |
| 82 | + |
| 83 | + static { |
| 84 | + try { |
| 85 | + jobDetailImplClass = Class.forName("org.quartz.impl.JobDetailImpl"); |
| 86 | + } |
| 87 | + catch (ClassNotFoundException ex) { |
| 88 | + jobDetailImplClass = null; |
| 89 | + } |
| 90 | + } |
| 91 | + |
74 | 92 |
|
75 | 93 | private String name;
|
76 | 94 |
|
@@ -174,14 +192,31 @@ public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodExce
|
174 | 192 | Class jobClass = (this.concurrent ? MethodInvokingJob.class : StatefulMethodInvokingJob.class);
|
175 | 193 |
|
176 | 194 | // Build JobDetail instance.
|
177 |
| - this.jobDetail = new JobDetail(name, this.group, jobClass); |
178 |
| - this.jobDetail.getJobDataMap().put("methodInvoker", this); |
179 |
| - this.jobDetail.setVolatility(true); |
180 |
| - this.jobDetail.setDurability(true); |
| 195 | + if (jobDetailImplClass != null) { |
| 196 | + // Using Quartz 2.0 JobDetailImpl class... |
| 197 | + Object jobDetail = BeanUtils.instantiate(jobDetailImplClass); |
| 198 | + BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(jobDetail); |
| 199 | + bw.setPropertyValue("name", name); |
| 200 | + bw.setPropertyValue("group", this.group); |
| 201 | + bw.setPropertyValue("jobClass", jobClass); |
| 202 | + bw.setPropertyValue("durability", true); |
| 203 | + ((JobDataMap) bw.getPropertyValue("jobDataMap")).put("methodInvoker", this); |
| 204 | + } |
| 205 | + else { |
| 206 | + // Using Quartz 1.x JobDetail class... |
| 207 | + this.jobDetail = new JobDetail(name, this.group, jobClass); |
| 208 | + this.jobDetail.setVolatility(true); |
| 209 | + this.jobDetail.setDurability(true); |
| 210 | + this.jobDetail.getJobDataMap().put("methodInvoker", this); |
| 211 | + } |
181 | 212 |
|
182 | 213 | // Register job listener names.
|
183 | 214 | if (this.jobListenerNames != null) {
|
184 | 215 | for (String jobListenerName : this.jobListenerNames) {
|
| 216 | + if (jobDetailImplClass != null) { |
| 217 | + throw new IllegalStateException("Non-global JobListeners not supported on Quartz 2 - " + |
| 218 | + "manually register a Matcher against the Quartz ListenerManager instead"); |
| 219 | + } |
185 | 220 | this.jobDetail.addJobListener(jobListenerName);
|
186 | 221 | }
|
187 | 222 | }
|
@@ -225,12 +260,12 @@ public Object getTargetObject() {
|
225 | 260 | }
|
226 | 261 |
|
227 | 262 |
|
228 |
| - public Object getObject() { |
| 263 | + public JobDetail getObject() { |
229 | 264 | return this.jobDetail;
|
230 | 265 | }
|
231 | 266 |
|
232 |
| - public Class<?> getObjectType() { |
233 |
| - return JobDetail.class; |
| 267 | + public Class<? extends JobDetail> getObjectType() { |
| 268 | + return (this.jobDetail != null ? this.jobDetail.getClass() : JobDetail.class); |
234 | 269 | }
|
235 | 270 |
|
236 | 271 | public boolean isSingleton() {
|
|
0 commit comments