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