1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.fulcrum.quartz.impl;
21
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Properties;
26 import java.util.Set;
27
28 import org.apache.avalon.framework.activity.Disposable;
29 import org.apache.avalon.framework.activity.Initializable;
30 import org.apache.avalon.framework.activity.Startable;
31 import org.apache.avalon.framework.configuration.Configurable;
32 import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.avalon.framework.configuration.ConfigurationException;
34 import org.apache.avalon.framework.logger.AbstractLogEnabled;
35 import org.apache.avalon.framework.logger.LogEnabled;
36 import org.apache.avalon.framework.parameters.Parameters;
37 import org.apache.avalon.framework.service.ServiceException;
38 import org.apache.avalon.framework.service.ServiceManager;
39 import org.apache.avalon.framework.service.Serviceable;
40 import org.apache.avalon.framework.thread.ThreadSafe;
41 import org.apache.fulcrum.quartz.QuartzScheduler;
42 import org.quartz.Job;
43 import org.quartz.JobDetail;
44 import org.quartz.JobExecutionContext;
45 import org.quartz.JobExecutionException;
46 import org.quartz.JobKey;
47 import org.quartz.JobListener;
48 import org.quartz.Scheduler;
49 import org.quartz.SchedulerException;
50 import org.quartz.Trigger;
51 import org.quartz.impl.StdSchedulerFactory;
52 import org.quartz.impl.matchers.GroupMatcher;
53
54
55
56
57 public class QuartzSchedulerImpl
58 extends AbstractLogEnabled
59 implements QuartzScheduler, Configurable, Serviceable, Disposable, Initializable, ThreadSafe, JobListener, Startable
60 {
61
62
63
64 private ServiceManager serviceManager;
65
66
67
68
69 private Scheduler scheduler;
70
71
72
73
74 private String quartzPropertyFile;
75
76
77
78
79 private Properties quartzProperties;
80
81
82
83
84
85
86 public void configure(Configuration conf) throws ConfigurationException
87 {
88 Configuration quartzConf = conf.getChild("configuration", true);
89
90 if(quartzConf.getChild("properties", false) != null)
91 {
92 this.quartzProperties = Parameters.toProperties(Parameters.fromConfiguration(quartzConf.getChild("properties")));
93 }
94 else if(quartzConf.getChild("quartzPropertyFile", false) != null)
95 {
96 this.quartzPropertyFile = quartzConf.getChild("quartzPropertyFile").getValue();
97 }
98 }
99
100
101
102
103 public void service(ServiceManager manager) throws ServiceException
104 {
105 this.serviceManager = manager;
106 }
107
108
109
110
111 public void initialize() throws Exception
112 {
113
114 StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
115 if(this.quartzProperties != null)
116 {
117 getLogger().info("Pulling quartz configuration from the container XML configuration");
118 schedulerFactory.initialize(this.quartzProperties);
119 }
120 else if(this.quartzPropertyFile != null)
121 {
122 getLogger().info("Pulling quartz configuration from the following property file : " + this.quartzPropertyFile);
123 schedulerFactory.initialize(this.quartzPropertyFile);
124 }
125 else
126 {
127 getLogger().info("Using Quartz default configuration since no user-supplied configuration was found");
128 schedulerFactory.initialize();
129 }
130
131 this.scheduler = schedulerFactory.getScheduler();
132
133
134 getScheduler().getListenerManager().addJobListener(this, new ArrayList());
135 }
136
137 public void start() throws Exception
138 {
139 getScheduler().start();
140
141 if(getLogger().isInfoEnabled())
142 {
143 logSchedulerConfiguration();
144 }
145
146 }
147
148 public void stop() throws Exception
149 {
150 getScheduler().standby();
151 }
152
153
154
155
156 public void dispose()
157 {
158 try
159 {
160
161 this.scheduler.shutdown(true);
162 }
163 catch (SchedulerException e)
164 {
165 this.getLogger().warn("Problem shutting down quartz scheduler ", e);
166 }
167
168 this.scheduler = null;
169 this.serviceManager = null;
170 }
171
172
173
174
175
176
177 public Scheduler getScheduler()
178 {
179 return scheduler;
180 }
181
182
183
184
185
186
187 public String getName()
188 {
189 return getClass().getName();
190 }
191
192
193
194
195
196
197
198 public void jobToBeExecuted(JobExecutionContext context)
199 {
200 Job job = context.getJobInstance();
201
202
203 if(job instanceof LogEnabled)
204 {
205 ((LogEnabled) job).enableLogging(getLogger());
206 }
207
208
209 if (job instanceof Serviceable)
210 {
211 try
212 {
213 ((Serviceable) job).service(serviceManager);
214 }
215 catch (ServiceException e)
216 {
217 getLogger().error("Error servicing Job[" + job + "]", e);
218 }
219 }
220 }
221
222
223
224
225 public void jobWasExecuted(JobExecutionContext context, JobExecutionException ex)
226 {
227 if (ex != null)
228 {
229 String msg = "Executing the job '" + context.getJobDetail().getKey() + "' failed";
230 getLogger().error(msg, ex.getCause());
231 }
232 else
233 {
234 if (getLogger().isDebugEnabled())
235 {
236 getLogger().debug("Executing the job '" + context.getJobDetail().getKey() + "' took " + context.getJobRunTime() + " ms");
237 }
238 }
239 }
240
241
242
243
244 public void jobExecutionVetoed(JobExecutionContext context)
245 {
246
247 }
248
249
250
251 private void logSchedulerConfiguration() throws SchedulerException
252 {
253 List jobGroups = getScheduler().getJobGroupNames();
254 for (Iterator i = jobGroups.iterator(); i.hasNext();)
255 {
256 String jobGroup = (String)i.next();
257 Set jobsInGroup = getScheduler().getJobKeys(GroupMatcher.groupEquals(jobGroup));
258 getLogger().info("Job Group: " + jobGroup + " contains the following number of jobs : " + jobsInGroup.size());
259 for (Iterator j = jobsInGroup.iterator(); j.hasNext();)
260 {
261 StringBuffer buffer = new StringBuffer();
262 JobKey jobKey = (JobKey)j.next();
263 JobDetail jobDetail = getScheduler().getJobDetail(jobKey);
264 List jobTriggers = getScheduler().getTriggersOfJob(jobKey);
265 buffer.append(jobDetail.getKey());
266 buffer.append(" => ");
267 if(jobTriggers != null && !jobTriggers.isEmpty())
268 {
269 Trigger jt = (Trigger)jobTriggers.get(0);
270 buffer.append(jt.getKey());
271 buffer.append(" (");
272 buffer.append(jt.getNextFireTime());
273 buffer.append(")");
274 }
275 else
276 {
277 buffer.append("no trigger defined");
278 }
279
280 getLogger().info(buffer.toString());
281 }
282 }
283 }
284 }