001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.scheduler;
018:
019: import java.util.Calendar;
020: import java.lang.Comparable;
021: import java.util.Date;
022:
023: /**
024: * This is a wrapper for a scheduled job. It is modeled after the
025: * Unix scheduler cron.
026: *
027: * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
028: * @version $Id: JobEntry.java 516448 2007-03-09 16:25:47Z ate $
029: */
030: public class JobEntry extends BaseJobEntry implements Comparable {
031:
032: /** indicates if job is currently running */
033: private boolean jobIsActive = false;
034:
035: /** Next runtime. **/
036: private long runtime = 0;
037:
038: /** schedule types **/
039: private static final int SECOND = 0;
040: private static final int MINUTE = 1;
041: private static final int WEEK_DAY = 2;
042: private static final int DAY_OF_MONTH = 3;
043: private static final int DAILY = 4;
044:
045: /**
046: * default constructor
047: */
048: public JobEntry() {
049: }
050:
051: /**
052: * Constuctor.
053: *
054: * Schedule a job to run on a certain point of time.<br>
055: *
056: * Example 1: Run the DefaultScheduledJob at 8:00am every 15th of
057: * the month - <br>
058: *
059: * JobEntry je = new JobEntry(0,0,8,15,"DefaultScheduledJob");<br>
060: *
061: * Example 2: Run the DefaultScheduledJob at 8:00am every day -
062: * <br>
063: *
064: * JobEntry je = new JobEntry(0,0,8,-1,"DefaultScheduledJob");<br>
065: *
066: * Example 3: Run the DefaultScheduledJob every 2 hours. - <br>
067: *
068: * JobEntry je = new JobEntry(0,120,-1,-1,"DefaultScheduledJob");<br>
069: *
070: * Example 4: Run the DefaultScheduledJob every 30 seconds. - <br>
071: *
072: * JobEntry je = new JobEntry(30,-1,-1,-1,"DefaultScheduledJob");<br>
073: *
074: * @param sec Value for entry "seconds".
075: * @param min Value for entry "minutes".
076: * @param hour Value for entry "hours".
077: * @param wd Value for entry "week days".
078: * @param day_mo Value for entry "month days".
079: * @param task Task to execute.
080: * @exception Exception, a generic exception.
081: */
082: public JobEntry(int sec, int min, int hour, int wd, int day_mo,
083: String task) throws Exception {
084: if (task == null || task.length() == 0) {
085: throw new Exception("Error in JobEntry. "
086: + "Bad Job parameter. Task not set.");
087: }
088:
089: setSecond(sec);
090: setMinute(min);
091: setHour(hour);
092: setWeekDay(wd);
093: setDayOfMonth(day_mo);
094: setTask(task);
095:
096: calcRunTime();
097: }
098:
099: /**
100: * Compares one JobEntry to another JobEntry based on the JobId
101: */
102: public int compareTo(Object je) {
103: int result = -1;
104: if (je instanceof JobEntry) {
105: if (jobId == ((JobEntry) je).getJobId()) {
106: return 0;
107: } else {
108: if (jobId > ((JobEntry) je).getJobId()) {
109: return 1;
110: }
111: }
112:
113: }
114: return result;
115: }
116:
117: /**
118: * Sets whether the job is running.
119: *
120: * @param isActive Whether the job is running.
121: */
122: public void setActive(boolean isActive) {
123: jobIsActive = isActive;
124: }
125:
126: /**
127: * Check to see if job is currently active/running
128: *
129: * @return true if job is currently geing run by the
130: * workerthread, otherwise false
131: */
132: public boolean isActive() {
133: return jobIsActive;
134: }
135:
136: /**
137: * Get the next runtime for this job as a long.
138: *
139: * @return The next run time as a long.
140: */
141: public long getNextRuntime() {
142: return runtime;
143: }
144:
145: /**
146: * Get the next runtime for this job as a String.
147: *
148: * @return The next run time as a String.
149: */
150: public String getNextRunAsString() {
151: return new Date(runtime).toString();
152: }
153:
154: /**
155: * Calculate how long before the next runtime.<br>
156: *
157: * The runtime determines it's position in the job queue.
158: * Here's the logic:<br>
159: *
160: * 1. Create a date the represents when this job is to run.<br>
161: *
162: * 2. If this date has expired, them "roll" appropriate date
163: * fields forward to the next date.<br>
164: *
165: * 3. Calculate the diff in time between the current time and the
166: * next run time.<br>
167: *
168: * @exception Exception, a generic exception.
169: */
170: public void calcRunTime() throws Exception {
171: Calendar schedrun = Calendar.getInstance();
172: Calendar now = Calendar.getInstance();
173:
174: switch (evaluateJobType()) {
175: case SECOND:
176: // SECOND (every so many seconds...)
177: schedrun.add(Calendar.SECOND, getSecond());
178: runtime = schedrun.getTime().getTime();
179: break;
180:
181: case MINUTE:
182: // MINUTE (every so many minutes...)
183: schedrun.add(Calendar.SECOND, getSecond());
184: schedrun.add(Calendar.MINUTE, getMinute());
185: runtime = schedrun.getTime().getTime();
186: break;
187:
188: case WEEK_DAY:
189: // WEEKDAY (day of the week)
190: schedrun.set(Calendar.SECOND, getSecond());
191: schedrun.set(Calendar.MINUTE, getMinute());
192: schedrun.set(Calendar.HOUR_OF_DAY, getHour());
193: schedrun.set(Calendar.DAY_OF_WEEK, getWeekDay());
194:
195: if (now.before(schedrun)) {
196: // Scheduled time has NOT expired.
197: runtime = schedrun.getTime().getTime();
198: } else {
199: // Scheduled time has expired; roll to the next week.
200: schedrun.add(Calendar.DAY_OF_WEEK, 7);
201: runtime = schedrun.getTime().getTime();
202: }
203: break;
204:
205: case DAY_OF_MONTH:
206: // DAY_OF_MONTH (date of the month)
207: schedrun.set(Calendar.SECOND, getSecond());
208: schedrun.set(Calendar.MINUTE, getMinute());
209: schedrun.set(Calendar.HOUR_OF_DAY, getHour());
210: schedrun.set(Calendar.DAY_OF_MONTH, getDayOfMonth());
211:
212: if (now.before(schedrun)) {
213: // Scheduled time has NOT expired.
214: runtime = schedrun.getTime().getTime();
215: } else {
216: // Scheduled time has expired; roll to the next month.
217: schedrun.add(Calendar.MONTH, 1);
218: runtime = schedrun.getTime().getTime();
219: }
220: break;
221:
222: case DAILY:
223: // DAILY (certain hour:minutes of the day)
224: schedrun.set(Calendar.SECOND, getSecond());
225: schedrun.set(Calendar.MINUTE, getMinute());
226: schedrun.set(Calendar.HOUR_OF_DAY, getHour());
227:
228: // Scheduled time has NOT expired.
229: if (now.before(schedrun)) {
230: runtime = schedrun.getTime().getTime();
231: } else {
232: // Scheduled time has expired; roll forward 24 hours.
233: schedrun.add(Calendar.HOUR_OF_DAY, 24);
234: runtime = schedrun.getTime().getTime();
235: }
236: break;
237:
238: default:
239: // Do nothing.
240: }
241: }
242:
243: /**
244: * What schedule am I on?
245: *
246: * I know this is kinda ugly! If you can think of a cleaner way
247: * to do this, please jump in!
248: *
249: * @return A number specifying the type of schedule. See
250: * calcRunTime().
251: * @exception Exception, a generic exception.
252: */
253: private int evaluateJobType() throws Exception {
254:
255: // First start by checking if it's a day of the month job.
256: if (getDayOfMonth() < 0) {
257: // Not a day of the month job... check weekday.
258: if (getWeekDay() < 0) {
259: // Not a weekday job...check if by the hour.
260: if (getHour() < 0) {
261: // Not an hourly job...check if it is by the minute
262: if (getMinute() < 0) {
263: // Not a by the minute job so must be by the second
264: if (getSecond() < 0)
265: throw new Exception(
266: "Error in JobEntry. Bad Job parameter.");
267:
268: return SECOND;
269: } else {
270: // Must be a job run by the minute so we need minutes and
271: // seconds.
272: if (getMinute() < 0 || getSecond() < 0)
273: throw new Exception(
274: "Error in JobEntry. Bad Job parameter.");
275:
276: return MINUTE;
277: }
278: } else {
279: // Must be a daily job by hours minutes, and seconds. In
280: // this case, we need the minute, second, and hour params.
281: if (getMinute() < 0 || getHour() < 0
282: || getSecond() < 0)
283: throw new Exception(
284: "Error in JobEntry. Bad Job parameter.");
285:
286: return DAILY;
287: }
288: } else {
289: // Must be a weekday job. In this case, we need
290: // minute, second, and hour params
291: if (getMinute() < 0 || getHour() < 0 || getSecond() < 0)
292: throw new Exception(
293: "Error in JobEntry. Bad Job parameter.");
294:
295: return WEEK_DAY;
296: }
297: } else {
298: // Must be a day of the month job. In this case, we need
299: // minute, second, and hour params
300: if (getMinute() < 0 || getHour() < 0)
301: throw new Exception(
302: "Error in JobEntry. Bad Job parameter.");
303:
304: return DAY_OF_MONTH;
305: }
306: }
307:
308: }
|