001 package org.apache.turbine.services.schedule;
002
003
004 import java.sql.Date;
005 import java.util.Calendar;
006
007 import org.apache.commons.lang.StringUtils;
008 import org.apache.commons.logging.Log;
009 import org.apache.commons.logging.LogFactory;
010 import org.apache.torque.om.Persistent;
011 import org.apache.turbine.util.TurbineException;
012
013 /**
014 * The skeleton for this class was autogenerated by Torque on:
015 *
016 * [Mon Jan 24 20:11:00 CET 2011]
017 *
018 * You should add additional methods to this class to meet the
019 * application requirements. This class will only be generated as
020 * long as it does not already exist in the output directory.
021 */
022 public class JobEntry
023 extends org.apache.turbine.services.schedule.BaseJobEntry
024 implements Persistent
025 {
026 /**
027 *
028 */
029 private static final long serialVersionUID = -5501116588294474363L;
030
031 /** Logging */
032 private static Log log = LogFactory.getLog(ScheduleService.LOGGER_NAME);
033
034 /** indicates if job is currently running */
035 private boolean jobIsActive = false;
036
037 /** Next runtime. **/
038 private long runtime = 0;
039
040 /** schedule types **/
041 private static final int SECOND = 0;
042 private static final int MINUTE = 1;
043 private static final int WEEK_DAY = 2;
044 private static final int DAY_OF_MONTH = 3;
045 private static final int DAILY = 4;
046
047 /**
048 * default constructor
049 */
050 public JobEntry()
051 {
052 // empty
053 }
054
055 /**
056 * Constuctor.
057 *
058 * Schedule a job to run on a certain point of time.<br>
059 *
060 * Example 1: Run the DefaultScheduledJob at 8:00am every 15th of
061 * the month - <br>
062 *
063 * JobEntry je = new JobEntry(0,0,8,15,"DefaultScheduledJob");<br>
064 *
065 * Example 2: Run the DefaultScheduledJob at 8:00am every day -
066 * <br>
067 *
068 * JobEntry je = new JobEntry(0,0,8,-1,"DefaultScheduledJob");<br>
069 *
070 * Example 3: Run the DefaultScheduledJob every 2 hours. - <br>
071 *
072 * JobEntry je = new JobEntry(0,120,-1,-1,"DefaultScheduledJob");<br>
073 *
074 * Example 4: Run the DefaultScheduledJob every 30 seconds. - <br>
075 *
076 * JobEntry je = new JobEntry(30,-1,-1,-1,"DefaultScheduledJob");<br>
077 *
078 * @param sec Value for entry "seconds".
079 * @param min Value for entry "minutes".
080 * @param hour Value for entry "hours".
081 * @param wd Value for entry "week days".
082 * @param day_mo Value for entry "month days".
083 * @param task Task to execute.
084 * @exception TurbineException a generic exception.
085 */
086 public JobEntry(int sec,
087 int min,
088 int hour,
089 int wd,
090 int day_mo,
091 String task)
092 throws TurbineException
093 {
094 if (StringUtils.isEmpty(task))
095 {
096 throw new TurbineException("Error in JobEntry. " +
097 "Bad Job parameter. Task not set.");
098 }
099
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 }