KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quartz > UICronTrigger


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

18
19 /*
20  * Previously Copyright (c) 2001-2004 James House
21  */

22 package org.quartz;
23
24 import org.quartz.Job;
25 import org.quartz.JobExecutionContext;
26 import org.quartz.JobExecutionException;
27 import org.quartz.Scheduler;
28 import org.quartz.SimpleTrigger;
29 import org.quartz.Trigger;
30 import org.quartz.CronTrigger;
31
32 import java.util.Calendar JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.SortedSet JavaDoc;
39 import java.util.TimeZone JavaDoc;
40 import java.util.TreeSet JavaDoc;
41 import java.text.ParseException JavaDoc;
42
43 /**
44  * <p>
45  * A concrete <code>{@link Trigger}</code> that is used to fire a <code>{@link Job}</code>
46  * at given moments in time, defined with Unix 'cron-like' definitions.
47  * </p>
48  *
49  * <p>
50  * What you should know about this particular trigger is that it is based on
51  * org.quartz.CronTrigger, but the the functionality to build the sets from a
52  * string are unused. Whereas CronTrigger would essentially deserialize by
53  * rebuilding the TreeSets from the cronExpression, this class does not have a
54  * cronExpression, and de/serializes the TreeSets in their entirety. This is
55  * because the TreeSets map directly to the Struts user interface for set
56  * selection, and no effort is made to write an interpreter to map them back
57  * and forth between legacy UN*X cron expressions that CronTrigger uses.
58  * </p>
59  *
60  * <p>
61  * The method I use with this trigger is to instantiate it, then put it in the
62  * ActionForm of a Struts bean, then let Struts manipulate it directly through
63  * BeanUtils. You are by no means required to do that, but to fully understand
64  * the concepts here, at least until there is better documentation, you should
65  * understand how it works within that context first so you can write the
66  * appropriate code that Struts does for you for free. I'll try to explain that
67  * here.
68  * </p>
69  *
70  * <p>
71  * Struts JSP tags allow the user to use Apache BeanUtils to reference
72  * components of beans by path. This is to say that a bean <code>Foo</code>
73  * that has an accessor method <code>Bar getBar()</code> and given <code>
74  * Bar</code>
75  * has a primitive type <code>String</code> as a field named <code>splat</code>,
76  * one can set the field to <i>"new string value"</i> as follows:
77  * </p>
78  * <code>
79  * // create a new Foo with contained reference to a new Bar
80  * Foo fooBean = new Foo();
81  * fooBean.setBar(new Bar());
82  * // set the splat string in the Bar bean from Foo
83  * BeanUtils.setProperty(fooBean, "bar.splat", "new string value");
84  * </code>
85  * <p>
86  * In turn, Struts JSP tags use the bean addressing provided by BeanUtils to
87  * address accessor methods within the bean graph that is rooted with the
88  * ActionForm that is put into the Action context.
89  * </p>
90  * <p>
91  * Finally, having all this allows you to put direct selection lists on the
92  * screen of the UI, then map them directly into the UICronTrigger bean. Given
93  * a ActionForm bean that was set up to contain a <code>UICronTrigger</code>
94  * in a field called <code>trigger</code>, the following HTML code will
95  * completely create your UI in Struts:
96  * </p>
97  *
98  * <code>
99  * <tr class="listRowUnshaded">
100  * <td width="80">Date</td>
101  * <td align="right">
102  * <html:select property="trigger.daysOfWeek" size="5" multiple="true">
103  * <html:options property="trigger.daysOfWeekValues" labelProperty="trigger.daysOfWeekLabels"/>
104  * </html:select>
105  * <html:select property="trigger.daysOfMonth" size="5" multiple="true">
106  * <html:options property="trigger.daysOfMonthValues" labelProperty="trigger.daysOfMonthLabels"/>
107  * </html:select>
108  * <html:select property="trigger.months" size="5" multiple="true">
109  * <html:options property="trigger.monthsValues" labelProperty="trigger.monthsLabels"/>
110  * </html:select>
111  * <html:select property="trigger.years" size="5" multiple="true">
112  * <html:options property="trigger.yearsValues" labelProperty="trigger.yearsLabels"/>
113  * </html:select>
114  * </td>
115  * </tr>
116  * <tr class="listRowShaded">
117  * <td width="80">Time</td>
118  * <td colspan="2" align="right">
119  * <html:select property="trigger.hours" size="5" multiple="true">
120  * <html:options property="trigger.hoursValues" labelProperty="trigger.hoursLabels"/>
121  * </html:select>
122  * <html:select property="trigger.minutes" size="5" multiple="true">
123  * <html:options property="trigger.minutesValues" labelProperty="trigger.minutesLabels"/>
124  * </html:select>
125  * </td>
126  * </tr>
127  * </code>
128  * <p>
129  * So if you don't want to use Struts, what you have to do is take the
130  * information that was submitted on the form in the HTML select ranges,
131  * iterate each of them, and add the values to the appropriate sets in the
132  * fields of this class. Make sense?
133  * </p>
134  *
135  * Note that this is not as versatile as the standard CronTrigger. There are
136  * tricks with "last day of month" and repeating sets that need to be manually
137  * selected, and sets that can happen for date ranges much longer than we can
138  * reasonably map with direct selection in a UI.
139  *
140  * @see org.quartz.CronTrigger
141  * @see Trigger
142  * @see SimpleTrigger
143  *
144  * @author Brian Topping
145  * @author based on code by Sharada Jambula, James House, Mads Henderson
146  * @deprecated
147  */

