|
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