KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > cornerstone > services > scheduler > CronTimeTrigger


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.cornerstone.services.scheduler;
19
20 import java.util.Calendar JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.GregorianCalendar JavaDoc;
23
24 /**
25  * This is the holder triggers based on standard crontabs format.
26  *
27  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
28  */

29 public class CronTimeTrigger
30     implements TimeTrigger
31 {
32     protected final int m_minute;
33     protected final int m_hour;
34     protected final int m_dayOfMonth;
35     protected final int m_month;
36     protected final int m_dayOfWeek;
37     protected final int m_year;
38
39     /**
40      * Constructor for CronTimeTrigger.
41      * Day is either day of week or day of month depending on value of isDayOfWeek.
42      * if (isDayOfWeek == true) then valid values are 1-7 otherwise the values
43      * are 1-31
44      *
45      * @param minute the minute at which job is scheduled. (0-59)
46      * @param hour hour at which job is scheduled. (0-23 or -1 for every hour)
47      * @param month the month at which job is scheduled. (0-11 or -1 for every month)
48      * @param year the year when job is scheduled (-1 implies every year)
49      * @param day the day
50      * @param isDayOfWeek true if day is a day of week or false if day is day of month
51      */

52     public CronTimeTrigger( final int minute,
53                             final int hour,
54                             final int day,
55                             final int month,
56                             final int year,
57                             final boolean isDayOfWeek )
58     {
59         m_minute = minute;
60         m_hour = hour;
61         m_month = month;
62         m_year = year;
63
64         if( isDayOfWeek )
65         {
66             m_dayOfMonth = -1;
67             m_dayOfWeek = day;
68         }
69         else
70         {
71             m_dayOfMonth = day;
72             m_dayOfWeek = -1;
73         }
74     }
75
76     /**
77      * Returns the next time after the given <tt>moment</tt> when
78      * this trigger goes off.
79      *
80      * @param moment base point in milliseconds
81      * @return the time in milliseconds when this trigger goes off
82      */

83     public long getTimeAfter( final long moment )
84     {
85         //first create calendars
86
final Date JavaDoc timeMarker = new Date JavaDoc( moment );
87         final GregorianCalendar JavaDoc relativeTo = new GregorianCalendar JavaDoc();
88         relativeTo.setTime( timeMarker );
89         relativeTo.set( Calendar.SECOND, 0 );
90
91         final GregorianCalendar JavaDoc next = (GregorianCalendar JavaDoc)relativeTo.clone();
92
93         if( -1 != m_minute )
94             next.set( Calendar.MINUTE, m_minute );
95         else
96         {
97             if( -1 == m_hour && -1 == m_month && -1 == m_year )
98             {
99                 //roll minutes if all other values -1
100
next.add( Calendar.MINUTE, 1 );
101             }
102             else
103             {
104                 next.set( Calendar.MINUTE, 0 );
105             }
106         }
107
108         if( -1 != m_hour )
109         {
110             next.set( Calendar.HOUR_OF_DAY, m_hour );
111             if( -1 == m_minute ) next.set( Calendar.MINUTE, 0 );
112         }
113
114         if( -1 != m_month )
115         {
116             next.set( Calendar.MONTH, m_month );
117             if( -1 == m_hour ) next.set( Calendar.HOUR_OF_DAY, 0 );
118             if( -1 == m_minute ) next.set( Calendar.MINUTE, 0 );
119         }
120
121         if( -1 != m_year )
122         {
123             next.set( Calendar.YEAR, m_year );
124             if( -1 == m_month ) next.set( Calendar.MONTH, 0 );
125             if( -1 == m_hour ) next.set( Calendar.HOUR_OF_DAY, 0 );
126             if( -1 == m_minute ) next.set( Calendar.MINUTE, 0 );
127         }
128
129         //use zeroed constant to make if statements easier to read
130
final int minute = ( -1 != m_minute ) ? m_minute : 0;
131         final int rminute = relativeTo.get( Calendar.MINUTE );
132
133         if( -1 == m_year && -1 == m_month && -1 == m_hour &&
134             -1 != m_minute && rminute >= minute )
135         {
136             //for every hour jobs and job is done this hour
137
next.add( Calendar.HOUR_OF_DAY, 1 );
138         }
139
140         //use zeroed constant to make if statements easier to read
141
final int hour = ( -1 != m_hour ) ? m_hour : 0;
142         final int rhour = relativeTo.get( Calendar.HOUR_OF_DAY );
143
144         if( -1 == m_dayOfMonth && -1 == m_dayOfWeek &&
145             (
146             //for when past hour that was scheduled to run
147
( -1 != m_hour && rhour > hour ) ||
148
149             //for the case where you have to wrap over day
150
//when hour is not specified
151
( -1 == m_hour && rhour == 24 && rminute >= minute ) ||
152
153             //for when you are past time of day where both minute and
154
//hour are specified
155
( -1 != m_hour && rhour == hour && rminute >= minute )
156             )
157         )
158         {
159             //for jobs scheduled everyday and job is done this day
160
next.add( Calendar.DAY_OF_YEAR, 1 );
161         }
162
163         int realDayOfMonth = m_dayOfMonth;
164         {
165             //This block will update day of month if it is out of bounds
166
//For instance if you ask to schedule on 30th of everymonth
167
//this section will set the day to 28th (or 29th) in febuary
168
//as there is no 30th
169
final Calendar JavaDoc targetMonth = (GregorianCalendar JavaDoc)next.clone();
170             targetMonth.set( Calendar.DAY_OF_MONTH, 1 );
171             targetMonth.set( Calendar.MONTH, m_month );
172
173             final int maxDayCount = targetMonth.getActualMaximum( Calendar.DAY_OF_MONTH );
174             if( maxDayCount < realDayOfMonth )
175             {
176                 realDayOfMonth = maxDayCount;
177                 next.add( Calendar.MONTH, -1 );
178             }
179         }
180
181         final int month = ( -1 != m_month ) ? m_month : 0;
182         final int dayOfMonth = ( -1 != m_dayOfMonth ) ? m_dayOfMonth : 0;
183
184         //update the year if ran job for this year
185
if( -1 != m_month && -1 == m_year &&
186             ( relativeTo.get( Calendar.MONTH ) > month ||
187             ( relativeTo.get( Calendar.MONTH ) == month &&
188             ( relativeTo.get( Calendar.DAY_OF_MONTH ) > dayOfMonth ||
189             ( relativeTo.get( Calendar.DAY_OF_MONTH ) == dayOfMonth &&
190             ( relativeTo.get( Calendar.HOUR_OF_DAY ) > hour ||
191             ( relativeTo.get( Calendar.HOUR_OF_DAY ) == hour &&
192             ( relativeTo.get( Calendar.MINUTE ) >= minute ) ) ) ) ) ) ) )
193         {
194             next.add( Calendar.YEAR, 1 );
195         }
196
197         if( -1 != m_year )
198         {
199             //if past current year or already executed job this year then
200
//bail out
201
if( relativeTo.get( Calendar.YEAR ) > m_year ||
202                 ( relativeTo.get( Calendar.YEAR ) == m_year &&
203                 ( relativeTo.get( Calendar.MONTH ) > month ||
204                 ( relativeTo.get( Calendar.MONTH ) == month &&
205                 ( relativeTo.get( Calendar.DAY_OF_MONTH ) > dayOfMonth ||
206                 ( relativeTo.get( Calendar.DAY_OF_MONTH ) == dayOfMonth &&
207                 ( relativeTo.get( Calendar.HOUR_OF_DAY ) > hour ||
208                 ( relativeTo.get( Calendar.HOUR_OF_DAY ) == hour &&
209                 ( relativeTo.get( Calendar.MINUTE ) >= minute ) ) ) ) ) ) ) ) )
210             {
211                 return -1;
212             }
213         }
214
215         //schedule weekly jobs
216
if( -1 != m_dayOfWeek )
217         {
218             final int dayWait =
219                 ( 7 + m_dayOfWeek - relativeTo.get( Calendar.DAY_OF_WEEK ) ) % 7;
220
221             if( 0 != dayWait )
222             {
223                 next.add( Calendar.DAY_OF_YEAR, dayWait );
224             }
225             else if( relativeTo.get( Calendar.HOUR_OF_DAY ) > hour ||
226                 ( relativeTo.get( Calendar.HOUR_OF_DAY ) == hour &&
227                 relativeTo.get( Calendar.MINUTE ) >= minute ) )
228             {
229                 //if job scheduled for today has passed then schedule on next week
230
next.add( Calendar.DAY_OF_YEAR, 7 );
231             }
232         }
233         // Schedule monthly jobs
234
else if( -1 != m_dayOfMonth )
235         {
236             //System.out.println( "Setting to maxday: " + realDayOfMonth );
237
next.set( Calendar.DAY_OF_MONTH, realDayOfMonth );
238             //next.set( Calendar.DAY_OF_MONTH, m_dayOfMonth );
239

240             //if this months job has already run then schedule next week
241
if( m_month == -1 &&
242                 ( relativeTo.get( Calendar.DAY_OF_MONTH ) > m_dayOfMonth ||
243                 ( relativeTo.get( Calendar.DAY_OF_MONTH ) == m_dayOfMonth &&
244                 ( relativeTo.get( Calendar.HOUR_OF_DAY ) > hour ||
245                 ( relativeTo.get( Calendar.HOUR_OF_DAY ) == hour &&
246                 relativeTo.get( Calendar.MINUTE ) >= minute ) ) ) ) )
247             {
248                 next.roll( Calendar.MONTH, true );
249             }
250         }
251
252         //return time in millis
253
return next.getTime().getTime();
254     }
255
256     /**
257      * Reset the cron-trigger.
258      */

259     public void reset()
260     {
261         // nothing to reset for CronTimeTrigger
262
}
263
264     public String JavaDoc toString()
265     {
266         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
267         sb.append( "CronTimeTrigger[ " );
268
269         if( -1 != m_minute )
270         {
271             sb.append( "minute=" );
272             sb.append( m_minute );
273             sb.append( " " );
274         }
275
276         if( -1 != m_hour )
277         {
278             sb.append( "hour=" );
279             sb.append( m_hour );
280             sb.append( " " );
281         }
282
283         if( -1 != m_month )
284         {
285             sb.append( "month=" );
286             sb.append( m_month );
287             sb.append( " " );
288         }
289
290         if( -1 != m_year )
291         {
292             sb.append( "year=" );
293             sb.append( m_year );
294             sb.append( " " );
295         }
296
297         if( -1 != m_dayOfMonth )
298         {
299             sb.append( "dayOfMonth=" );
300             sb.append( m_dayOfMonth );
301             sb.append( " " );
302         }
303
304         if( -1 != m_dayOfWeek )
305         {
306             sb.append( "dayOfWeek=" );
307             sb.append( m_dayOfWeek );
308             sb.append( " " );
309         }
310
311         sb.append( "]" );
312
313         return sb.toString();
314     }
315 }
316
317
318
319
Popular Tags