148 public class UICronTrigger extends Trigger {
149
150     /*
151      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152      *
153      * Constants.
154      *
155      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156      */

157
158     /**
159      * <p>
160      * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire
161      * situation, the <code>{@link org.quartz.CronTrigger}</code> wants to be
162      * fired now by <code>Scheduler</code>.
163      * </p>
164      */

165     public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
166
167     /**
168      * <p>
169      * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire
170      * situation, the <code>{@link org.quartz.CronTrigger}</code> wants to
171      * have it's next-fire-time updated to the next time in the schedule after
172      * the current time, but it does not to be fired now.
173      * </p>
174      */

175     public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
176
177     /*
178      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179      *
180      * Data members.
181      *
182      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183      */

184     private static final int ALL_SPEC_INT = 99; // '*'
185

186     private static final int NO_SPEC_INT = 98; // '?'
187

188     private static final Integer JavaDoc ALL_SPEC = new Integer JavaDoc(ALL_SPEC_INT);
189
190     private static final Integer JavaDoc NO_SPEC = new Integer JavaDoc(NO_SPEC_INT);
191
192     private static Map JavaDoc monthMap = new HashMap JavaDoc(20);
193
194     private static Map JavaDoc dayMap = new HashMap JavaDoc(60);
195
196     static {
197         monthMap.put("JAN", new Integer JavaDoc(0));
198         monthMap.put("FEB", new Integer JavaDoc(1));
199         monthMap.put("MAR", new Integer JavaDoc(2));
200         monthMap.put("APR", new Integer JavaDoc(3));
201         monthMap.put("MAY", new Integer JavaDoc(4));
202         monthMap.put("JUN", new Integer JavaDoc(5));
203         monthMap.put("JUL", new Integer JavaDoc(6));
204         monthMap.put("AUG", new Integer JavaDoc(7));
205         monthMap.put("SEP", new Integer JavaDoc(8));
206         monthMap.put("OCT", new Integer JavaDoc(9));
207         monthMap.put("NOV", new Integer JavaDoc(10));
208         monthMap.put("DEC", new Integer JavaDoc(11));
209
210         dayMap.put("SUN", new Integer JavaDoc(1));
211         dayMap.put("MON", new Integer JavaDoc(2));
212         dayMap.put("TUE", new Integer JavaDoc(3));
213         dayMap.put("WED", new Integer JavaDoc(4));
214         dayMap.put("THU", new Integer JavaDoc(5));
215         dayMap.put("FRI", new Integer JavaDoc(6));
216         dayMap.put("SAT", new Integer JavaDoc(7));
217     }
218
219     private Date JavaDoc startTime = null;
220
221     private Date JavaDoc endTime = null;
222
223     private Date JavaDoc nextFireTime = null;
224
225     private TimeZone JavaDoc timeZone = null;
226
227     private Date JavaDoc previousFireTime = null;
228
229     private TreeSet JavaDoc seconds = null;
230
231     private TreeSet JavaDoc minutes = null;
232
233     private TreeSet JavaDoc hours = null;
234
235     private TreeSet JavaDoc daysOfMonth = null;
236
237     private TreeSet JavaDoc months = null;
238
239     private TreeSet JavaDoc daysOfWeek = null;
240
241     private TreeSet JavaDoc years = null;
242
243     private transient boolean lastdayOfWeek = false;
244
245     private transient int nthdayOfWeek = 0;
246
247     private transient boolean lastdayOfMonth = false;
248
249     private transient boolean calendardayOfWeek = false;
250
251     private transient boolean calendardayOfMonth = false;
252
253     /*
254      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
255      *
256      * Constructors.
257      *
258      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
259      */

260
261     public void reset() {
262         seconds = new TreeSet JavaDoc();
263         minutes = new TreeSet JavaDoc();
264         hours = new TreeSet JavaDoc();
265         daysOfMonth = new TreeSet JavaDoc();
266         months = new TreeSet JavaDoc();
267         daysOfWeek = new TreeSet JavaDoc();
268         years = new TreeSet JavaDoc();
269
270         // we always fire on the minute
271
seconds.add(new Integer JavaDoc(0));
272
273         minutes.add(ALL_SPEC);
274         for (int i = 0; i < 60; i++)
275             minutes.add(new Integer JavaDoc(i));
276
277         hours.add(ALL_SPEC);
278         for (int i = 0; i < 24; i++)
279             hours.add(new Integer JavaDoc(i));
280
281         daysOfMonth.add(ALL_SPEC);
282         for (int i = 1; i <= 31; i++)
283             daysOfMonth.add(new Integer JavaDoc(i));
284
285         months.add(ALL_SPEC);
286         for (int i = 1; i <= 12; i++)
287             months.add(new Integer JavaDoc(i));
288
289         daysOfWeek.add(NO_SPEC);
290
291         years.add(ALL_SPEC);
292         for (int i = 1970; i <= 2099; i++)
293             years.add(new Integer JavaDoc(i));
294
295         startTime = new Date JavaDoc();
296         setStartTime(startTime);
297         setTimeZone(TimeZone.getDefault());
298     }
299
300     /**
301      * <p>
302      * Create a <code>CronTrigger</code> with no settings.
303      * </p>
304      */

305     public UICronTrigger() {
306         super();
307         reset();
308     }
309
310     /**
311      * <p>
312      * Create a <code>CronTrigger</code> with the given name and group.
313      * </p>
314      */

315     public UICronTrigger(String JavaDoc name, String JavaDoc group) {
316         super(name, group);
317         reset();
318     }
319
320     /**
321      * <p>
322      * Create a <code>CronTrigger</code> with the given name and group, and
323      * associated with the identified <code>{@link Job}</code>.
324      * </p>
325      */

326     public UICronTrigger(String JavaDoc name, String JavaDoc group, String JavaDoc jobName,
327             String JavaDoc jobGroup) {
328         super(name, group, jobName, jobGroup);
329         reset();
330     }
331
332     /*
333      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
334      *
335      * Interface.
336      *
337      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
338      */

339
340     /**
341      * <p>
342      * Get the time at which the <code>CronTrigger</code> should occur.
343      * </p>
344      */

345     public Date JavaDoc getStartTime() {
346         return this.startTime;
347     }
348
349     public void setStartTime(Date JavaDoc startTime) {
350         if (startTime == null)
351                 throw new IllegalArgumentException JavaDoc("Start time cannot be null");
352
353         Date JavaDoc eTime = getEndTime();
354         if (eTime != null && startTime != null && eTime.before(startTime))
355             throw new IllegalArgumentException JavaDoc(
356             "End time cannot be before start time");
357
358         
359         // round off millisecond...
360
// Note timeZone is not needed here as parameter for
361
// Calendar.getInstance(), since time zone is implicit
362
// when using a Date in the setTime method.
363
Calendar cl = Calendar.getInstance();
364         cl.setTime(startTime);
365         cl.set(Calendar.MILLISECOND, 0);
366
367         this.startTime = cl.getTime();
368     }
369
370     /**
371      * <p>
372      * Get the time at which the <code>CronTrigger</code> should quit
373      * repeating - even if repeastCount isn't yet satisfied.
374      * </p>
375      *
376      * @see #getFinalFireTime()
377      */

378     public Date JavaDoc getEndTime() {
379         return this.endTime;
380     }
381
382     public void setEndTime(Date JavaDoc endTime) {
383         Date JavaDoc sTime = getStartTime();
384         if (sTime != null && endTime != null && sTime.after(endTime))
385                 throw new IllegalArgumentException JavaDoc(
386                         "End time cannot be before start time");
387
388         this.endTime = endTime;
389     }
390
391     /**
392      * <p>
393      * Returns the next time at which the <code>CronTrigger</code> will fire.
394      * If the trigger will not fire again, <code>null</code> will be
395      * returned. The value returned is not guaranteed to be valid until after
396      * the <code>Trigger</code> has been added to the scheduler.
397      * </p>
398      */

399     public Date JavaDoc getNextFireTime() {
400         return this.nextFireTime;
401     }
402
403     public void updateAfterMisfire(org.quartz.Calendar cal) {
404         int instr = getMisfireInstruction();
405
406         if (instr == MISFIRE_INSTRUCTION_SMART_POLICY)
407                 instr = MISFIRE_INSTRUCTION_DO_NOTHING;
408
409         if (instr == MISFIRE_INSTRUCTION_DO_NOTHING) {
410             Date JavaDoc newFireTime = getFireTimeAfter(new Date JavaDoc());
411             while (newFireTime != null && cal != null
412                     && !cal.isTimeIncluded(newFireTime.getTime())) {
413                 newFireTime = getFireTimeAfter(newFireTime);
414             }
415
416             setNextFireTime(newFireTime);
417
418         } else if (instr == MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) {
419             setNextFireTime(new Date JavaDoc());
420         }
421     }
422
423     public Date JavaDoc getPreviousFireTime() {
424         return this.previousFireTime;
425     }
426
427     /**
428      * <p>
429      * Set the previous time at which the <code>SimpleTrigger</code> fired.
430      * </p>
431      *
432      * <p>
433      * <b>This method should not be invoked by client code.</b>
434      * </p>
435      */

436     public void setPreviousFireTime(Date JavaDoc previousFireTime) {
437         this.previousFireTime = previousFireTime;
438     }
439
440     /**
441      * <p>
442      * Sets the next time at which the <code>CronTrigger</code> will fire. If
443      * the trigger will not fire again, <code>null</code> will be returned.
444      * </p>
445      */

446     public void setNextFireTime(Date JavaDoc nextFireTime) {
447         this.nextFireTime = nextFireTime;
448     }
449
450     /**
451      * <p>
452      * Returns the time zone for which the <code>cronExpression</code> of
453      * this <code>CronTrigger</code> will be resolved.
454      * </p>
455      */

456     public TimeZone JavaDoc getTimeZone() {
457         return this.timeZone;
458     }
459
460     /**
461      * <p>
462      * Sets the time zone for which the <code>cronExpression</code> of this
463      * <code>CronTrigger</code> will be resolved.
464      * </p>
465      */

466     public void setTimeZone(TimeZone JavaDoc timeZone) {
467         this.timeZone = timeZone;
468     }
469
470     /**
471      * <p>
472      * Returns the next time at which the <code>CronTrigger</code> will fire,
473      * after the given time. If the trigger will not fire after the given time,
474      * <code>null</code> will be returned.
475      * </p>
476      *
477      * <p>
478      * Note that the date returned is NOT validated against the related
479      * org.quartz.Calendar (if any)
480      * </p>
481      */

482     public Date JavaDoc getFireTimeAfter(Date JavaDoc afterTime) {
483         if (afterTime == null) afterTime = new Date JavaDoc();
484
485         if (startTime.after(afterTime))
486                 afterTime = new Date JavaDoc(startTime.getTime() - 1000l);
487
488         Date JavaDoc pot = getTimeAfter(afterTime);
489         if (endTime != null && pot != null && pot.after(endTime)) return null;
490
491         return pot;
492     }
493
494     /**
495      * <p>
496      * Returns the final time at which the <code>CronTrigger</code> will
497      * fire.
498      * </p>
499      *
500      * <p>
501      * Note that the return time *may* be in the past. and the date returned is
502      * not validated against org.quartz.calendar
503      * </p>
504      */

505     public Date JavaDoc getFinalFireTime() {
506         if (this.endTime != null) return getTimeBefore(this.endTime);
507         else
508             return null;
509     }
510
511     /**
512      * <p>
513      * Determines whether or not the <code>CronTrigger</code> will occur
514      * again.
515      * </p>
516      */

517     public boolean mayFireAgain() {
518         return (getNextFireTime() != null);
519     }
520
521     protected boolean validateMisfireInstruction(int misfireInstruction) {
522         if (misfireInstruction < MISFIRE_INSTRUCTION_SMART_POLICY)
523                 return false;
524
525         if (misfireInstruction > MISFIRE_INSTRUCTION_DO_NOTHING) return false;
526
527         return true;
528     }
529
530     /**
531      * <p>
532      * Updates the <code>CronTrigger</code>'s state based on the
533      * MISFIRE_INSTRUCTION_XXX that was selected when the <code>SimpleTrigger</code>
534      * was created.
535      * </p>
536      *
537      * <p>
538      * If the misfire instruction is set to MISFIRE_INSTRUCTION_SMART_POLICY,
539      * then the following scheme will be used: <br>
540      * <ul>
541      * <li>The instruction will be interpreted as <code>MISFIRE_INSTRUCTION_DO_NOTHING</code>
542      * </ul>
543      * </p>
544      */

545     public void updateAfterMisfire() {
546         int instr = getMisfireInstruction();
547
548         if (instr == MISFIRE_INSTRUCTION_SMART_POLICY)
549                 instr = MISFIRE_INSTRUCTION_DO_NOTHING;
550
551         if (instr == MISFIRE_INSTRUCTION_DO_NOTHING) {
552             setNextFireTime(getFireTimeAfter(new Date JavaDoc()));
553         } else if (instr == MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) {
554             setNextFireTime(new Date JavaDoc());
555         }
556     }
557
558     /**
559      * <p>
560      * Determines whether the date & time of the given java.util.Calendar
561      * instance falls on a scheduled fire-time of this trigger.
562      * </p>
563      *
564      * <p>
565      * Note that the date returned is NOT validated against the related
566      * org.quartz.Calendar (if any)
567      * </p>
568      */

569     public boolean willFireOn(Calendar test) {
570         Integer JavaDoc second = new Integer JavaDoc(test.get(Calendar.SECOND));
571         Integer JavaDoc minute = new Integer JavaDoc(test.get(Calendar.MINUTE));
572         Integer JavaDoc hour = new Integer JavaDoc(test.get(Calendar.HOUR_OF_DAY));
573         Integer JavaDoc day = new Integer JavaDoc(test.get(Calendar.DAY_OF_MONTH));
574         Integer JavaDoc month = new Integer JavaDoc(test.get(Calendar.MONTH));
575
576         if ((seconds.contains(second) || seconds.contains(ALL_SPEC))
577                 && (minutes.contains(minute) || minutes.contains(ALL_SPEC))
578                 && (hours.contains(hour) || hours.contains(ALL_SPEC))
579                 && (daysOfMonth.contains(day) || daysOfMonth.contains(ALL_SPEC))
580                 && (months.contains(month) || months.contains(ALL_SPEC))) {
581
582         return true; }
583
584         return false;
585     }
586
587     /**
588      * <p>
589      * Called after the <code>{@link Scheduler}</code> has executed the
590      * <code>{@link Job}</code> associated with the <code>Trigger</code> in
591      * order to get the final instruction code from the trigger.
592      * </p>
593      *
594      * @param context
595      * is the <code>JobExecutionContext</code> that was used by the
596      * <code>Job</code>'s<code>execute(xx)</code> method.
597      * @param result
598      * is the <code>JobExecutionException</code> thrown by the
599      * <code>Job</code>, if any (may be null).
600      * @return one of the Trigger.INSTRUCTION_XXX constants.
601      *
602      * @see #INSTRUCTION_NOOP
603      * @see #INSTRUCTION_RE_EXECUTE_JOB
604      * @see #INSTRUCTION_DELETE_TRIGGER
605      * @see #INSTRUCTION_SET_TRIGGER_COMPLETE
606      * @see #triggered(Calendar)
607      */

608     public int executionComplete(JobExecutionContext context,
609             JobExecutionException result) {
610         if (result != null && result.refireImmediately())
611                 return Trigger.INSTRUCTION_RE_EXECUTE_JOB;
612
613         if (result != null && result.refireImmediately())
614                 return INSTRUCTION_RE_EXECUTE_JOB;
615
616         if (result != null && result.unscheduleFiringTrigger())
617                 return INSTRUCTION_SET_TRIGGER_COMPLETE;
618
619         if (result != null && result.unscheduleAllTriggers())
620                 return INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE;
621
622         if (!mayFireAgain()) return INSTRUCTION_DELETE_TRIGGER;
623
624         return INSTRUCTION_NOOP;
625     }
626
627     /**
628      * <p>
629      * Called when the <code>{@link Scheduler}</code> has decided to 'fire'
630      * the trigger (execute the associated <code>Job</code>), in order to
631      * give the <code>Trigger</code> a chance to update itself for its next
632      * triggering (if any).
633      * </p>
634      *
635      * @see #executionComplete(JobExecutionContext, JobExecutionException)
636      */

637     public void triggered(org.quartz.Calendar calendar) {
638         previousFireTime = nextFireTime;
639         nextFireTime = getFireTimeAfter(nextFireTime);
640
641         while (nextFireTime != null && calendar != null
642                 && !calendar.isTimeIncluded(nextFireTime.getTime())) {
643             nextFireTime = getFireTimeAfter(nextFireTime);
644         }
645     }
646
647     /**
648      *
649      * @see org.quartz.Trigger#updateWithNewCalendar(org.quartz.Calendar, long)
650      */

651     public void updateWithNewCalendar(org.quartz.Calendar calendar, long misfireThreshold)
652     {
653         nextFireTime = getFireTimeAfter(previousFireTime);
654         
655         Date JavaDoc now = new Date JavaDoc();
656         do {
657             while (nextFireTime != null && calendar != null
658                     && !calendar.isTimeIncluded(nextFireTime.getTime())) {
659                 nextFireTime = getFireTimeAfter(nextFireTime);
660             }
661             
662             if(nextFireTime != null && nextFireTime.before(now)) {
663                 long diff = now.getTime() - nextFireTime.getTime();
664                 if(diff >= misfireThreshold) {
665                     nextFireTime = getFireTimeAfter(nextFireTime);
666                     continue;
667                 }
668             }
669         }while(false);
670     }
671
672     /**
673      * <p>
674      * Called by the scheduler at the time a <code>Trigger</code> is first
675      * added to the scheduler, in order to have the <code>Trigger</code>
676      * compute its first fire time, based on any associated calendar.
677      * </p>
678      *
679      * <p>
680      * After this method has been called, <code>getNextFireTime()</code>
681      * should return a valid answer.
682      * </p>
683      *
684      * @return the first time at which the <code>Trigger</code> will be fired
685      * by the scheduler, which is also the same value <code>getNextFireTime()</code>
686      * will return (until after the first firing of the <code>Trigger</code>).
687      * </p>
688      */

689     public Date JavaDoc computeFirstFireTime(org.quartz.Calendar calendar) {
690         nextFireTime = getFireTimeAfter(new Date JavaDoc(startTime.getTime() - 1000l));
691
692         while (nextFireTime != null && calendar != null
693                 && !calendar.isTimeIncluded(nextFireTime.getTime())) {
694             nextFireTime = getFireTimeAfter(nextFireTime);
695         }
696
697         return nextFireTime;
698     }
699
700     public String JavaDoc getExpressionSummary() {
701         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
702
703         buf.append("seconds: ");
704         buf.append(getExpressionSetSummary(seconds));
705         buf.append("\n");
706         buf.append("minutes: ");
707         buf.append(getExpressionSetSummary(minutes));
708         buf.append("\n");
709         buf.append("hours: ");
710         buf.append(getExpressionSetSummary(hours));
711         buf.append("\n");
712         buf.append("daysOfMonth: ");
713         buf.append(getExpressionSetSummary(daysOfMonth));
714         buf.append("\n");
715         buf.append("months: ");
716         buf.append(getExpressionSetSummary(months));
717         buf.append("\n");
718         buf.append("daysOfWeek: ");
719         buf.append(getExpressionSetSummary(daysOfWeek));
720         buf.append("\n");
721         buf.append("lastdayOfWeek: ");
722         buf.append(lastdayOfWeek);
723         buf.append("\n");
724         buf.append("lastdayOfMonth: ");
725         buf.append(lastdayOfMonth);
726         buf.append("\n");
727         buf.append("calendardayOfWeek: ");
728         buf.append(calendardayOfWeek);
729         buf.append("\n");
730         buf.append("calendardayOfMonth: ");
731         buf.append(calendardayOfMonth);
732         buf.append("\n");
733         buf.append("years: ");
734         buf.append(getExpressionSetSummary(years));
735         buf.append("\n");
736
737         return buf.toString();
738     }
739
740     private String JavaDoc getExpressionSetSummary(Set JavaDoc set) {
741
742         if (set.contains(NO_SPEC)) return "?";
743         if (set.contains(ALL_SPEC)) return "*";
744
745         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
746
747         Iterator JavaDoc itr = set.iterator();
748         boolean first = true;
749         while (itr.hasNext()) {
750             Integer JavaDoc iVal = (Integer JavaDoc) itr.next();
751             String JavaDoc val = iVal.toString();
752             if (!first) buf.append(",");
753             buf.append(val);
754             first = false;
755         }
756
757         return buf.toString();
758     }
759
760     ////////////////////////////////////////////////////////////////////////////
761
//
762
// Computation Functions
763
//
764
////////////////////////////////////////////////////////////////////////////
765

766     private Date JavaDoc getTimeAfter(Date JavaDoc afterTime) {
767         Calendar cl = Calendar.getInstance(timeZone);
768
769         // move ahead one second, since we're computing the time *after* the
770
// given time
771
afterTime = new Date JavaDoc(afterTime.getTime() + 1000);
772         // CronTrigger does not deal with milliseconds
773
cl.setTime(afterTime);
774         cl.set(Calendar.MILLISECOND, 0);
775
776         boolean gotOne = false;
777
778         // loop until we've computed the next time, or we've past the endTime
779
while (!gotOne) {
780
781             if (endTime != null && cl.getTime().after(endTime)) return null;
782
783             SortedSet JavaDoc st = null;
784             int t = 0;
785
786             int sec = cl.get(Calendar.SECOND);
787             int min = cl.get(Calendar.MINUTE);
788
789             // get second.................................................
790
st = seconds.tailSet(new Integer JavaDoc(sec));
791             if (st != null && st.size() != 0) {
792                 sec = ((Integer JavaDoc) st.first()).intValue();
793             } else {
794                 sec = ((Integer JavaDoc) seconds.first()).intValue();
795                 min++;
796                 cl.set(Calendar.MINUTE, min);
797             }
798             cl.set(Calendar.SECOND, sec);
799
800             min = cl.get(Calendar.MINUTE);
801             int hr = cl.get(Calendar.HOUR_OF_DAY);
802             t = -1;
803
804             // get minute.................................................
805
st = minutes.tailSet(new Integer JavaDoc(min));
806             if (st != null && st.size() != 0) {
807                 t = min;
808                 min = ((Integer JavaDoc) st.first()).intValue();
809             } else {
810                 min = ((Integer JavaDoc) minutes.first()).intValue();
811                 hr++;
812             }
813             if (min != t) {
814                 cl.set(Calendar.SECOND, 0);
815                 cl.set(Calendar.MINUTE, min);
816                 cl.set(Calendar.HOUR_OF_DAY, hr);
817                 continue;
818             }
819             cl.set(Calendar.MINUTE, min);
820
821             hr = cl.get(Calendar.HOUR_OF_DAY);
822             int day = cl.get(Calendar.DAY_OF_MONTH);
823             t = -1;
824
825             // get hour...................................................
826
st = hours.tailSet(new Integer JavaDoc(hr));
827             if (st != null && st.size() != 0) {
828                 t = hr;
829                 hr = ((Integer JavaDoc) st.first()).intValue();
830             } else {
831                 hr = ((Integer JavaDoc) hours.first()).intValue();
832                 day++;
833             }
834             if (hr != t) {
835                 cl.set(Calendar.SECOND, 0);
836                 cl.set(Calendar.MINUTE, 0);
837                 cl.set(Calendar.HOUR_OF_DAY, hr);
838                 cl.set(Calendar.DAY_OF_MONTH, day);
839                 continue;
840             }
841             cl.set(Calendar.HOUR_OF_DAY, hr);
842
843             day = cl.get(Calendar.DAY_OF_MONTH);
844             int mon = cl.get(Calendar.MONTH) + 1; // '+ 1' because calendar is
845
// 0-based for this field,
846
// and we are 1-based
847
t = -1;
848
849             // get day...................................................
850
boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC);
851             boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC);
852             if (dayOfMSpec && !dayOfWSpec) { // get day only by day of month
853
// rule
854
st = daysOfMonth.tailSet(new Integer JavaDoc(day));
855                 if (lastdayOfMonth) {
856                     t = day;
857                     day = getLastDayOfMonth(mon);
858                 } else if (st != null && st.size() != 0) {
859                     t = day;
860                     day = ((Integer JavaDoc) st.first()).intValue();
861                 } else {
862                     day = ((Integer JavaDoc) daysOfMonth.first()).intValue();
863                     mon++;
864                 }
865                 if (day != t) {
866                     cl.set(Calendar.SECOND, 0);
867                     cl.set(Calendar.MINUTE, 0);
868                     cl.set(Calendar.HOUR_OF_DAY, 0);
869                     cl.set(Calendar.DAY_OF_MONTH, day);
870                     cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar
871
// is 0-based for this
872
// field, and we are
873
// 1-based
874
continue;
875                 }
876             } else if (dayOfWSpec && !dayOfMSpec) { // get day only by day of
877
// week rule
878
if (lastdayOfWeek) { // are we looking for the last XXX day of
879
// the month?
880
int dow = ((Integer JavaDoc) daysOfWeek.first()).intValue(); // desired
881
// d-o-w
882
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
883
int daysToAdd = 0;
884                     if (cDow < dow) daysToAdd = dow - cDow;
885                     if (cDow > dow) daysToAdd = dow + (7 - cDow);
886
887                     int lDay = getLastDayOfMonth(mon);
888
889                     if (day + daysToAdd > lDay) { // did we already miss the
890
// last one?
891
cl.set(Calendar.SECOND, 0);
892                         cl.set(Calendar.MINUTE, 0);
893                         cl.set(Calendar.HOUR_OF_DAY, 0);
894                         cl.set(Calendar.DAY_OF_MONTH, 1);
895                         cl.set(Calendar.MONTH, mon); // no '- 1' here because
896
// we are promoting the
897
// month
898
continue;
899                     }
900
901                     // find date of last occurance of this day in this month...
902
while ((day + daysToAdd + 7) <= lDay)
903                         daysToAdd += 7;
904
905                     day += daysToAdd;
906                 } else if (nthdayOfWeek != 0) { // are we looking for the Nth
907
// XXX day in the month?
908
int dow = ((Integer JavaDoc) daysOfWeek.first()).intValue(); // desired
909
// d-o-w
910
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
911
int daysToAdd = 0;
912                     if (cDow < dow) daysToAdd = dow - cDow;
913                     else if (cDow > dow) daysToAdd = dow + (7 - cDow);
914
915                     day += daysToAdd;
916                     int weekOfMonth = day / 7;
917                     if (day % 7 > 0) weekOfMonth++;
918
919                     daysToAdd = (nthdayOfWeek - weekOfMonth) * 7;
920                     day += daysToAdd;
921                     if (daysToAdd < 0 || day > getLastDayOfMonth(mon)) {
922                         cl.set(Calendar.SECOND, 0);
923                         cl.set(Calendar.MINUTE, 0);
924                         cl.set(Calendar.HOUR_OF_DAY, 0);
925                         cl.set(Calendar.DAY_OF_MONTH, 1);
926                         cl.set(Calendar.MONTH, mon); // no '- 1' here because
927
// we are promoting the
928
// month
929
continue;
930                     }
931                 } else {
932                     int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
933
int dow = ((Integer JavaDoc) daysOfWeek.first()).intValue(); // desired
934
// d-o-w
935
st = daysOfWeek.tailSet(new Integer JavaDoc(cDow));
936                     if (st != null && st.size() > 0) {
937                         dow = ((Integer JavaDoc) st.first()).intValue();
938                     }
939
940                     int daysToAdd = 0;
941                     if (cDow < dow) daysToAdd = dow - cDow;
942                     if (cDow > dow) daysToAdd = dow + (7 - cDow);
943
944                     int lDay = getLastDayOfMonth(mon);
945
946                     if (day + daysToAdd > lDay) { // will we pass the end of
947
// the month?
948
cl.set(Calendar.SECOND, 0);
949                         cl.set(Calendar.MINUTE, 0);
950                         cl.set(Calendar.HOUR_OF_DAY, 0);
951                         cl.set(Calendar.DAY_OF_MONTH, 1);
952                         cl.set(Calendar.MONTH, mon); // no '- 1' here because
953
// we are promoting the
954
// month
955
continue;
956                     } else if (daysToAdd > 0) { // are we swithing days?
957
cl.set(Calendar.SECOND, 0);
958                         cl.set(Calendar.MINUTE, 0);
959                         cl.set(Calendar.HOUR_OF_DAY, 0);
960                         cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd);
961                         cl.set(Calendar.MONTH, mon - 1); // '- 1' because
962
// calendar is 0-based
963
// for this field, and
964
// we are 1-based
965
continue;
966                     }
967                 }
968             } else { // dayOfWSpec && !dayOfMSpec
969
throw new UnsupportedOperationException JavaDoc(
970                         "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented."); // TODO:
971
}
972             cl.set(Calendar.DAY_OF_MONTH, day);
973
974             mon = cl.get(Calendar.MONTH) + 1; // '+ 1' because calendar is
975
// 0-based for this field, and we
976
// are 1-based
977
int year = cl.get(Calendar.YEAR);
978             t = -1;
979
980             // get month...................................................
981
st = months.tailSet(new Integer JavaDoc(mon));
982             if (st != null && st.size() != 0) {
983                 t = mon;
984                 mon = ((Integer JavaDoc) st.first()).intValue();
985             } else {
986                 mon = ((Integer JavaDoc) months.first()).intValue();
987                 year++;
988             }
989             if (mon != t) {
990                 cl.set(Calendar.SECOND, 0);
991                 cl.set(Calendar.MINUTE, 0);
992                 cl.set(Calendar.HOUR_OF_DAY, 0);
993                 cl.set(Calendar.DAY_OF_MONTH, 1);
994                 cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is
995
// 0-based for this field, and
996
// we are 1-based
997
cl.set(Calendar.YEAR, year);
998                 continue;
999             }
1000            cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is
1001
// 0-based for this field, and we
1002
// are 1-based
1003

