KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > config > types > CronType


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.config.types;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.util.L10N;
33 import com.caucho.util.QDate;
34
35 import java.util.regex.Pattern JavaDoc;
36
37 /**
38  * Class-loading TypeBuilder
39  */

40 public class CronType {
41   static L10N L = new L10N(CronType.class);
42
43   private static final long DAY = 24L * 3600L * 1000L;
44
45   private final QDate _localCalendar = QDate.createLocal();
46   
47   private boolean []_minutes;
48   private boolean []_hours;
49   private boolean []_days;
50   private boolean []_months;
51   private boolean []_daysOfWeek;
52
53   public CronType()
54   {
55   }
56   
57   /**
58    * Sets the text.
59    */

60   public void addText(String JavaDoc text)
61     throws ConfigException
62   {
63     text = text.trim();
64     
65     String JavaDoc []split = Pattern.compile("\\s+").split(text);
66
67     if (split.length > 0)
68       _minutes = parseRange(split[0], 0, 59);
69     
70     if (split.length > 1)
71       _hours = parseRange(split[1], 0, 23);
72     else
73       _hours = parseRange("*", 0, 23);
74     
75     if (split.length > 2)
76       _days = parseRange(split[2], 1, 31);
77     
78     if (split.length > 3)
79       _months = parseRange(split[3], 1, 12);
80     
81     if (split.length > 4)
82       _daysOfWeek = parseRange(split[4], 0, 7);
83   }
84
85   /**
86    * parses a range, following cron rules.
87    */

88   private boolean []parseRange(String JavaDoc range, int rangeMin, int rangeMax)
89     throws ConfigException
90   {
91     boolean []values = new boolean[rangeMax + 1];
92     
93     int j = 0;
94     while (j < range.length()) {
95       char ch = range.charAt(j);
96
97       int min = 0;
98       int max = 0;
99       int step = 1;
100       
101       if (ch == '*') {
102     min = rangeMin;
103     max = rangeMax;
104     j++;
105       }
106       else if ('0' <= ch && ch <= '9') {
107     for (;
108          j < range.length() && '0' <= (ch = range.charAt(j)) && ch <= '9';
109          j++) {
110       min = 10 * min + ch - '0';
111     }
112
113     if (j < range.length() && ch == '-') {
114       for (j++;
115            j < range.length() && '0' <= (ch = range.charAt(j)) && ch <= '9';
116            j++) {
117         max = 10 * max + ch - '0';
118       }
119     }
120     else
121       max = min;
122       }
123       else
124     throw new ConfigException(L.l("`{0}' is an illegal cron range",
125                       range));
126
127       if (min < rangeMin)
128     throw new ConfigException(L.l("`{0}' is an illegal cron range (min value is too small)",
129                       range));
130       else if (rangeMax < max)
131     throw new ConfigException(L.l("`{0}' is an illegal cron range (max value is too large)",
132                       range));
133
134       if (j < range.length() && (ch = range.charAt(j)) == '/') {
135     step = 0;
136     
137     for (j++;
138          j < range.length() && '0' <= (ch = range.charAt(j)) && ch <= '9';
139          j++) {
140       step = 10 * step + ch - '0';
141     }
142
143     if (step == 0)
144       throw new ConfigException(L.l("`{0}' is an illegal cron range",
145                     range));
146       }
147
148       if (range.length() <= j) {
149       }
150       else if (ch == ',')
151     j++;
152       else {
153     throw new ConfigException(L.l("`{0}' is an illegal cron range",
154                       range));
155       }
156
157       for (; min <= max; min += step)
158     values[min] = true;
159     }
160
161     return values;
162   }
163
164   public long nextTime(long now)
165   {
166     QDate cal = _localCalendar;
167
168     long time = now + 60000 - now % 60000;
169     
170     synchronized (cal) {
171       cal.setGMTTime(time);
172
173       int minute = nextInterval(_minutes, cal.getMinute());
174
175       if (minute < 0) {
176     minute = nextInterval(_minutes, 0);
177     
178     cal.setHour(cal.getHour() + 1);
179       }
180
181       int hour = nextInterval(_hours, cal.getHour());
182       if (hour < 0) {
183     hour = nextInterval(_hours, 0);
184     minute = nextInterval(_minutes, 0);
185     
186     cal.setDayOfMonth(cal.getDayOfMonth() + 1);
187       }
188
189       int day = cal.getDayOfMonth();
190
191       if (_days != null) {
192     day = nextInterval(_days, cal.getDayOfMonth());
193
194     if (day < 0) {
195       cal.setMonth(cal.getMonth() + 1);
196       cal.setDayOfMonth(1);
197
198       day = nextInterval(_days, cal.getDayOfMonth());
199       hour = nextInterval(_hours, 0);
200       minute = nextInterval(_minutes, 0);
201     }
202       }
203
204       if (_daysOfWeek != null) {
205     int oldDayOfWeek = cal.getDayOfWeek();
206     int dayOfWeek = nextInterval(_daysOfWeek, oldDayOfWeek);
207
208     if (dayOfWeek > 0) {
209       day += (dayOfWeek - oldDayOfWeek);
210     }
211     else {
212       dayOfWeek = nextInterval(_daysOfWeek, 0);
213       
214       day += (dayOfWeek - oldDayOfWeek + 7);
215     }
216       }
217
218       int month = cal.getMonth();
219       int year = (int) cal.getYear();
220       
221       long nextTime = nextTime(year, month, day, hour, minute);
222
223       if (now < nextTime)
224     return nextTime;
225       else
226     return nextTime(now + 3600000L); // DST
227
}
228   }
229
230   private long nextTime(int year, int month, int day, int hour, int minute)
231   {
232     QDate cal = _localCalendar;
233     
234     cal.setLocalTime(0);
235
236     cal.setYear(year);
237     cal.setMonth(month);
238     cal.setDayOfMonth(day);
239     cal.setHour(hour);
240     cal.setMinute(minute);
241
242     return cal.getGMTTime();
243   }
244     
245   public int nextInterval(boolean []values, int now)
246   {
247     for (; now < values.length; now++) {
248       if (values[now])
249     return now;
250     }
251
252     return -1;
253   }
254 }
255
Popular Tags