1 package org.apache.turbine.services.schedule;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.List;
23 import java.util.Vector;
24
25 import javax.servlet.ServletConfig;
26
27 import org.apache.commons.configuration.Configuration;
28
29 import org.apache.commons.lang.StringUtils;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 import org.apache.turbine.services.InitializationException;
35 import org.apache.turbine.util.TurbineException;
36
37 /**
38 * Service for a cron like scheduler that uses the
39 * TurbineResources.properties file instead of the database.
40 * The methods that operate on jobs ( get,add,update,remove )
41 * only operate on the queue in memory and changes are not reflected
42 * to the properties file which was used to initilize the jobs.
43 * An example is given below. The job names are the class names that
44 * extend ScheduledJob.
45 *
46 * <PRE>
47 *
48 * services.SchedulerService.scheduler.jobs=scheduledJobName,scheduledJobName2
49 *
50 * services.SchedulerService.scheduler.job.scheduledJobName.ID=1
51 * services.SchedulerService.scheduler.job.scheduledJobName.SECOND=-1
52 * services.SchedulerService.scheduler.job.scheduledJobName.MINUTE=-1
53 * services.SchedulerService.scheduler.job.scheduledJobName.HOUR=7
54 * services.SchedulerService.scheduler.job.scheduledJobName.WEEKDAY=-1
55 * services.SchedulerService.scheduler.job.scheduledJobName.DAY_OF_MONTH=-1
56 *
57 * services.SchedulerService.scheduler.job.scheduledJobName2.ID=1
58 * services.SchedulerService.scheduler.job.scheduledJobName2.SECOND=-1
59 * services.SchedulerService.scheduler.job.scheduledJobName2.MINUTE=-1
60 * services.SchedulerService.scheduler.job.scheduledJobName2.HOUR=7
61 * services.SchedulerService.scheduler.job.scheduledJobName2.WEEKDAY=-1
62 * services.SchedulerService.scheduler.job.scheduledJobName2.DAY_OF_MONTH=-1
63 *
64 * </PRE>
65 *
66 * Based on TamboraSchedulerService written by John Thorhauer.
67 *
68 * @author <a href="mailto:ekkerbj@netscpae.net">Jeff Brekke</a>
69 * @author <a href="mailto:john@zenplex.com">John Thorhauer</a>
70 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
71 * @version $Id: TurbineNonPersistentSchedulerService.java 534527 2007-05-02 16:10:59Z tv $
72 */
73 public class TurbineNonPersistentSchedulerService
74 extends TurbineSchedulerService
75 {
76 /** Logging */
77 private static Log log = LogFactory.getLog(ScheduleService.LOGGER_NAME);
78
79 /**
80 * Constructor.
81 *
82 * @exception TurbineException a generic exception.
83 */
84 public TurbineNonPersistentSchedulerService()
85 throws TurbineException
86 {
87 super();
88 }
89
90 /**
91 * Called the first time the Service is used.<br>
92 *
93 * Load all the jobs from cold storage. Add jobs to the queue
94 * (sorted in ascending order by runtime) and start the scheduler
95 * thread.
96 */
97 @SuppressWarnings("unchecked")
98 @Override
99 public void init()
100 throws InitializationException
101 {
102 Configuration conf = getConfiguration();
103
104 try
105 {
106 scheduleQueue = new JobQueue();
107 mainLoop = new MainLoop();
108
109 List<String> jobProps = conf.getList("scheduler.jobs");
110 List<JobEntry> jobs = new Vector<JobEntry>();
111 // If there are scheduler.jobs defined then set up a job vector
112 // for the scheduleQueue
113 if (!jobProps.isEmpty())
114 {
115 for (int i = 0; i < jobProps.size(); i++)
116 {
117 String jobName = jobProps.get(i);
118 String jobPrefix = "scheduler.job." + jobName;
119
120 String jobId = conf.getString(jobPrefix + ".ID", null);
121 if (StringUtils.isEmpty(jobId))
122 {
123 throw new Exception(
124 "There is an error in the TurbineResources.properties file. \n"
125 + jobPrefix + ".ID is not found.\n");
126 }
127
128 int sec = conf.getInt(jobPrefix + ".SECOND", -1);
129 int min = conf.getInt(jobPrefix + ".MINUTE", -1);
130 int hr = conf.getInt(jobPrefix + ".HOUR", -1);
131 int wkday = conf.getInt(jobPrefix + ".WEEKDAY", -1);
132 int dayOfMonth = conf.getInt(jobPrefix + ".DAY_OF_MONTH", -1);
133
134 JobEntry je = new JobEntry(
135 sec,
136 min,
137 hr,
138 wkday,
139 dayOfMonth,
140 jobName);
141 je.setJobId(Integer.parseInt(jobId));
142 jobs.add(je);
143
144 }
145 }
146
147 if (jobs != null && jobs.size() > 0)
148 {
149 scheduleQueue.batchLoad(jobs);
150 }
151
152 setEnabled(getConfiguration().getBoolean("enabled", true));
153 restart();
154
155 setInit(true);
156 }
157 catch (Exception e)
158 {
159 String errorMessage = "Could not initialize the scheduler service";
160 log.error(errorMessage, e);
161 throw new InitializationException(errorMessage, e);
162 }
163 }
164
165 /**
166 * Called the first time the Service is used.<br>
167 *
168 * Load all the jobs from cold storage. Add jobs to the queue
169 * (sorted in ascending order by runtime) and start the scheduler
170 * thread.
171 *
172 * @param config A ServletConfig.
173 * @deprecated use init() instead.
174 */
175 @Deprecated
176 @Override
177 public void init(ServletConfig config)
178 throws InitializationException
179 {
180 init();
181 }
182
183 /**
184 * This method returns the job element from the internal queue.
185 *
186 * @param oid The int id for the job.
187 * @return A JobEntry.
188 * @exception TurbineException could not retrieve job
189 */
190 @Override
191 public JobEntry getJob(int oid)
192 throws TurbineException
193 {
194 JobEntry je = new JobEntry();
195 je.setJobId(oid);
196 return scheduleQueue.getJob(je);
197 }
198
199 /**
200 * Add a new job to the queue.
201 *
202 * @param je A JobEntry with the job to add.
203 * @throws TurbineException job could not be added
204 */
205 @Override
206 public void addJob(JobEntry je)
207 throws TurbineException
208 {
209 updateJob(je);
210 }
211
212 /**
213 * Remove a job from the queue.
214 *
215 * @param je A JobEntry with the job to remove.
216 */
217 @Override
218 public void removeJob(JobEntry je)
219 {
220 // Remove from the queue.
221 scheduleQueue.remove(je);
222 restart();
223 }
224
225 /**
226 * Add/update a job
227 *
228 * @param je A JobEntry with the job to modify
229 * @throws TurbineException job could not be updated
230 */
231 @Override
232 public void updateJob(JobEntry je)
233 throws TurbineException
234 {
235 try
236 {
237 je.calcRunTime();
238
239 // Update the queue.
240 scheduleQueue.modify(je);
241 restart();
242 }
243 catch (Exception e)
244 {
245 String errorMessage = "Problem updating Scheduled Job: " + je.getTask();
246 log.error(errorMessage, e);
247 throw new TurbineException(errorMessage, e);
248 }
249 }
250 }