1004            year = cl.get(Calendar.YEAR);
1005            t = -1;
1006
1007            // get year...................................................
1008
st = years.tailSet(new Integer JavaDoc(year));
1009            if (st != null && st.size() != 0) {
1010                t = year;
1011                year = ((Integer JavaDoc) st.first()).intValue();
1012            } else
1013                return null; // ran out of years...
1014

1015            if (year != t) {
1016                cl.set(Calendar.SECOND, 0);
1017                cl.set(Calendar.MINUTE, 0);
1018                cl.set(Calendar.HOUR_OF_DAY, 0);
1019                cl.set(Calendar.DAY_OF_MONTH, 1);
1020                cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is
1021
// 0-based for this field, and
1022
// we are 1-based
1023
cl.set(Calendar.YEAR, year);
1024                continue;
1025            }
1026            cl.set(Calendar.YEAR, year);
1027
1028            gotOne = true;
1029        } // while( !done )
1030

1031        return cl.getTime();
1032    }
1033
1034    private Date JavaDoc getTimeBefore(Date JavaDoc endTime) // TODO: implement
1035
{
1036        return null;
1037    }
1038
1039    public boolean isLeapYear() {
1040        Calendar cl = Calendar.getInstance(timeZone);
1041        int year = cl.get(Calendar.YEAR);
1042
1043        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return true;
1044        else
1045            return false;
1046    }
1047
1048    public int getLastDayOfMonth(int monthNum) {
1049
1050        switch (monthNum) {
1051        case 1:
1052            return 31;
1053        case 2:
1054            return (isLeapYear()) ? 29 : 28;
1055        case 3:
1056            return 31;
1057        case 4:
1058            return 30;
1059        case 5:
1060            return 31;
1061        case 6:
1062            return 30;
1063        case 7:
1064            return 31;
1065        case 8:
1066            return 31;
1067        case 9:
1068            return 30;
1069        case 10:
1070            return 31;
1071        case 11:
1072            return 30;
1073        case 12:
1074            return 31;
1075        default:
1076            throw new IllegalArgumentException JavaDoc("Illegal month number: "
1077                    + monthNum);
1078        }
1079    }
1080
1081    public Integer JavaDoc[] getSecondsValues() {
1082        Integer JavaDoc list[] = new Integer JavaDoc[60];
1083        for (int i = 0; i < 60; i++) {
1084            list[i] = new Integer JavaDoc(i);
1085        }
1086
1087        return list;
1088    }
1089
1090    public Integer JavaDoc[] getSecondsLabels() {
1091        return getSecondsValues();
1092    }
1093
1094    public Integer JavaDoc[] getSeconds() {
1095        Integer JavaDoc list[] = new Integer JavaDoc[seconds.size()];
1096        if (seconds != null) {
1097            int i = 0;
1098            for (Iterator JavaDoc it = seconds.iterator(); it.hasNext(); i++) {
1099                list[i] = (Integer JavaDoc) it.next();
1100            }
1101        }
1102        return list;
1103    }
1104
1105    public void setSeconds(Integer JavaDoc[] val) {
1106        if (seconds != null) seconds.clear();
1107        else
1108            seconds = new TreeSet JavaDoc();
1109
1110        for (int i = 0; i < val.length; i++) {
1111            seconds.add(val[i]);
1112        }
1113    }
1114
1115    public Integer JavaDoc[] getMinutesValues() {
1116        Integer JavaDoc list[] = new Integer JavaDoc[60];
1117        for (int i = 0; i < 60; i++) {
1118            list[i] = new Integer JavaDoc(i);
1119        }
1120
1121        return list;
1122    }
1123
1124    public Integer JavaDoc[] getMinutesLabels() {
1125        return getMinutesValues();
1126    }
1127
1128    public Integer JavaDoc[] getMinutes() {
1129        Integer JavaDoc list[] = new Integer JavaDoc[minutes.size()];
1130        if (minutes != null) {
1131            int i = 0;
1132            for (Iterator JavaDoc it = minutes.iterator(); it.hasNext(); i++) {
1133                list[i] = (Integer JavaDoc) it.next();
1134            }
1135        }
1136        return list;
1137    }
1138
1139    public void setMinutes(Integer JavaDoc[] val) {
1140        if (minutes != null) minutes.clear();
1141        else
1142            minutes = new TreeSet JavaDoc();
1143
1144        for (int i = 0; i < val.length; i++) {
1145            minutes.add(val[i]);
1146        }
1147    }
1148
1149    public Integer JavaDoc[] getHoursValues() {
1150        Integer JavaDoc list[] = new Integer JavaDoc[24];
1151        for (int i = 0; i < 24; i++) {
1152            list[i] = new Integer JavaDoc(i);
1153        }
1154
1155        return list;
1156    }
1157
1158    public String JavaDoc[] getHoursLabels() {
1159        String JavaDoc vals[] = {"12AM (Midnight)", "1AM", "2AM", "3AM", "4AM", "5AM",
1160                "6AM", "7AM", "8AM", "9AM", "10AM", "11AM", "12PM (Noon)",
1161                "1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM",
1162                "10PM", "11PM"};
1163        return vals;
1164    }
1165
1166    public Integer JavaDoc[] getHours() {
1167        Integer JavaDoc list[] = new Integer JavaDoc[hours.size()];
1168        if (hours != null) {
1169            int i = 0;
1170            for (Iterator JavaDoc it = hours.iterator(); it.hasNext(); i++) {
1171                list[i] = (Integer JavaDoc) it.next();
1172            }
1173        }
1174        return list;
1175    }
1176
1177    public void setHours(Integer JavaDoc[] val) {
1178        if (hours != null) hours.clear();
1179        else
1180            hours = new TreeSet JavaDoc();
1181
1182        for (int i = 0; i < val.length; i++) {
1183            hours.add(val[i]);
1184        }
1185    }
1186
1187    public Integer JavaDoc[] getDaysOfMonthValues() {
1188        Integer JavaDoc list[] = new Integer JavaDoc[31];
1189        for (int i = 0; i < 31; i++) {
1190            list[i] = new Integer JavaDoc(i + 1);
1191        }
1192
1193        return list;
1194    }
1195
1196    public Integer JavaDoc[] getDaysOfMonthLabels() {
1197        return getDaysOfMonthValues();
1198    }
1199
1200    public Integer JavaDoc[] getDaysOfMonth() {
1201        Integer JavaDoc list[] = new Integer JavaDoc[daysOfMonth.size()];
1202        if (daysOfMonth != null) {
1203            int i = 0;
1204            for (Iterator JavaDoc it = daysOfMonth.iterator(); it.hasNext(); i++) {
1205                list[i] = (Integer JavaDoc) it.next();
1206            }
1207        }
1208        return list;
1209    }
1210
1211    public void setDaysOfMonth(Integer JavaDoc[] val) {
1212        if (daysOfMonth != null) daysOfMonth.clear();
1213        else
1214            daysOfMonth = new TreeSet JavaDoc();
1215
1216        for (int i = 0; i < val.length; i++) {
1217            daysOfMonth.add(val[i]);
1218        }
1219        daysOfWeek.clear();
1220        daysOfWeek.add(NO_SPEC);
1221    }
1222
1223    public Integer JavaDoc[] getMonthsValues() {
1224        Integer JavaDoc list[] = new Integer JavaDoc[12];
1225        for (int i = 0; i < 12; i++) {
1226            list[i] = new Integer JavaDoc(i + 1);
1227        }
1228
1229        return list;
1230    }
1231
1232    public String JavaDoc[] getMonthsLabels() {
1233        String JavaDoc vals[] = {"January", "February", "March", "April", "May",
1234                "June", "July", "August", "September", "October", "November",
1235                "December"};
1236        return vals;
1237    }
1238
1239    public Integer JavaDoc[] getMonths() {
1240        Integer JavaDoc list[] = new Integer JavaDoc[months.size()];
1241        if (months != null) {
1242            int i = 0;
1243            for (Iterator JavaDoc it = months.iterator(); it.hasNext(); i++) {
1244                list[i] = (Integer JavaDoc) it.next();
1245            }
1246        }
1247        return list;
1248    }
1249
1250    public void setMonths(Integer JavaDoc[] val) {
1251        if (months != null) months.clear();
1252        else
1253            months = new TreeSet JavaDoc();
1254
1255        for (int i = 0; i < val.length; i++) {
1256            months.add(val[i]);
1257        }
1258    }
1259
1260    public String JavaDoc[] getDaysOfWeekLabels() {
1261        String JavaDoc list[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
1262                "Thursday", "Friday", "Saturday"};
1263        return list;
1264    }
1265
1266    public Integer JavaDoc[] getDaysOfWeekValues() {
1267        Integer JavaDoc list[] = new Integer JavaDoc[7];
1268        for (int i = 0; i < 7; i++)
1269            list[i] = new Integer JavaDoc(i + 1);
1270        return list;
1271    }
1272
1273    public Integer JavaDoc[] getDaysOfWeek() {
1274        Integer JavaDoc list[] = new Integer JavaDoc[daysOfWeek.size()];
1275        if (daysOfWeek != null) {
1276            int i = 0;
1277            for (Iterator JavaDoc it = daysOfWeek.iterator(); it.hasNext(); i++) {
1278                list[i] = (Integer JavaDoc) it.next();
1279            }
1280        }
1281        return list;
1282    }
1283
1284    public void setDaysOfWeek(Integer JavaDoc[] val) {
1285        if (daysOfWeek != null) daysOfWeek.clear();
1286        else
1287            daysOfWeek = new TreeSet JavaDoc();
1288
1289        for (int i = 0; i < val.length; i++) {
1290            daysOfWeek.add(val[i]);
1291        }
1292
1293        daysOfMonth.clear();
1294        daysOfMonth.add(NO_SPEC);
1295    }
1296
1297    public Integer JavaDoc[] getYearsValues() {
1298        Integer JavaDoc list[] = new Integer JavaDoc[20];
1299        Calendar now = Calendar.getInstance();
1300        int year = now.get(Calendar.YEAR);
1301        for (int i = 0; i < 20; i++) {
1302            list[i] = new Integer JavaDoc(i + year);
1303        }
1304
1305        return list;
1306    }
1307
1308    public Integer JavaDoc[] getYearsLabels() {
1309        return getYearsValues();
1310    }
1311
1312    public Integer JavaDoc[] getYears() {
1313        Integer JavaDoc list[] = new Integer JavaDoc[years.size()];
1314        if (years != null) {
1315            int i = 0;
1316            for (Iterator JavaDoc it = years.iterator(); it.hasNext(); i++) {
1317                list[i] = (Integer JavaDoc) it.next();
1318            }
1319        }
1320        return list;
1321    }
1322
1323    public void setYears(Integer JavaDoc[] val) {
1324        if (years != null) years.clear();
1325        else
1326            years = new TreeSet JavaDoc();
1327
1328        for (int i = 0; i < val.length; i++) {
1329            years.add(val[i]);
1330        }
1331    }
1332
1333    public static void main(String JavaDoc[] argv) {
1334        CronTrigger ct = new CronTrigger("a", "a");
1335        try {
1336            ct.setCronExpression("0 * * * * ? *");
1337        } catch (ParseException JavaDoc e) {
1338            // log.error("caught an exception", e);
1339
}
1340        ct.setStartTime(new Date JavaDoc());
1341        ct.setTimeZone(TimeZone.getDefault());
1342        System.out.println(ct.getExpressionSummary());
1343        ct.computeFirstFireTime(null);
1344
1345        UICronTrigger uict = new UICronTrigger("a", "a");
1346        Integer JavaDoc set[] = new Integer JavaDoc[1];
1347        set[0] = new Integer JavaDoc(1);
1348        uict.setSeconds(set);
1349        System.out.println(ct.getExpressionSummary());
1350        uict.computeFirstFireTime(null);
1351
1352    }
1353}
1354
Popular Tags