KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > scalagent > scheduler > event > CronEvent


1 /*
2  * Copyright (C) 2001 - 2005 ScalAgent Distributed Technologies
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA.
18  *
19  * Initial developer(s): ScalAgent Distributed Technologies
20  * Contributor(s):
21  */

22 package com.scalagent.scheduler.event;
23
24 import java.util.*;
25
26 import fr.dyade.aaa.agent.*;
27 import com.scalagent.scheduler.*;
28
29 /**
30  * Notification requesting a recurrent scheduling to a <code>Scheduler</code> agent.
31  * The recurring occurence time is described in a cron like syntax, that is :
32  * <minutes> <hours> <days of month> <months> <days of week>
33  * <minutes> = [ 0-59 | * ]
34  * <hours> = [ 0-23 | * ]
35  * <days of month> = [ 1-31 | * ]
36  * <months> = [ 0-11 | * ]
37  * <days of week> = [ 0-6 | * ]
38  *
39  * @see Scheduler
40  * @see ScheduleEvent
41  */

42 public class CronEvent extends ScheduleEvent {
43   /** minutes of hour */
44   private static final int CRON_MN = 0;
45   /** hours of day */
46   private static final int CRON_H = 1;
47   /** days of month */
48   private static final int CRON_DOM = 2;
49   /** months of year */
50   private static final int CRON_MOY = 3;
51   /** days of week */
52   private static final int CRON_DOW = 4;
53   /** max value (+1) for <code>CRON_*</code> constants */
54   private static final int CRON_MAX = 5;
55
56   /** string image for <code>CRON_*</code> constants, by index in the table */
57   private static final String JavaDoc[] values = {
58     "minutes", "hours", "days of month", "months of year", "days of week"
59   };
60   /** minimum for values designed by <code>CRON_*</code> constants */
61   private static final int[] min = { 0, 0, 1, 0, 0 };
62   /** maximum for values designed by <code>CRON_*</code> constants */
63   private static final int[] max = { 59, 23, 31, 11, 6 };
64
65   /** cron dates for this event */
66   private BitSet ranges[] = new BitSet[CRON_MAX];
67
68
69   /**
70    * Creates an item.
71    *
72    * @param name event and condition name
73    * @param date event scheduling date as a cron like string
74    * @exception IllegalArgumentException when date is misformed
75    */

76   public CronEvent(String JavaDoc name, String JavaDoc date) throws IllegalArgumentException JavaDoc {
77     super(name, new Date());
78
79     StringTokenizer st = new StringTokenizer(date, " ", false);
80     if (st.countTokens() != CRON_MAX)
81       throw new IllegalArgumentException JavaDoc("Bad number of tokens in cron date");
82
83     String JavaDoc sched[] = new String JavaDoc[CRON_MAX];
84     for (int i = 0; i < CRON_MAX; i ++) {
85       sched[i] = st.nextToken();
86     }
87
88     for (int i = 0; i < CRON_MAX; i ++) {
89       String JavaDoc tok = null;
90       try {
91     ranges[i] = new BitSet(max[i] + 1);
92     st = new StringTokenizer(sched[i], ",", false);
93     while (st.countTokens() > 0) {
94       // range syntax is not allowed in first version
95
tok = st.nextToken();
96       if (tok.compareTo("*") == 0) {
97         for (int j = max[i]+1; j-- > 0;)
98           ranges[i].set(j);
99       } else {
100         int j = Integer.parseInt(tok);
101         if (j < min[i] || j > max[i])
102           throw new IllegalArgumentException JavaDoc("Bad " + values[i] + " (" + tok + ") in cron date");
103         ranges[i].set(j);
104       }
105     }
106       } catch (NumberFormatException JavaDoc exc) {
107     throw new IllegalArgumentException JavaDoc("Bad " + values[i] + " (" + tok + ") in cron date");
108       }
109     }
110   }
111
112
113   /**
114    * Provides a string image for this object.
115    *
116    * @return a string image for this object
117    */

118   public StringBuffer JavaDoc toString(StringBuffer JavaDoc output) {
119     output.append('(');
120     output.append(super.toString(output));
121     for (int i = 0; i < CRON_MAX; i ++) {
122       output.append(",");
123       output.append(values[i]);
124       output.append("=");
125       output.append(ranges[i]);
126     }
127     output.append(")");
128     return output;
129   }
130
131   /**
132    * Returns the next scheduling date after current date given as parameter.
133    * The new date must be strictly greater than the current date.
134    * A <code>null</code> date leads to the scheduler deleting the event.
135    *
136    * @param now current date
137    * @return next scheduling date after now
138    */

139   Date nextDate(Date now) {
140     // avoids multiple scheduling in a minute
141
long start = now.getTime() + 60000;
142     Calendar calendar = Calendar.getInstance();
143     calendar.clear();
144     calendar.setTime(new Date(start));
145
146     int idx_h = calendar.get(Calendar.HOUR_OF_DAY);
147     int idx_mn = calendar.get(Calendar.MINUTE);
148
149     date_loop:
150     while (true) {
151       while (! ranges[CRON_MOY].get(calendar.get(Calendar.MONTH))) {
152     calendar.set(Calendar.DAY_OF_MONTH, 1);
153     calendar.add(Calendar.MONTH, 1);
154     idx_h = 0;
155     idx_mn = 0;
156       }
157       month_block:
158       // authorized month, finds next day
159
while (true) {
160     day_block:
161     if (ranges[CRON_DOM].get(calendar.get(Calendar.DAY_OF_MONTH)) &&
162         ranges[CRON_DOW].get(calendar.get(Calendar.DAY_OF_WEEK))) {
163       // authorized day, finds next time in the day
164
while (true){
165         hour_block:
166         if (ranges[CRON_H].get(idx_h)) {
167           // finds minute in current hour
168
while (true) {
169         if (ranges[CRON_MN].get(idx_mn)) {
170           // next date found
171
calendar.set(Calendar.HOUR_OF_DAY, idx_h);
172           calendar.set(Calendar.MINUTE, idx_mn);
173           break date_loop;
174         }
175         idx_mn ++;
176         if (idx_mn > max[CRON_MN])
177           break hour_block;
178           }
179         }
180         idx_h ++;
181         idx_mn = 0;
182         if (idx_h > max[CRON_H])
183           break day_block;
184       }
185     }
186     calendar.add(Calendar.DAY_OF_MONTH, 1);
187     idx_h = 0;
188     if (calendar.get(Calendar.DAY_OF_MONTH) == 1)
189       break month_block;
190       }
191     }
192
193     // updates date variable so as to be able to add the minute
194
date = calendar.getTime();
195     return date;
196   }
197 }
198
Popular Tags