1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.scheduler;
35
36 import info.magnolia.module.ModuleLifecycle;
37 import info.magnolia.module.ModuleLifecycleContext;
38
39 import java.text.ParseException;
40 import java.util.ArrayList;
41 import java.util.Iterator;
42 import java.util.List;
43
44 import org.apache.commons.lang.StringUtils;
45 import org.quartz.CronTrigger;
46 import org.quartz.JobDetail;
47 import org.quartz.Scheduler;
48 import org.quartz.SchedulerException;
49 import org.quartz.SchedulerFactory;
50 import org.quartz.Trigger;
51 import org.quartz.impl.StdSchedulerFactory;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55
56
57
58
59
60
61
62
63
64 public class SchedulerModule implements ModuleLifecycle {
65 private static final Logger log = LoggerFactory.getLogger(JobDefinition.class);
66
67 private static SchedulerModule instance;
68
69 private List jobs = new ArrayList();
70
71 private boolean running = false;
72
73
74
75
76 protected Scheduler scheduler;
77
78 public SchedulerModule() {
79 instance = this;
80 }
81
82
83 public List getJobs() {
84 return this.jobs;
85 }
86
87
88 public void setJobs(List jobs) {
89 this.jobs = jobs;
90 }
91
92 public void addJob(JobDefinition job) throws SchedulerException{
93 jobs.add(job);
94 if(running){
95 initJob(job);
96 }
97 }
98
99
100
101
102 public void stop(ModuleLifecycleContext moduleLifecycleContext) {
103 try {
104 scheduler.shutdown(true);
105 running = false;
106 }
107 catch (SchedulerException e) {
108 log.error("Can't stop scheduler properly", e);
109 }
110 }
111
112
113
114
115 public void start(ModuleLifecycleContext moduleLifecycleContext) {
116 try {
117 initScheduler();
118 running = true;
119 }
120 catch (SchedulerException e) {
121 log.error("Can't start scheduler", e);
122 return;
123 }
124
125 initJobs();
126 }
127
128
129
130
131 protected void initJobs() {
132 for (Iterator iter = jobs.iterator(); iter.hasNext();) {
133 JobDefinition job = (JobDefinition) iter.next();
134 try {
135 initJob(job);
136 }
137 catch (SchedulerException e) {
138 log.error("Can't initialize job [" + job.getName() + "]", e);
139 }
140 }
141 }
142
143
144
145
146 protected void initJob(JobDefinition job) throws SchedulerException {
147 if (job.isActive()) {
148 try {
149 stopJob(job.getName());
150 startJob(job);
151 }
152 catch (SchedulerException e) {
153 throw new SchedulerException("Can't schedule job" + job.getName(), e);
154 }
155 }
156 else {
157 try {
158 stopJob(job.getName());
159 } catch (SchedulerException e) {
160 throw new SchedulerException("Can't delete inactive job " + job.getName(), e);
161 }
162 }
163 }
164
165 protected void startJob(JobDefinition job) throws SchedulerException {
166 Trigger trigger;
167 try {
168 String cron = cronToQuarzCron(job.getCron());
169 trigger = new CronTrigger(job.getName(), SchedulerConsts.SCHEDULER_GROUP_NAME, cron);
170 }
171 catch (ParseException e) {
172 log.error("Can't parse the job's cron expression [" + job.getCron() + "]", e);
173 return;
174 }
175
176 final Class jobClass = job.isConcurrent() ? CommandJob.class : StatefulCommandJob.class;
177 final JobDetail jd = new JobDetail(job.getName(), SchedulerConsts.SCHEDULER_GROUP_NAME, jobClass);
178 jd.getJobDataMap().put(SchedulerConsts.CONFIG_JOB_COMMAND, job.getCommand());
179 jd.getJobDataMap().put(SchedulerConsts.CONFIG_JOB_COMMAND_CATALOG, job.getCatalog());
180 jd.getJobDataMap().put(SchedulerConsts.CONFIG_JOB_PARAMS, job.getParams());
181 scheduler.scheduleJob(jd, trigger);
182 log.info("Job " + job.getName() + " added [" + job.getCron() + "]. Will fire first time at " + trigger.getNextFireTime());
183 }
184
185
186 protected String cronToQuarzCron(String cron) {
187
188 String[] tokens = StringUtils.split(cron);
189 if (tokens.length >= 6) {
190 if (!tokens[3].equals("?") && !tokens[5].equals("?")) {
191 if(tokens[5].equals("*")){
192 tokens[5] = "?";
193 }
194 else if(tokens[3].equals("*")){
195 tokens[3] = "?";
196 }
197 }
198 }
199 cron = StringUtils.join(tokens, " ");
200 return cron;
201 }
202
203
204
205
206 public void stopJob(String name) throws SchedulerException {
207 scheduler.deleteJob(name, SchedulerConsts.SCHEDULER_GROUP_NAME);
208 }
209
210
211
212
213
214 protected void initScheduler() throws SchedulerException {
215 SchedulerFactory sf = new StdSchedulerFactory();
216 scheduler = sf.getScheduler();
217 scheduler.start();
218 }
219
220
221
222
223 public Scheduler getScheduler() {
224 return scheduler;
225 }
226
227
228
229
230 public static SchedulerModule getInstance() {
231 return instance;
232 }
233
234 }