Save This Page
Home » quartz-1.6.0 » org » quartz » [javadoc | source]
    1   /*
    2    * UICronTrigger.java
    3    * 
    4    * Based on work in Quartz: Copyright James House (c) 2001-2004
    5    * 
    6    * All rights reserved.
    7    * 
    8    * Redistribution and use in source and binary forms, with or without
    9    * modification, are permitted provided that the following conditions are met: 1.
   10    * Redistributions of source code must retain the above copyright notice, this
   11    * list of conditions and the following disclaimer. 2. Redistributions in
   12    * binary form must reproduce the above copyright notice, this list of
   13    * conditions and the following disclaimer in the documentation and/or other
   14    * materials provided with the distribution.
   15    * 
   16    * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
   17    * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   18    * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   19    * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
   20    * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   21    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   22    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   23    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26    *  
   27    */
   28   package org.quartz;
   29   
   30   import org.quartz.Job;
   31   import org.quartz.JobExecutionContext;
   32   import org.quartz.JobExecutionException;
   33   import org.quartz.Scheduler;
   34   import org.quartz.SimpleTrigger;
   35   import org.quartz.Trigger;
   36   import org.quartz.CronTrigger;
   37   
   38   import java.util.Calendar;
   39   import java.util.Date;
   40   import java.util.HashMap;
   41   import java.util.Iterator;
   42   import java.util.Map;
   43   import java.util.Set;
   44   import java.util.SortedSet;
   45   import java.util.TimeZone;
   46   import java.util.TreeSet;
   47   import java.text.ParseException;
   48   
   49   /**
   50    * <p>
   51    * A concrete <code>{@link Trigger}</code> that is used to fire a <code>{@link Job}</code>
   52    * at given moments in time, defined with Unix 'cron-like' definitions.
   53    * </p>
   54    * 
   55    * <p>
   56    * What you should know about this particular trigger is that it is based on
   57    * org.quartz.CronTrigger, but the the functionality to build the sets from a
   58    * string are unused. Whereas CronTrigger would essentially deserialize by
   59    * rebuilding the TreeSets from the cronExpression, this class does not have a
   60    * cronExpression, and de/serializes the TreeSets in their entirety. This is
   61    * because the TreeSets map directly to the Struts user interface for set
   62    * selection, and no effort is made to write an interpreter to map them back
   63    * and forth between legacy UN*X cron expressions that CronTrigger uses.
   64    * </p>
   65    * 
   66    * <p>
   67    * The method I use with this trigger is to instantiate it, then put it in the
   68    * ActionForm of a Struts bean, then let Struts manipulate it directly through
   69    * BeanUtils. You are by no means required to do that, but to fully understand
   70    * the concepts here, at least until there is better documentation, you should
   71    * understand how it works within that context first so you can write the
   72    * appropriate code that Struts does for you for free. I'll try to explain that
   73    * here.
   74    * </p>
   75    * 
   76    * <p>
   77    * Struts JSP tags allow the user to use Apache BeanUtils to reference
   78    * components of beans by path. This is to say that a bean <code>Foo</code>
   79    * that has an accessor method <code>Bar getBar()</code> and given <code>
   80    * Bar</code>
   81    * has a primitive type <code>String</code> as a field named <code>splat</code>,
   82    * one can set the field to <i>"new string value"</i> as follows:
   83    * </p>
   84    * <code>
   85    * // create a new Foo with contained reference to a new Bar
   86    * Foo fooBean = new Foo();
   87    * fooBean.setBar(new Bar());
   88    * // set the splat string in the Bar bean from Foo
   89    * BeanUtils.setProperty(fooBean, "bar.splat", "new string value");
   90    * </code>
   91    * <p>
   92    * In turn, Struts JSP tags use the bean addressing provided by BeanUtils to
   93    * address accessor methods within the bean graph that is rooted with the
   94    * ActionForm that is put into the Action context.
   95    * </p>
   96    * <p>
   97    * Finally, having all this allows you to put direct selection lists on the
   98    * screen of the UI, then map them directly into the UICronTrigger bean. Given
   99    * a ActionForm bean that was set up to contain a <code>UICronTrigger</code>
  100    * in a field called <code>trigger</code>, the following HTML code will
  101    * completely create your UI in Struts:
  102    * </p>
  103    * 
  104    * <code>
  105    *               <tr class="listRowUnshaded">
  106    *   <td width="80">Date</td>
  107    *   <td align="right">
  108    *   <html:select property="trigger.daysOfWeek" size="5" multiple="true">
  109    *   <html:options property="trigger.daysOfWeekValues" labelProperty="trigger.daysOfWeekLabels"/>
  110    *   </html:select>
  111    *   <html:select property="trigger.daysOfMonth" size="5" multiple="true">
  112    *   <html:options property="trigger.daysOfMonthValues" labelProperty="trigger.daysOfMonthLabels"/>
  113    *   </html:select>
  114    *   <html:select property="trigger.months" size="5" multiple="true">
  115    *   <html:options property="trigger.monthsValues" labelProperty="trigger.monthsLabels"/>
  116    *   </html:select>
  117    *   <html:select property="trigger.years" size="5" multiple="true">
  118    *   <html:options property="trigger.yearsValues" labelProperty="trigger.yearsLabels"/>
  119    *   </html:select>
  120    *   </td>
  121    *   </tr>
  122    *   <tr class="listRowShaded">
  123    *   <td width="80">Time</td>
  124    *   <td colspan="2" align="right">
  125    *   <html:select property="trigger.hours" size="5" multiple="true">
  126    *   <html:options property="trigger.hoursValues" labelProperty="trigger.hoursLabels"/>
  127    *   </html:select>
  128    *   <html:select property="trigger.minutes" size="5" multiple="true">
  129    *   <html:options property="trigger.minutesValues" labelProperty="trigger.minutesLabels"/>
  130    *   </html:select>
  131    *   </td>
  132    *   </tr>
  133    *   </code>
  134    * <p>
  135    * So if you don't want to use Struts, what you have to do is take the
  136    * information that was submitted on the form in the HTML select ranges,
  137    * iterate each of them, and add the values to the appropriate sets in the
  138    * fields of this class. Make sense?
  139    * </p>
  140    * 
  141    * Note that this is not as versatile as the standard CronTrigger. There are
  142    * tricks with "last day of month" and repeating sets that need to be manually
  143    * selected, and sets that can happen for date ranges much longer than we can
  144    * reasonably map with direct selection in a UI.
  145    * 
  146    * @see org.quartz.CronTrigger
  147    * @see Trigger
  148    * @see SimpleTrigger
  149    * 
  150    * @author Brian Topping
  151    * @author based on code by Sharada Jambula, James House, Mads Henderson
  152    */
  153   public class UICronTrigger extends Trigger {
  154   
  155       /*
  156        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  157        * 
  158        * Constants.
  159        * 
  160        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  161        */
  162   
  163       /**
  164        * <p>
  165        * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire
  166        * situation, the <code>{@link org.quartz.CronTrigger}</code> wants to be
  167        * fired now by <code>Scheduler</code>.
  168        * </p>
  169        */
  170       public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
  171   
  172       /**
  173        * <p>
  174        * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire
  175        * situation, the <code>{@link org.quartz.CronTrigger}</code> wants to
  176        * have it's next-fire-time updated to the next time in the schedule after
  177        * the current time, but it does not to be fired now.
  178        * </p>
  179        */
  180       public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
  181   
  182       /*
  183        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  184        * 
  185        * Data members.
  186        * 
  187        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  188        */
  189       private static final int ALL_SPEC_INT = 99; // '*'
  190   
  191       private static final int NO_SPEC_INT = 98; // '?'
  192   
  193       private static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT);
  194   
  195       private static final Integer NO_SPEC = new Integer(NO_SPEC_INT);
  196   
  197       private static Map monthMap = new HashMap(20);
  198   
  199       private static Map dayMap = new HashMap(60);
  200   
  201       static {
  202           monthMap.put("JAN", new Integer(0));
  203           monthMap.put("FEB", new Integer(1));
  204           monthMap.put("MAR", new Integer(2));
  205           monthMap.put("APR", new Integer(3));
  206           monthMap.put("MAY", new Integer(4));
  207           monthMap.put("JUN", new Integer(5));
  208           monthMap.put("JUL", new Integer(6));
  209           monthMap.put("AUG", new Integer(7));
  210           monthMap.put("SEP", new Integer(8));
  211           monthMap.put("OCT", new Integer(9));
  212           monthMap.put("NOV", new Integer(10));
  213           monthMap.put("DEC", new Integer(11));
  214   
  215           dayMap.put("SUN", new Integer(1));
  216           dayMap.put("MON", new Integer(2));
  217           dayMap.put("TUE", new Integer(3));
  218           dayMap.put("WED", new Integer(4));
  219           dayMap.put("THU", new Integer(5));
  220           dayMap.put("FRI", new Integer(6));
  221           dayMap.put("SAT", new Integer(7));
  222       }
  223   
  224       private Date startTime = null;
  225   
  226       private Date endTime = null;
  227   
  228       private Date nextFireTime = null;
  229   
  230       private TimeZone timeZone = null;
  231   
  232       private Date previousFireTime = null;
  233   
  234       private TreeSet seconds = null;
  235   
  236       private TreeSet minutes = null;
  237   
  238       private TreeSet hours = null;
  239   
  240       private TreeSet daysOfMonth = null;
  241   
  242       private TreeSet months = null;
  243   
  244       private TreeSet daysOfWeek = null;
  245   
  246       private TreeSet years = null;
  247   
  248       private transient boolean lastdayOfWeek = false;
  249   
  250       private transient int nthdayOfWeek = 0;
  251   
  252       private transient boolean lastdayOfMonth = false;
  253   
  254       private transient boolean calendardayOfWeek = false;
  255   
  256       private transient boolean calendardayOfMonth = false;
  257   
  258       /*
  259        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  260        * 
  261        * Constructors.
  262        * 
  263        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  264        */
  265   
  266       public void reset() {
  267           seconds = new TreeSet();
  268           minutes = new TreeSet();
  269           hours = new TreeSet();
  270           daysOfMonth = new TreeSet();
  271           months = new TreeSet();
  272           daysOfWeek = new TreeSet();
  273           years = new TreeSet();
  274   
  275           // we always fire on the minute
  276           seconds.add(new Integer(0));
  277   
  278           minutes.add(ALL_SPEC);
  279           for (int i = 0; i < 60; i++)
  280               minutes.add(new Integer(i));
  281   
  282           hours.add(ALL_SPEC);
  283           for (int i = 0; i < 24; i++)
  284               hours.add(new Integer(i));
  285   
  286           daysOfMonth.add(ALL_SPEC);
  287           for (int i = 1; i <= 31; i++)
  288               daysOfMonth.add(new Integer(i));
  289   
  290           months.add(ALL_SPEC);
  291           for (int i = 1; i <= 12; i++)
  292               months.add(new Integer(i));
  293   
  294           daysOfWeek.add(NO_SPEC);
  295   
  296           years.add(ALL_SPEC);
  297           for (int i = 1970; i <= 2099; i++)
  298               years.add(new Integer(i));
  299   
  300           startTime = new Date();
  301           setStartTime(startTime);
  302           setTimeZone(TimeZone.getDefault());
  303       }
  304   
  305       /**
  306        * <p>
  307        * Create a <code>CronTrigger</code> with no settings.
  308        * </p>
  309        */
  310       public UICronTrigger() {
  311           super();
  312           reset();
  313       }
  314   
  315       /**
  316        * <p>
  317        * Create a <code>CronTrigger</code> with the given name and group.
  318        * </p>
  319        */
  320       public UICronTrigger(String name, String group) {
  321           super(name, group);
  322           reset();
  323       }
  324   
  325       /**
  326        * <p>
  327        * Create a <code>CronTrigger</code> with the given name and group, and
  328        * associated with the identified <code>{@link Job}</code>.
  329        * </p>
  330        */
  331       public UICronTrigger(String name, String group, String jobName,
  332               String jobGroup) {
  333           super(name, group, jobName, jobGroup);
  334           reset();
  335       }
  336   
  337       /*
  338        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  339        * 
  340        * Interface.
  341        * 
  342        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  343        */
  344   
  345       /**
  346        * <p>
  347        * Get the time at which the <code>CronTrigger</code> should occur.
  348        * </p>
  349        */
  350       public Date getStartTime() {
  351           return this.startTime;
  352       }
  353   
  354       public void setStartTime(Date startTime) {
  355           if (startTime == null)
  356                   throw new IllegalArgumentException("Start time cannot be null");
  357   
  358           Date eTime = getEndTime();
  359           if (eTime != null && startTime != null && eTime.before(startTime))
  360               throw new IllegalArgumentException(
  361               "End time cannot be before start time");
  362   
  363           
  364           // round off millisecond...
  365           // Note timeZone is not needed here as parameter for
  366           // Calendar.getInstance(), since time zone is implicit
  367           // when using a Date in the setTime method.
  368           Calendar cl = Calendar.getInstance();
  369           cl.setTime(startTime);
  370           cl.set(Calendar.MILLISECOND, 0);
  371   
  372           this.startTime = cl.getTime();
  373       }
  374   
  375       /**
  376        * <p>
  377        * Get the time at which the <code>CronTrigger</code> should quit
  378        * repeating - even if repeastCount isn't yet satisfied.
  379        * </p>
  380        * 
  381        * @see #getFinalFireTime()
  382        */
  383       public Date getEndTime() {
  384           return this.endTime;
  385       }
  386   
  387       public void setEndTime(Date endTime) {
  388           Date sTime = getStartTime();
  389           if (sTime != null && endTime != null && sTime.after(endTime))
  390                   throw new IllegalArgumentException(
  391                           "End time cannot be before start time");
  392   
  393           this.endTime = endTime;
  394       }
  395   
  396       /**
  397        * <p>
  398        * Returns the next time at which the <code>CronTrigger</code> will fire.
  399        * If the trigger will not fire again, <code>null</code> will be
  400        * returned. The value returned is not guaranteed to be valid until after
  401        * the <code>Trigger</code> has been added to the scheduler.
  402        * </p>
  403        */
  404       public Date getNextFireTime() {
  405           return this.nextFireTime;
  406       }
  407   
  408       public void updateAfterMisfire(org.quartz.Calendar cal) {
  409           int instr = getMisfireInstruction();
  410   
  411           if (instr == MISFIRE_INSTRUCTION_SMART_POLICY)
  412                   instr = MISFIRE_INSTRUCTION_DO_NOTHING;
  413   
  414           if (instr == MISFIRE_INSTRUCTION_DO_NOTHING) {
  415               Date newFireTime = getFireTimeAfter(new Date());
  416               while (newFireTime != null && cal != null
  417                       && !cal.isTimeIncluded(newFireTime.getTime())) {
  418                   newFireTime = getFireTimeAfter(newFireTime);
  419               }
  420   
  421               setNextFireTime(newFireTime);
  422   
  423           } else if (instr == MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) {
  424               setNextFireTime(new Date());
  425           }
  426       }
  427   
  428       public Date getPreviousFireTime() {
  429           return this.previousFireTime;
  430       }
  431   
  432       /**
  433        * <p>
  434        * Set the previous time at which the <code>SimpleTrigger</code> fired.
  435        * </p>
  436        * 
  437        * <p>
  438        * <b>This method should not be invoked by client code.</b>
  439        * </p>
  440        */
  441       public void setPreviousFireTime(Date previousFireTime) {
  442           this.previousFireTime = previousFireTime;
  443       }
  444   
  445       /**
  446        * <p>
  447        * Sets the next time at which the <code>CronTrigger</code> will fire. If
  448        * the trigger will not fire again, <code>null</code> will be returned.
  449        * </p>
  450        */
  451       public void setNextFireTime(Date nextFireTime) {
  452           this.nextFireTime = nextFireTime;
  453       }
  454   
  455       /**
  456        * <p>
  457        * Returns the time zone for which the <code>cronExpression</code> of
  458        * this <code>CronTrigger</code> will be resolved.
  459        * </p>
  460        */
  461       public TimeZone getTimeZone() {
  462           return this.timeZone;
  463       }
  464   
  465       /**
  466        * <p>
  467        * Sets the time zone for which the <code>cronExpression</code> of this
  468        * <code>CronTrigger</code> will be resolved.
  469        * </p>
  470        */
  471       public void setTimeZone(TimeZone timeZone) {
  472           this.timeZone = timeZone;
  473       }
  474   
  475       /**
  476        * <p>
  477        * Returns the next time at which the <code>CronTrigger</code> will fire,
  478        * after the given time. If the trigger will not fire after the given time,
  479        * <code>null</code> will be returned.
  480        * </p>
  481        * 
  482        * <p>
  483        * Note that the date returned is NOT validated against the related
  484        * org.quartz.Calendar (if any)
  485        * </p>
  486        */
  487       public Date getFireTimeAfter(Date afterTime) {
  488           if (afterTime == null) afterTime = new Date();
  489   
  490           if (startTime.after(afterTime))
  491                   afterTime = new Date(startTime.getTime() - 1000l);
  492   
  493           Date pot = getTimeAfter(afterTime);
  494           if (endTime != null && pot != null && pot.after(endTime)) return null;
  495   
  496           return pot;
  497       }
  498   
  499       /**
  500        * <p>
  501        * Returns the final time at which the <code>CronTrigger</code> will
  502        * fire.
  503        * </p>
  504        * 
  505        * <p>
  506        * Note that the return time *may* be in the past. and the date returned is
  507        * not validated against org.quartz.calendar
  508        * </p>
  509        */
  510       public Date getFinalFireTime() {
  511           if (this.endTime != null) return getTimeBefore(this.endTime);
  512           else
  513               return null;
  514       }
  515   
  516       /**
  517        * <p>
  518        * Determines whether or not the <code>CronTrigger</code> will occur
  519        * again.
  520        * </p>
  521        */
  522       public boolean mayFireAgain() {
  523           return (getNextFireTime() != null);
  524       }
  525   
  526       protected boolean validateMisfireInstruction(int misfireInstruction) {
  527           if (misfireInstruction < MISFIRE_INSTRUCTION_SMART_POLICY)
  528                   return false;
  529   
  530           if (misfireInstruction > MISFIRE_INSTRUCTION_DO_NOTHING) return false;
  531   
  532           return true;
  533       }
  534   
  535       /**
  536        * <p>
  537        * Updates the <code>CronTrigger</code>'s state based on the
  538        * MISFIRE_INSTRUCTION_XXX that was selected when the <code>SimpleTrigger</code>
  539        * was created.
  540        * </p>
  541        * 
  542        * <p>
  543        * If the misfire instruction is set to MISFIRE_INSTRUCTION_SMART_POLICY,
  544        * then the following scheme will be used: <br>
  545        * <ul>
  546        * <li>The instruction will be interpreted as <code>MISFIRE_INSTRUCTION_DO_NOTHING</code>
  547        * </ul>
  548        * </p>
  549        */
  550       public void updateAfterMisfire() {
  551           int instr = getMisfireInstruction();
  552   
  553           if (instr == MISFIRE_INSTRUCTION_SMART_POLICY)
  554                   instr = MISFIRE_INSTRUCTION_DO_NOTHING;
  555   
  556           if (instr == MISFIRE_INSTRUCTION_DO_NOTHING) {
  557               setNextFireTime(getFireTimeAfter(new Date()));
  558           } else if (instr == MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) {
  559               setNextFireTime(new Date());
  560           }
  561       }
  562   
  563       /**
  564        * <p>
  565        * Determines whether the date & time of the given java.util.Calendar
  566        * instance falls on a scheduled fire-time of this trigger.
  567        * </p>
  568        * 
  569        * <p>
  570        * Note that the date returned is NOT validated against the related
  571        * org.quartz.Calendar (if any)
  572        * </p>
  573        */
  574       public boolean willFireOn(Calendar test) {
  575           Integer second = new Integer(test.get(Calendar.SECOND));
  576           Integer minute = new Integer(test.get(Calendar.MINUTE));
  577           Integer hour = new Integer(test.get(Calendar.HOUR_OF_DAY));
  578           Integer day = new Integer(test.get(Calendar.DAY_OF_MONTH));
  579           Integer month = new Integer(test.get(Calendar.MONTH));
  580   
  581           if ((seconds.contains(second) || seconds.contains(ALL_SPEC))
  582                   && (minutes.contains(minute) || minutes.contains(ALL_SPEC))
  583                   && (hours.contains(hour) || hours.contains(ALL_SPEC))
  584                   && (daysOfMonth.contains(day) || daysOfMonth.contains(ALL_SPEC))
  585                   && (months.contains(month) || months.contains(ALL_SPEC))) { 
  586   
  587           return true; }
  588   
  589           return false;
  590       }
  591   
  592       /**
  593        * <p>
  594        * Called after the <code>{@link Scheduler}</code> has executed the
  595        * <code>{@link Job}</code> associated with the <code>Trigger</code> in
  596        * order to get the final instruction code from the trigger.
  597        * </p>
  598        * 
  599        * @param context
  600        *          is the <code>JobExecutionContext</code> that was used by the
  601        *          <code>Job</code>'s<code>execute(xx)</code> method.
  602        * @param result
  603        *          is the <code>JobExecutionException</code> thrown by the
  604        *          <code>Job</code>, if any (may be null).
  605        * @return one of the Trigger.INSTRUCTION_XXX constants.
  606        * 
  607        * @see #INSTRUCTION_NOOP
  608        * @see #INSTRUCTION_RE_EXECUTE_JOB
  609        * @see #INSTRUCTION_DELETE_TRIGGER
  610        * @see #INSTRUCTION_SET_TRIGGER_COMPLETE
  611        * @see #triggered(Calendar)
  612        */
  613       public int executionComplete(JobExecutionContext context,
  614               JobExecutionException result) {
  615           if (result != null && result.refireImmediately())
  616                   return Trigger.INSTRUCTION_RE_EXECUTE_JOB;
  617   
  618           if (result != null && result.refireImmediately())
  619                   return INSTRUCTION_RE_EXECUTE_JOB;
  620   
  621           if (result != null && result.unscheduleFiringTrigger())
  622                   return INSTRUCTION_SET_TRIGGER_COMPLETE;
  623   
  624           if (result != null && result.unscheduleAllTriggers())
  625                   return INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE;
  626   
  627           if (!mayFireAgain()) return INSTRUCTION_DELETE_TRIGGER;
  628   
  629           return INSTRUCTION_NOOP;
  630       }
  631   
  632       /**
  633        * <p>
  634        * Called when the <code>{@link Scheduler}</code> has decided to 'fire'
  635        * the trigger (execute the associated <code>Job</code>), in order to
  636        * give the <code>Trigger</code> a chance to update itself for its next
  637        * triggering (if any).
  638        * </p>
  639        * 
  640        * @see #executionComplete(JobExecutionContext, JobExecutionException)
  641        */
  642       public void triggered(org.quartz.Calendar calendar) {
  643           previousFireTime = nextFireTime;
  644           nextFireTime = getFireTimeAfter(nextFireTime);
  645   
  646           while (nextFireTime != null && calendar != null
  647                   && !calendar.isTimeIncluded(nextFireTime.getTime())) {
  648               nextFireTime = getFireTimeAfter(nextFireTime);
  649           }
  650       }
  651   
  652       /**
  653        *  
  654        * @see org.quartz.Trigger#updateWithNewCalendar(org.quartz.Calendar, long)
  655        */
  656       public void updateWithNewCalendar(org.quartz.Calendar calendar, long misfireThreshold)
  657       {
  658           nextFireTime = getFireTimeAfter(previousFireTime);
  659           
  660           Date now = new Date();
  661           do {
  662               while (nextFireTime != null && calendar != null
  663                       && !calendar.isTimeIncluded(nextFireTime.getTime())) {
  664                   nextFireTime = getFireTimeAfter(nextFireTime);
  665               }
  666               
  667               if(nextFireTime != null && nextFireTime.before(now)) {
  668                   long diff = now.getTime() - nextFireTime.getTime();
  669                   if(diff >= misfireThreshold) {
  670                       nextFireTime = getFireTimeAfter(nextFireTime);
  671                       continue;
  672                   }
  673               }
  674           }while(false);
  675       }
  676   
  677       /**
  678        * <p>
  679        * Called by the scheduler at the time a <code>Trigger</code> is first
  680        * added to the scheduler, in order to have the <code>Trigger</code>
  681        * compute its first fire time, based on any associated calendar.
  682        * </p>
  683        * 
  684        * <p>
  685        * After this method has been called, <code>getNextFireTime()</code>
  686        * should return a valid answer.
  687        * </p>
  688        * 
  689        * @return the first time at which the <code>Trigger</code> will be fired
  690        *         by the scheduler, which is also the same value <code>getNextFireTime()</code>
  691        *         will return (until after the first firing of the <code>Trigger</code>).
  692        *         </p>
  693        */
  694       public Date computeFirstFireTime(org.quartz.Calendar calendar) {
  695           nextFireTime = getFireTimeAfter(new Date(startTime.getTime() - 1000l));
  696   
  697           while (nextFireTime != null && calendar != null
  698                   && !calendar.isTimeIncluded(nextFireTime.getTime())) {
  699               nextFireTime = getFireTimeAfter(nextFireTime);
  700           }
  701   
  702           return nextFireTime;
  703       }
  704   
  705       public String getExpressionSummary() {
  706           StringBuffer buf = new StringBuffer();
  707   
  708           buf.append("seconds: ");
  709           buf.append(getExpressionSetSummary(seconds));
  710           buf.append("\n");
  711           buf.append("minutes: ");
  712           buf.append(getExpressionSetSummary(minutes));
  713           buf.append("\n");
  714           buf.append("hours: ");
  715           buf.append(getExpressionSetSummary(hours));
  716           buf.append("\n");
  717           buf.append("daysOfMonth: ");
  718           buf.append(getExpressionSetSummary(daysOfMonth));
  719           buf.append("\n");
  720           buf.append("months: ");
  721           buf.append(getExpressionSetSummary(months));
  722           buf.append("\n");
  723           buf.append("daysOfWeek: ");
  724           buf.append(getExpressionSetSummary(daysOfWeek));
  725           buf.append("\n");
  726           buf.append("lastdayOfWeek: ");
  727           buf.append(lastdayOfWeek);
  728           buf.append("\n");
  729           buf.append("lastdayOfMonth: ");
  730           buf.append(lastdayOfMonth);
  731           buf.append("\n");
  732           buf.append("calendardayOfWeek: ");
  733           buf.append(calendardayOfWeek);
  734           buf.append("\n");
  735           buf.append("calendardayOfMonth: ");
  736           buf.append(calendardayOfMonth);
  737           buf.append("\n");
  738           buf.append("years: ");
  739           buf.append(getExpressionSetSummary(years));
  740           buf.append("\n");
  741   
  742           return buf.toString();
  743       }
  744   
  745       private String getExpressionSetSummary(Set set) {
  746   
  747           if (set.contains(NO_SPEC)) return "?";
  748           if (set.contains(ALL_SPEC)) return "*";
  749   
  750           StringBuffer buf = new StringBuffer();
  751   
  752           Iterator itr = set.iterator();
  753           boolean first = true;
  754           while (itr.hasNext()) {
  755               Integer iVal = (Integer) itr.next();
  756               String val = iVal.toString();
  757               if (!first) buf.append(",");
  758               buf.append(val);
  759               first = false;
  760           }
  761   
  762           return buf.toString();
  763       }
  764   
  765       ////////////////////////////////////////////////////////////////////////////
  766       //
  767       // Computation Functions
  768       //
  769       ////////////////////////////////////////////////////////////////////////////
  770   
  771       private Date getTimeAfter(Date afterTime) {
  772           Calendar cl = Calendar.getInstance(timeZone);
  773   
  774           // move ahead one second, since we're computing the time *after* the
  775           // given time
  776           afterTime = new Date(afterTime.getTime() + 1000);
  777           // CronTrigger does not deal with milliseconds
  778           cl.setTime(afterTime);
  779           cl.set(Calendar.MILLISECOND, 0);
  780   
  781           boolean gotOne = false;
  782   
  783           // loop until we've computed the next time, or we've past the endTime
  784           while (!gotOne) {
  785   
  786               if (endTime != null && cl.getTime().after(endTime)) return null;
  787   
  788               SortedSet st = null;
  789               int t = 0;
  790   
  791               int sec = cl.get(Calendar.SECOND);
  792               int min = cl.get(Calendar.MINUTE);
  793   
  794               // get second.................................................
  795               st = seconds.tailSet(new Integer(sec));
  796               if (st != null && st.size() != 0) {
  797                   sec = ((Integer) st.first()).intValue();
  798               } else {
  799                   sec = ((Integer) seconds.first()).intValue();
  800                   min++;
  801                   cl.set(Calendar.MINUTE, min);
  802               }
  803               cl.set(Calendar.SECOND, sec);
  804   
  805               min = cl.get(Calendar.MINUTE);
  806               int hr = cl.get(Calendar.HOUR_OF_DAY);
  807               t = -1;
  808   
  809               // get minute.................................................
  810               st = minutes.tailSet(new Integer(min));
  811               if (st != null && st.size() != 0) {
  812                   t = min;
  813                   min = ((Integer) st.first()).intValue();
  814               } else {
  815                   min = ((Integer) minutes.first()).intValue();
  816                   hr++;
  817               }
  818               if (min != t) {
  819                   cl.set(Calendar.SECOND, 0);
  820                   cl.set(Calendar.MINUTE, min);
  821                   cl.set(Calendar.HOUR_OF_DAY, hr);
  822                   continue;
  823               }
  824               cl.set(Calendar.MINUTE, min);
  825   
  826               hr = cl.get(Calendar.HOUR_OF_DAY);
  827               int day = cl.get(Calendar.DAY_OF_MONTH);
  828               t = -1;
  829   
  830               // get hour...................................................
  831               st = hours.tailSet(new Integer(hr));
  832               if (st != null && st.size() != 0) {
  833                   t = hr;
  834                   hr = ((Integer) st.first()).intValue();
  835               } else {
  836                   hr = ((Integer) hours.first()).intValue();
  837                   day++;
  838               }
  839               if (hr != t) {
  840                   cl.set(Calendar.SECOND, 0);
  841                   cl.set(Calendar.MINUTE, 0);
  842                   cl.set(Calendar.HOUR_OF_DAY, hr);
  843                   cl.set(Calendar.DAY_OF_MONTH, day);
  844                   continue;
  845               }
  846               cl.set(Calendar.HOUR_OF_DAY, hr);
  847   
  848               day = cl.get(Calendar.DAY_OF_MONTH);
  849               int mon = cl.get(Calendar.MONTH) + 1; // '+ 1' because calendar is
  850               // 0-based for this field,
  851               // and we are 1-based
  852               t = -1;
  853   
  854               // get day...................................................
  855               boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC);
  856               boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC);
  857               if (dayOfMSpec && !dayOfWSpec) { // get day only by day of month
  858                   // rule
  859                   st = daysOfMonth.tailSet(new Integer(day));
  860                   if (lastdayOfMonth) {
  861                       t = day;
  862                       day = getLastDayOfMonth(mon);
  863                   } else if (st != null && st.size() != 0) {
  864                       t = day;
  865                       day = ((Integer) st.first()).intValue();
  866                   } else {
  867                       day = ((Integer) daysOfMonth.first()).intValue();
  868                       mon++;
  869                   }
  870                   if (day != t) {
  871                       cl.set(Calendar.SECOND, 0);
  872                       cl.set(Calendar.MINUTE, 0);
  873                       cl.set(Calendar.HOUR_OF_DAY, 0);
  874                       cl.set(Calendar.DAY_OF_MONTH, day);
  875                       cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar
  876                       // is 0-based for this
  877                       // field, and we are
  878                       // 1-based
  879                       continue;
  880                   }
  881               } else if (dayOfWSpec && !dayOfMSpec) { // get day only by day of
  882                   // week rule
  883                   if (lastdayOfWeek) { // are we looking for the last XXX day of
  884                       // the month?
  885                       int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
  886                       // d-o-w
  887                       int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
  888                       int daysToAdd = 0;
  889                       if (cDow < dow) daysToAdd = dow - cDow;
  890                       if (cDow > dow) daysToAdd = dow + (7 - cDow);
  891   
  892                       int lDay = getLastDayOfMonth(mon);
  893   
  894                       if (day + daysToAdd > lDay) { // did we already miss the
  895                           // last one?
  896                           cl.set(Calendar.SECOND, 0);
  897                           cl.set(Calendar.MINUTE, 0);
  898                           cl.set(Calendar.HOUR_OF_DAY, 0);
  899                           cl.set(Calendar.DAY_OF_MONTH, 1);
  900                           cl.set(Calendar.MONTH, mon); // no '- 1' here because
  901                           // we are promoting the
  902                           // month
  903                           continue;
  904                       }
  905   
  906                       // find date of last occurance of this day in this month...
  907                       while ((day + daysToAdd + 7) <= lDay)
  908                           daysToAdd += 7;
  909   
  910                       day += daysToAdd;
  911                   } else if (nthdayOfWeek != 0) { // are we looking for the Nth
  912                       // XXX day in the month?
  913                       int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
  914                       // d-o-w
  915                       int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
  916                       int daysToAdd = 0;
  917                       if (cDow < dow) daysToAdd = dow - cDow;
  918                       else if (cDow > dow) daysToAdd = dow + (7 - cDow);
  919   
  920                       day += daysToAdd;
  921                       int weekOfMonth = day / 7;
  922                       if (day % 7 > 0) weekOfMonth++;
  923   
  924                       daysToAdd = (nthdayOfWeek - weekOfMonth) * 7;
  925                       day += daysToAdd;
  926                       if (daysToAdd < 0 || day > getLastDayOfMonth(mon)) {
  927                           cl.set(Calendar.SECOND, 0);
  928                           cl.set(Calendar.MINUTE, 0);
  929                           cl.set(Calendar.HOUR_OF_DAY, 0);
  930                           cl.set(Calendar.DAY_OF_MONTH, 1);
  931                           cl.set(Calendar.MONTH, mon); // no '- 1' here because
  932                           // we are promoting the
  933                           // month
  934                           continue;
  935                       }
  936                   } else {
  937                       int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
  938                       int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
  939                       // d-o-w
  940                       st = daysOfWeek.tailSet(new Integer(cDow));
  941                       if (st != null && st.size() > 0) {
  942                           dow = ((Integer) st.first()).intValue();
  943                       }
  944   
  945                       int daysToAdd = 0;
  946                       if (cDow < dow) daysToAdd = dow - cDow;
  947                       if (cDow > dow) daysToAdd = dow + (7 - cDow);
  948   
  949                       int lDay = getLastDayOfMonth(mon);
  950   
  951                       if (day + daysToAdd > lDay) { // will we pass the end of
  952                           // the month?
  953                           cl.set(Calendar.SECOND, 0);
  954                           cl.set(Calendar.MINUTE, 0);
  955                           cl.set(Calendar.HOUR_OF_DAY, 0);
  956                           cl.set(Calendar.DAY_OF_MONTH, 1);
  957                           cl.set(Calendar.MONTH, mon); // no '- 1' here because
  958                           // we are promoting the
  959                           // month
  960                           continue;
  961                       } else if (daysToAdd > 0) { // are we swithing days?
  962                           cl.set(Calendar.SECOND, 0);
  963                           cl.set(Calendar.MINUTE, 0);
  964                           cl.set(Calendar.HOUR_OF_DAY, 0);
  965                           cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd);
  966                           cl.set(Calendar.MONTH, mon - 1); // '- 1' because
  967                           // calendar is 0-based
  968                           // for this field, and
  969                           // we are 1-based
  970                           continue;
  971                       }
  972                   }
  973               } else { // dayOfWSpec && !dayOfMSpec
  974                   throw new UnsupportedOperationException(
  975                           "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented."); // TODO:
  976               }
  977               cl.set(Calendar.DAY_OF_MONTH, day);
  978   
  979               mon = cl.get(Calendar.MONTH) + 1; // '+ 1' because calendar is
  980               // 0-based for this field, and we
  981               // are 1-based
  982               int year = cl.get(Calendar.YEAR);
  983               t = -1;
  984   
  985               // get month...................................................
  986               st = months.tailSet(new Integer(mon));
  987               if (st != null && st.size() != 0) {
  988                   t = mon;
  989                   mon = ((Integer) st.first()).intValue();
  990               } else {
  991                   mon = ((Integer) months.first()).intValue();
  992                   year++;
  993               }
  994               if (mon != t) {
  995                   cl.set(Calendar.SECOND, 0);
  996                   cl.set(Calendar.MINUTE, 0);
  997                   cl.set(Calendar.HOUR_OF_DAY, 0);
  998                   cl.set(Calendar.DAY_OF_MONTH, 1);
  999                   cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is
 1000                   // 0-based for this field, and
 1001                   // we are 1-based
 1002                   cl.set(Calendar.YEAR, year);
 1003                   continue;
 1004               }
 1005               cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is
 1006               // 0-based for this field, and we
 1007               // are 1-based
 1008   
 1009               year = cl.get(Calendar.YEAR);
 1010               t = -1;
 1011   
 1012               // get year...................................................
 1013               st = years.tailSet(new Integer(year));
 1014               if (st != null && st.size() != 0) {
 1015                   t = year;
 1016                   year = ((Integer) st.first()).intValue();
 1017               } else
 1018                   return null; // ran out of years...
 1019   
 1020               if (year != t) {
 1021                   cl.set(Calendar.SECOND, 0);
 1022                   cl.set(Calendar.MINUTE, 0);
 1023                   cl.set(Calendar.HOUR_OF_DAY, 0);
 1024                   cl.set(Calendar.DAY_OF_MONTH, 1);
 1025                   cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is
 1026                   // 0-based for this field, and
 1027                   // we are 1-based
 1028                   cl.set(Calendar.YEAR, year);
 1029                   continue;
 1030               }
 1031               cl.set(Calendar.YEAR, year);
 1032   
 1033               gotOne = true;
 1034           } // while( !done )
 1035   
 1036           return cl.getTime();
 1037       }
 1038   
 1039       private Date getTimeBefore(Date endTime) // TODO: implement
 1040       {
 1041           return null;
 1042       }
 1043   
 1044       public boolean isLeapYear() {
 1045           Calendar cl = Calendar.getInstance(timeZone);
 1046           int year = cl.get(Calendar.YEAR);
 1047   
 1048           if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return true;
 1049           else
 1050               return false;
 1051       }
 1052   
 1053       public int getLastDayOfMonth(int monthNum) {
 1054   
 1055           switch (monthNum) {
 1056           case 1:
 1057               return 31;
 1058           case 2:
 1059               return (isLeapYear()) ? 29 : 28;
 1060           case 3:
 1061               return 31;
 1062           case 4:
 1063               return 30;
 1064           case 5:
 1065               return 31;
 1066           case 6:
 1067               return 30;
 1068           case 7:
 1069               return 31;
 1070           case 8:
 1071               return 31;
 1072           case 9:
 1073               return 30;
 1074           case 10:
 1075               return 31;
 1076           case 11:
 1077               return 30;
 1078           case 12:
 1079               return 31;
 1080           default:
 1081               throw new IllegalArgumentException("Illegal month number: "
 1082                       + monthNum);
 1083           }
 1084       }
 1085   
 1086       public Integer[] getSecondsValues() {
 1087           Integer list[] = new Integer[60];
 1088           for (int i = 0; i < 60; i++) {
 1089               list[i] = new Integer(i);
 1090           }
 1091   
 1092           return list;
 1093       }
 1094   
 1095       public Integer[] getSecondsLabels() {
 1096           return getSecondsValues();
 1097       }
 1098   
 1099       public Integer[] getSeconds() {
 1100           Integer list[] = new Integer[seconds.size()];
 1101           if (seconds != null) {
 1102               int i = 0;
 1103               for (Iterator it = seconds.iterator(); it.hasNext(); i++) {
 1104                   list[i] = (Integer) it.next();
 1105               }
 1106           }
 1107           return list;
 1108       }
 1109   
 1110       public void setSeconds(Integer[] val) {
 1111           if (seconds != null) seconds.clear();
 1112           else
 1113               seconds = new TreeSet();
 1114   
 1115           for (int i = 0; i < val.length; i++) {
 1116               seconds.add(val[i]);
 1117           }
 1118       }
 1119   
 1120       public Integer[] getMinutesValues() {
 1121           Integer list[] = new Integer[60];
 1122           for (int i = 0; i < 60; i++) {
 1123               list[i] = new Integer(i);
 1124           }
 1125   
 1126           return list;
 1127       }
 1128   
 1129       public Integer[] getMinutesLabels() {
 1130           return getMinutesValues();
 1131       }
 1132   
 1133       public Integer[] getMinutes() {
 1134           Integer list[] = new Integer[minutes.size()];
 1135           if (minutes != null) {
 1136               int i = 0;
 1137               for (Iterator it = minutes.iterator(); it.hasNext(); i++) {
 1138                   list[i] = (Integer) it.next();
 1139               }
 1140           }
 1141           return list;
 1142       }
 1143   
 1144       public void setMinutes(Integer[] val) {
 1145           if (minutes != null) minutes.clear();
 1146           else
 1147               minutes = new TreeSet();
 1148   
 1149           for (int i = 0; i < val.length; i++) {
 1150               minutes.add(val[i]);
 1151           }
 1152       }
 1153   
 1154       public Integer[] getHoursValues() {
 1155           Integer list[] = new Integer[24];
 1156           for (int i = 0; i < 24; i++) {
 1157               list[i] = new Integer(i);
 1158           }
 1159   
 1160           return list;
 1161       }
 1162   
 1163       public String[] getHoursLabels() {
 1164           String vals[] = {"12AM (Midnight)", "1AM", "2AM", "3AM", "4AM", "5AM",
 1165                   "6AM", "7AM", "8AM", "9AM", "10AM", "11AM", "12PM (Noon)",
 1166                   "1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM",
 1167                   "10PM", "11PM"};
 1168           return vals;
 1169       }
 1170   
 1171       public Integer[] getHours() {
 1172           Integer list[] = new Integer[hours.size()];
 1173           if (hours != null) {
 1174               int i = 0;
 1175               for (Iterator it = hours.iterator(); it.hasNext(); i++) {
 1176                   list[i] = (Integer) it.next();
 1177               }
 1178           }
 1179           return list;
 1180       }
 1181   
 1182       public void setHours(Integer[] val) {
 1183           if (hours != null) hours.clear();
 1184           else
 1185               hours = new TreeSet();
 1186   
 1187           for (int i = 0; i < val.length; i++) {
 1188               hours.add(val[i]);
 1189           }
 1190       }
 1191   
 1192       public Integer[] getDaysOfMonthValues() {
 1193           Integer list[] = new Integer[31];
 1194           for (int i = 0; i < 31; i++) {
 1195               list[i] = new Integer(i + 1);
 1196           }
 1197   
 1198           return list;
 1199       }
 1200   
 1201       public Integer[] getDaysOfMonthLabels() {
 1202           return getDaysOfMonthValues();
 1203       }
 1204   
 1205       public Integer[] getDaysOfMonth() {
 1206           Integer list[] = new Integer[daysOfMonth.size()];
 1207           if (daysOfMonth != null) {
 1208               int i = 0;
 1209               for (Iterator it = daysOfMonth.iterator(); it.hasNext(); i++) {
 1210                   list[i] = (Integer) it.next();
 1211               }
 1212           }
 1213           return list;
 1214       }
 1215   
 1216       public void setDaysOfMonth(Integer[] val) {
 1217           if (daysOfMonth != null) daysOfMonth.clear();
 1218           else
 1219               daysOfMonth = new TreeSet();
 1220   
 1221           for (int i = 0; i < val.length; i++) {
 1222               daysOfMonth.add(val[i]);
 1223           }
 1224           daysOfWeek.clear();
 1225           daysOfWeek.add(NO_SPEC);
 1226       }
 1227   
 1228       public Integer[] getMonthsValues() {
 1229           Integer list[] = new Integer[12];
 1230           for (int i = 0; i < 12; i++) {
 1231               list[i] = new Integer(i + 1);
 1232           }
 1233   
 1234           return list;
 1235       }
 1236   
 1237       public String[] getMonthsLabels() {
 1238           String vals[] = {"January", "February", "March", "April", "May",
 1239                   "June", "July", "August", "September", "October", "November",
 1240                   "December"};
 1241           return vals;
 1242       }
 1243   
 1244       public Integer[] getMonths() {
 1245           Integer list[] = new Integer[months.size()];
 1246           if (months != null) {
 1247               int i = 0;
 1248               for (Iterator it = months.iterator(); it.hasNext(); i++) {
 1249                   list[i] = (Integer) it.next();
 1250               }
 1251           }
 1252           return list;
 1253       }
 1254   
 1255       public void setMonths(Integer[] val) {
 1256           if (months != null) months.clear();
 1257           else
 1258               months = new TreeSet();
 1259   
 1260           for (int i = 0; i < val.length; i++) {
 1261               months.add(val[i]);
 1262           }
 1263       }
 1264   
 1265       public String[] getDaysOfWeekLabels() {
 1266           String list[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
 1267                   "Thursday", "Friday", "Saturday"};
 1268           return list;
 1269       }
 1270   
 1271       public Integer[] getDaysOfWeekValues() {
 1272           Integer list[] = new Integer[7];
 1273           for (int i = 0; i < 7; i++)
 1274               list[i] = new Integer(i + 1);
 1275           return list;
 1276       }
 1277   
 1278       public Integer[] getDaysOfWeek() {
 1279           Integer list[] = new Integer[daysOfWeek.size()];
 1280           if (daysOfWeek != null) {
 1281               int i = 0;
 1282               for (Iterator it = daysOfWeek.iterator(); it.hasNext(); i++) {
 1283                   list[i] = (Integer) it.next();
 1284               }
 1285           }
 1286           return list;
 1287       }
 1288   
 1289       public void setDaysOfWeek(Integer[] val) {
 1290           if (daysOfWeek != null) daysOfWeek.clear();
 1291           else
 1292               daysOfWeek = new TreeSet();
 1293   
 1294           for (int i = 0; i < val.length; i++) {
 1295               daysOfWeek.add(val[i]);
 1296           }
 1297   
 1298           daysOfMonth.clear();
 1299           daysOfMonth.add(NO_SPEC);
 1300       }
 1301   
 1302       public Integer[] getYearsValues() {
 1303           Integer list[] = new Integer[20];
 1304           Calendar now = Calendar.getInstance();
 1305           int year = now.get(Calendar.YEAR);
 1306           for (int i = 0; i < 20; i++) {
 1307               list[i] = new Integer(i + year);
 1308           }
 1309   
 1310           return list;
 1311       }
 1312   
 1313       public Integer[] getYearsLabels() {
 1314           return getYearsValues();
 1315       }
 1316   
 1317       public Integer[] getYears() {
 1318           Integer list[] = new Integer[years.size()];
 1319           if (years != null) {
 1320               int i = 0;
 1321               for (Iterator it = years.iterator(); it.hasNext(); i++) {
 1322                   list[i] = (Integer) it.next();
 1323               }
 1324           }
 1325           return list;
 1326       }
 1327   
 1328       public void setYears(Integer[] val) {
 1329           if (years != null) years.clear();
 1330           else
 1331               years = new TreeSet();
 1332   
 1333           for (int i = 0; i < val.length; i++) {
 1334               years.add(val[i]);
 1335           }
 1336       }
 1337   
 1338       public static void main(String[] argv) {
 1339           CronTrigger ct = new CronTrigger("a", "a");
 1340           try {
 1341               ct.setCronExpression("0 * * * * ? *");
 1342           } catch (ParseException e) {
 1343               //            log.error("caught an exception", e);
 1344           }
 1345           ct.setStartTime(new Date());
 1346           ct.setTimeZone(TimeZone.getDefault());
 1347           System.out.println(ct.getExpressionSummary());
 1348           ct.computeFirstFireTime(null);
 1349   
 1350           UICronTrigger uict = new UICronTrigger("a", "a");
 1351           Integer set[] = new Integer[1];
 1352           set[0] = new Integer(1);
 1353           uict.setSeconds(set);
 1354           System.out.println(ct.getExpressionSummary());
 1355           uict.computeFirstFireTime(null);
 1356   
 1357       }
 1358   }

Save This Page
Home » quartz-1.6.0 » org » quartz » [javadoc | source]