1 package org.apache.turbine.services.schedule;
2
3
4 import java.sql.Date;
5 import java.util.Calendar;
6
7 import org.apache.commons.lang.StringUtils;
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.apache.torque.om.Persistent;
11 import org.apache.turbine.util.TurbineException;
12
13 /**
14 * The skeleton for this class was autogenerated by Torque on:
15 *
16 * [Mon Jan 24 20:11:00 CET 2011]
17 *
18 * You should add additional methods to this class to meet the
19 * application requirements. This class will only be generated as
20 * long as it does not already exist in the output directory.
21 */
22 public class JobEntry
23 extends org.apache.turbine.services.schedule.BaseJobEntry
24 implements Persistent
25 {
26 /**
27 *
28 */
29 private static final long serialVersionUID = -5501116588294474363L;
30
31 /** Logging */
32 private static Log log = LogFactory.getLog(ScheduleService.LOGGER_NAME);
33
34 /** indicates if job is currently running */
35 private boolean jobIsActive = false;
36
37 /** Next runtime. **/
38 private long runtime = 0;
39
40 /** schedule types **/
41 private static final int SECOND = 0;
42 private static final int MINUTE = 1;
43 private static final int WEEK_DAY = 2;
44 private static final int DAY_OF_MONTH = 3;
45 private static final int DAILY = 4;
46
47 /**
48 * default constructor
49 */
50 public JobEntry()
51 {
52 // empty
53 }
54
55 /**
56 * Constuctor.
57 *
58 * Schedule a job to run on a certain point of time.<br>
59 *
60 * Example 1: Run the DefaultScheduledJob at 8:00am every 15th of
61 * the month - <br>
62 *
63 * JobEntry je = new JobEntry(0,0,8,15,"DefaultScheduledJob");<br>
64 *
65 * Example 2: Run the DefaultScheduledJob at 8:00am every day -
66 * <br>
67 *
68 * JobEntry je = new JobEntry(0,0,8,-1,"DefaultScheduledJob");<br>
69 *
70 * Example 3: Run the DefaultScheduledJob every 2 hours. - <br>
71 *
72 * JobEntry je = new JobEntry(0,120,-1,-1,"DefaultScheduledJob");<br>
73 *
74 * Example 4: Run the DefaultScheduledJob every 30 seconds. - <br>
75 *
76 * JobEntry je = new JobEntry(30,-1,-1,-1,"DefaultScheduledJob");<br>
77 *
78 * @param sec Value for entry "seconds".
79 * @param min Value for entry "minutes".
80 * @param hour Value for entry "hours".
81 * @param wd Value for entry "week days".
82 * @param day_mo Value for entry "month days".
83 * @param task Task to execute.
84 * @exception TurbineException a generic exception.
85 */
86 public JobEntry(int sec,
87 int min,
88 int hour,
89 int wd,
90 int day_mo,
91 String task)
92 throws TurbineException
93 {
94 if (StringUtils.isEmpty(task))
95 {
96 throw new TurbineException("Error in JobEntry. " +
97 "Bad Job parameter. Task not set.");
98 }
99
100 setSecond(sec);
101 setMinute(min);
102 setHour(hour);
103 setWeekDay(wd);
104 setDayOfMonth(day_mo);
105 setTask(task);
106
107 calcRunTime();
108 }
109
110 /**
111 * Used for ordering Jobentries
112 * Note: this comparator imposes orderings that are inconsistent with
113 * equals.
114 *
115 * @param je The first <code>JobEntry</code> object.
116 * @return An <code>int</code> indicating the result of the comparison.
117 */
118 public int compareTo(Object je)
119 {
120 int result = -1;
121 if (je instanceof JobEntry)
122 {
123 result = getJobId() - ((JobEntry) je).getJobId();
124 }
125 return result;
126 }
127
128 /**
129 * Sets whether the job is running.
130 *
131 * @param isActive Whether the job is running.
132 */
133 public void setActive(boolean isActive)
134 {
135 jobIsActive = isActive;
136 }
137
138 /**
139 * Check to see if job is currently active/running
140 *
141 * @return true if job is currently geing run by the
142 * workerthread, otherwise false
143 */
144 public boolean isActive()
145 {
146 return jobIsActive;
147 }
148
149 /**
150 * Get the next runtime for this job as a long.
151 *
152 * @return The next run time as a long.
153 */
154 public long getNextRuntime()
155 {
156 return runtime;
157 }
158
159 /**
160 * Gets the next runtime as a date
161 *
162 * @return Next run date
163 */
164 public Date getNextRunDate()
165 {
166 return new Date(runtime);
167 }
168
169 /**
170 * Get the next runtime for this job as a String.
171 *
172 * @return The next run time as a String.
173 */
174 public String getNextRunAsString()
175 {
176 return getNextRunDate().toString();
177 }
178
179 /**
180 * Calculate how long before the next runtime.<br>
181 *
182 * The runtime determines it's position in the job queue.
183 * Here's the logic:<br>
184 *
185 * 1. Create a date the represents when this job is to run.<br>
186 *
187 * 2. If this date has expired, them "roll" appropriate date
188 * fields forward to the next date.<br>
189 *
190 * 3. Calculate the diff in time between the current time and the
191 * next run time.<br>
192 *
193 * @exception TurbineException a generic exception.
194 */
195 public void calcRunTime()
196 throws TurbineException
197 {
198 Calendar schedrun = Calendar.getInstance();
199 Calendar now = Calendar.getInstance();
200
201 switch (evaluateJobType())
202 {
203 case SECOND:
204 // SECOND (every so many seconds...)
205 schedrun.add(Calendar.SECOND, getSecond());
206 runtime = schedrun.getTime().getTime();
207 break;
208
209 case MINUTE:
210 // MINUTE (every so many minutes...)
211 schedrun.add(Calendar.SECOND, getSecond());
212 schedrun.add(Calendar.MINUTE, getMinute());
213 runtime = schedrun.getTime().getTime();
214 break;
215
216 case WEEK_DAY:
217 // WEEKDAY (day of the week)
218 schedrun.set(Calendar.SECOND, getSecond());
219 schedrun.set(Calendar.MINUTE, getMinute());
220 schedrun.set(Calendar.HOUR_OF_DAY, getHour());
221 schedrun.set(Calendar.DAY_OF_WEEK, getWeekDay());
222
223 if (now.before(schedrun))
224 {
225 // Scheduled time has NOT expired.
226 runtime = schedrun.getTime().getTime();
227 }
228 else
229 {
230 // Scheduled time has expired; roll to the next week.
231 schedrun.add(Calendar.DAY_OF_WEEK, 7);
232 runtime = schedrun.getTime().getTime();
233 }
234 break;
235
236 case DAY_OF_MONTH:
237 // DAY_OF_MONTH (date of the month)
238 schedrun.set(Calendar.SECOND, getSecond());
239 schedrun.set(Calendar.MINUTE, getMinute());
240 schedrun.set(Calendar.HOUR_OF_DAY, getHour());
241 schedrun.set(Calendar.DAY_OF_MONTH, getDayOfMonth());
242
243 if (now.before(schedrun))
244 {
245 // Scheduled time has NOT expired.
246 runtime = schedrun.getTime().getTime();
247 }
248 else
249 {
250 // Scheduled time has expired; roll to the next month.
251 schedrun.add(Calendar.MONTH, 1);
252 runtime = schedrun.getTime().getTime();
253 }
254 break;
255
256 case DAILY:
257 // DAILY (certain hour:minutes of the day)
258 schedrun.set(Calendar.SECOND, getSecond());
259 schedrun.set(Calendar.MINUTE, getMinute());
260 schedrun.set(Calendar.HOUR_OF_DAY, getHour());
261
262 // Scheduled time has NOT expired.
263 if (now.before(schedrun))
264 {
265 runtime = schedrun.getTime().getTime();
266 }
267 else
268 {
269 // Scheduled time has expired; roll forward 24 hours.
270 schedrun.add(Calendar.HOUR_OF_DAY, 24);
271 runtime = schedrun.getTime().getTime();
272 }
273 break;
274
275 default:
276 // Do nothing.
277 }
278
279 log.info("Next runtime for task " + this.getTask() + " is " + this.getNextRunDate());
280 }
281
282 /**
283 * What schedule am I on?
284 *
285 * I know this is kinda ugly! If you can think of a cleaner way
286 * to do this, please jump in!
287 *
288 * @return A number specifying the type of schedule. See
289 * calcRunTime().
290 * @exception TurbineException a generic exception.
291 */
292 private int evaluateJobType()
293 throws TurbineException
294 {
295
296 // First start by checking if it's a day of the month job.
297 if (getDayOfMonth() < 0)
298 {
299 // Not a day of the month job... check weekday.
300 if (getWeekDay() < 0)
301 {
302 // Not a weekday job...check if by the hour.
303 if (getHour() < 0)
304 {
305 // Not an hourly job...check if it is by the minute
306 if (getMinute() < 0)
307 {
308 // Not a by the minute job so must be by the second
309 if (getSecond() < 0)
310 throw new TurbineException("Error in JobEntry. Bad Job parameter.");
311
312 return SECOND;
313 }
314 else
315 {
316 // Must be a job run by the minute so we need minutes and
317 // seconds.
318 if (getMinute() < 0 || getSecond() < 0)
319 throw new TurbineException("Error in JobEntry. Bad Job parameter.");
320
321 return MINUTE;
322 }
323 }
324 else
325 {
326 // Must be a daily job by hours minutes, and seconds. In
327 // this case, we need the minute, second, and hour params.
328 if (getMinute() < 0 || getHour() < 0 || getSecond() < 0)
329 throw new TurbineException("Error in JobEntry. Bad Job parameter.");
330
331 return DAILY;
332 }
333 }
334 else
335 {
336 // Must be a weekday job. In this case, we need
337 // minute, second, and hour params
338 if (getMinute() < 0 || getHour() < 0 || getSecond() < 0)
339 throw new TurbineException("Error in JobEntry. Bad Job parameter.");
340
341 return WEEK_DAY;
342 }
343 }
344 else
345 {
346 // Must be a day of the month job. In this case, we need
347 // minute, second, and hour params
348 if (getMinute() < 0 || getHour() < 0)
349 throw new TurbineException("Error in JobEntry. Bad Job parameter.");
350
351 return DAY_OF_MONTH;
352 }
353 }
354
355 }