KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > applications > crontab > CronEntry


1 /*
2  This software is OSI Certified Open Source Software.
3 OSI Certified is a certification mark of the Open Source Initiative.
4
5 The license (Mozilla version 1.0) can be read at the MMBase site.
6 See http://www.MMBase.org/license
7  */

8 package org.mmbase.applications.crontab;
9
10 import java.util.*;
11
12 import org.mmbase.util.logging.*;
13
14 /**
15  * Defines one entry for CronDaemon. This class is used by the CronDaemon.
16  *
17  * @author Kees Jongenburger
18  * @author Michiel Meeuwissen
19  * @version $Id: CronEntry.java,v 1.6 2006/08/30 18:07:28 michiel Exp $
20  */

21
22 public class CronEntry {
23
24     private static final Logger log = Logging.getLoggerInstance(CronEntry.class);
25
26     /**
27      * A CronEntry of this type will run without the overhead of an extra thread. This does mean
28      * though that such a job will halt the cron-daemon itself. Such jobs must therefore be
29      * extremely short-living, and used with care (only if you have a lot of those which must run
30      * very often)
31      */

32     public static final int SHORT_JOB_TYPE = 0;
33
34     public static final String JavaDoc SHORT_JOB_TYPE_STRING = "short";
35
36     /**
37      * The default job type is the 'must be one' job. Such jobs are not started if the same job is
38      * still running. They are wrapped in a seperate thread, so other jobs can be started during the
39      * execution of this one.
40      */

41     public static final int MUSTBEONE_JOB_TYPE = 1;
42
43     public static final String JavaDoc MUSTBEONE_JOB_TYPE_STRING = "mustbeone";
44
45     /**
46      * The 'can be more' type job is like a 'must be one' job, but the run() method of such jobs is even
47      * called (when scheduled) if it itself is still running.
48      */

49     public static final int CANBEMORE_JOB_TYPE = 2;
50
51     public static final String JavaDoc CANBEMORE_JOB_TYPE_STRING = "canbemore";
52
53     public static final int DEFAULT_JOB_TYPE = MUSTBEONE_JOB_TYPE;
54
55     public static final String JavaDoc DEFAULT_JOB_TYPE_STRING = MUSTBEONE_JOB_TYPE_STRING;
56
57     private CronJob cronJob;
58
59     private List threads = Collections.synchronizedList(new ArrayList());
60
61     private final String JavaDoc id;
62     private final String JavaDoc name;
63     private final String JavaDoc className;
64     private final String JavaDoc cronTime;
65     private String JavaDoc configuration = null;
66
67     private int count = 0;
68
69     private final CronEntryField second = new CronEntryField(); // 0-59
70
private final CronEntryField minute = new CronEntryField(); // 0-59
71
private final CronEntryField hour = new CronEntryField(); // 0-23
72
private final CronEntryField dayOfMonth = new CronEntryField(); // 1-31
73
private final CronEntryField month = new CronEntryField(); // 1-12
74
private final CronEntryField dayOfWeek = new CronEntryField(); // 0-7 (0 or 7 is sunday)
75

76     private int type = DEFAULT_JOB_TYPE;
77
78     public CronEntry(String JavaDoc id, String JavaDoc cronTime, String JavaDoc name, String JavaDoc className, String JavaDoc configuration) throws Exception JavaDoc {
79         this(id, cronTime, name, className, configuration, DEFAULT_JOB_TYPE);
80     }
81
82     public CronEntry(String JavaDoc id, String JavaDoc cronTime, String JavaDoc name, String JavaDoc className, String JavaDoc configuration, String JavaDoc typeString) throws Exception JavaDoc {
83         this(id, cronTime, name, className, configuration, stringToJobType(typeString));
84     }
85
86     /**
87      * @throws ClassCastException if className does not refer to a Runnable.
88      * @throws RuntimeException if the cronTime format isn't correct
89      */

90     public CronEntry(String JavaDoc id, String JavaDoc cronTime, String JavaDoc name, String JavaDoc className, String JavaDoc configuration, int type) throws Exception JavaDoc {
91         this.id = id;
92         this.name = name == null ? "" : name;
93         this.className = className;
94         this.cronTime = cronTime;
95         this.configuration = configuration;
96         this.type = type;
97
98         Runnable JavaDoc runnable = (Runnable JavaDoc) Class.forName(className).newInstance();
99         if (! (runnable instanceof CronJob)) {
100             cronJob = new RunnableCronJob(runnable);
101         } else {
102             cronJob = (CronJob) runnable;
103         }
104
105         setCronTime(cronTime);
106     }
107
108     public void init() {
109         cronJob.init(this);
110     }
111
112     public void stop() {
113         synchronized(threads) {
114             Iterator i = threads.iterator();
115             while (i.hasNext()) {
116                 Interruptable thread = (Interruptable) i.next();
117                 thread.interrupt();
118             }
119         }
120         cronJob.stop();
121     }
122     /**
123      * @since MMBase-1.8
124      */

125     public Interruptable getThread(int i) {
126         synchronized(threads) {
127             if (threads.size() <= i) return null;
128             return (Interruptable) threads.get(i);
129         }
130     }
131     public List getThreads() {
132         return new ArrayList(threads);
133     }
134     /**
135      * @since MMBase-1.8
136      */

137     public boolean isAlive(int i) {
138         Interruptable t = getThread(i);
139         return t != null && t.isAlive();
140
141     }
142     public boolean isAlive() {
143         return isAlive(0);
144     }
145
146     public boolean kick() {
147         switch (type) {
148             case SHORT_JOB_TYPE :
149                 {
150                     count++;
151                     try {
152                         Interruptable thread = new Interruptable(cronJob, threads);
153                         thread.run();
154                     } catch (Throwable JavaDoc t) {
155                         log.error("Error during cron-job " + this +" : " + t.getClass().getName() + " " + t.getMessage() + "\n" + Logging.stackTrace(t));
156                     }
157                     return true;
158                 }
159             case MUSTBEONE_JOB_TYPE :
160                 if (isAlive()) {
161                     return false;
162                 }
163                 // fall through
164
case CANBEMORE_JOB_TYPE :
165             default :
166                 count++;
167                 Interruptable thread = new Interruptable(cronJob, threads);
168                 org.mmbase.util.ThreadPools.jobsExecutor.execute(thread);
169                 return true;
170         }
171
172     }
173
174     protected void setCronTime(String JavaDoc cronTime) {
175         StringTokenizer st = new StringTokenizer(cronTime, " ");
176         if (st.countTokens() != 5) {
177             throw new RuntimeException JavaDoc("A crontime must contain 5 field please refer to the UNIX man page http://www.rt.com/man/crontab.5.html");
178         }
179
180         minute.setTimeVal(st.nextToken());
181         hour.setTimeVal(st.nextToken());
182         dayOfMonth.setTimeVal(st.nextToken());
183         month.setTimeVal(st.nextToken());
184         String JavaDoc dow = st.nextToken();
185
186         dayOfWeek.setTimeVal(dow);
187     }
188
189
190     public String JavaDoc getCronTime() {
191         return cronTime;
192     }
193
194     public String JavaDoc getId() {
195         return id;
196     }
197     public String JavaDoc getName() {
198         return name;
199     }
200
201     public void setConfiguration(String JavaDoc conf) {
202         configuration = conf;
203     }
204     public String JavaDoc getConfiguration() {
205         return configuration;
206     }
207     public String JavaDoc getType() {
208         return jobTypeToString(type);
209     }
210     public String JavaDoc getClassName() {
211         return className;
212     }
213
214     boolean mustRun(Date date) {
215         Calendar cal = Calendar.getInstance();
216         cal.setTime(date);
217         if (minute.valid(cal.get(Calendar.MINUTE))
218             && hour.valid(cal.get(Calendar.HOUR_OF_DAY))
219             && dayOfMonth.valid(cal.get(Calendar.DAY_OF_MONTH))
220             && month.valid(cal.get(Calendar.MONTH) + 1)
221             && dayOfWeek.valid(cal.get(Calendar.DAY_OF_WEEK) - 1)) {
222             return true;
223         }
224         return false;
225     }
226
227     public CronEntryField getMinuteEntry() {
228         return minute;
229     }
230
231     public CronEntryField getHourEntry() {
232         return hour;
233     }
234
235     public CronEntryField getDayOfMonthEntry() {
236         return dayOfMonth;
237     }
238
239     public CronEntryField getMonthEntry() {
240         return month;
241     }
242
243     public CronEntryField getDayOfWeekEntry() {
244         return dayOfWeek;
245     }
246
247     public String JavaDoc toString() {
248         return id + ":" + cronTime + ":" + name + ": " + className + ":" + configuration + ": count" + count + " type " + jobTypeToString(type);
249     }
250
251     public int hashCode() {
252         return id.hashCode() + name.hashCode() + className.hashCode() + cronTime.hashCode();
253     }
254
255     public boolean equals(Object JavaDoc o) {
256         if (!(o instanceof CronEntry)) {
257             return false;
258         }
259         CronEntry other = (CronEntry)o;
260         return id.equals(other.id) && name.equals(other.name) && className.equals(other.className) && cronTime.equals(other.cronTime);
261     }
262
263
264     /**
265      * Convert a jobType int to a jobType String. invalid types are accepted and return DEFAULT_JOB_TYPE_STRING
266      * @param type the job type
267      * @return The string representation of the job type
268      */

269     public static String JavaDoc jobTypeToString(int type) {
270         switch (type) {
271         case SHORT_JOB_TYPE :
272             return SHORT_JOB_TYPE_STRING;
273         case MUSTBEONE_JOB_TYPE :
274             return MUSTBEONE_JOB_TYPE_STRING;
275         case CANBEMORE_JOB_TYPE :
276             return CANBEMORE_JOB_TYPE_STRING;
277         }
278         return DEFAULT_JOB_TYPE_STRING;
279     }
280
281     /**
282      * Convert a jobType String to a jobType int. first the string is lowered cased and trimed.
283      * null values and invalid values are accepted and return the DEFAULT_JOB_TYPE
284      * @param type the string representation of the job type
285      * @return the int representation of the jobType
286      */

287     public static int stringToJobType(String JavaDoc type) {
288
289         if (type == null) {
290             return DEFAULT_JOB_TYPE;
291         }
292         type = type.toLowerCase().trim();
293
294         if (type.equals(SHORT_JOB_TYPE_STRING)) {
295             return SHORT_JOB_TYPE;
296         } else if (type.equals(MUSTBEONE_JOB_TYPE_STRING)) {
297             return MUSTBEONE_JOB_TYPE;
298         } else if (type.equals(CANBEMORE_JOB_TYPE_STRING)) {
299             return CANBEMORE_JOB_TYPE;
300         }
301
302         return DEFAULT_JOB_TYPE;
303     }
304
305 }
306
Popular Tags