Home » quartz-1.6.0 » org » quartz » [javadoc | source]

    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 java.util.Date;
   25   import java.util.LinkedList;
   26   
   27   import org.quartz.utils.Key;
   28   
   29   
   30   /**
   31    * <p>
   32    * The base abstract class to be extended by all <code>Trigger</code>s.
   33    * </p>
   34    * 
   35    * <p>
   36    * <code>Triggers</code> s have a name and group associated with them, which
   37    * should uniquely identify them within a single <code>{@link Scheduler}</code>.
   38    * </p>
   39    * 
   40    * <p>
   41    * <code>Trigger</code>s are the 'mechanism' by which <code>Job</code> s
   42    * are scheduled. Many <code>Trigger</code> s can point to the same <code>Job</code>,
   43    * but a single <code>Trigger</code> can only point to one <code>Job</code>.
   44    * </p>
   45    * 
   46    * <p>
   47    * Triggers can 'send' parameters/data to <code>Job</code>s by placing contents
   48    * into the <code>JobDataMap</code> on the <code>Trigger</code>.
   49    * </p>
   50    * 
   51    * @see SimpleTrigger
   52    * @see CronTrigger
   53    * @see NthIncludedDayTrigger
   54    * @see TriggerUtils
   55    * @see JobDataMap
   56    * @see JobExecutionContext
   57    * 
   58    * @author James House
   59    * @author Sharada Jambula
   60    */
   61   public abstract class Trigger implements java.io.Serializable, Cloneable,
   62           Comparable {
   63   
   64       private static final long serialVersionUID = -3904243490805975570L;
   65   
   66       /*
   67       * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   68       *
   69       * Constants.
   70       *
   71       * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   72       */
   73   
   74       /**
   75        * <p>
   76        * Instructs the <code>{@link Scheduler}</code> that the <code>{@link Trigger}</code>
   77        * has no further instructions.
   78        * </p>
   79        */
   80       public static final int INSTRUCTION_NOOP = 0;
   81   
   82       /**
   83        * <p>
   84        * Instructs the <code>{@link Scheduler}</code> that the <code>{@link Trigger}</code>
   85        * wants the <code>{@link org.quartz.JobDetail}</code> to re-execute
   86        * immediately. If not in a 'RECOVERING' or 'FAILED_OVER' situation, the
   87        * execution context will be re-used (giving the <code>Job</code> the
   88        * abilitiy to 'see' anything placed in the context by its last execution).
   89        * </p>
   90        */
   91       public static final int INSTRUCTION_RE_EXECUTE_JOB = 1;
   92   
   93       /**
   94        * <p>
   95        * Instructs the <code>{@link Scheduler}</code> that the <code>{@link Trigger}</code>
   96        * should be put in the <code>COMPLETE</code> state.
   97        * </p>
   98        */
   99       public static final int INSTRUCTION_SET_TRIGGER_COMPLETE = 2;
  100   
  101       /**
  102        * <p>
  103        * Instructs the <code>{@link Scheduler}</code> that the <code>{@link Trigger}</code>
  104        * wants itself deleted.
  105        * </p>
  106        */
  107       public static final int INSTRUCTION_DELETE_TRIGGER = 3;
  108   
  109       /**
  110        * <p>
  111        * Instructs the <code>{@link Scheduler}</code> that all <code>Trigger</code>
  112        * s referencing the same <code>{@link org.quartz.JobDetail}</code> as
  113        * this one should be put in the <code>COMPLETE</code> state.
  114        * </p>
  115        */
  116       public static final int INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE = 4;
  117   
  118       /**
  119        * <p>
  120        * Instructs the <code>{@link Scheduler}</code> that all <code>Trigger</code>
  121        * s referencing the same <code>{@link org.quartz.JobDetail}</code> as
  122        * this one should be put in the <code>ERROR</code> state.
  123        * </p>
  124        */
  125       public static final int INSTRUCTION_SET_TRIGGER_ERROR = 5;
  126   
  127       /**
  128        * <p>
  129        * Instructs the <code>{@link Scheduler}</code> that the <code>Trigger</code>
  130        * should be put in the <code>ERROR</code> state.
  131        * </p>
  132        */
  133       public static final int INSTRUCTION_SET_ALL_JOB_TRIGGERS_ERROR = 6;
  134   
  135       /**
  136        * <p>
  137        * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire
  138        * situation, the <code>updateAfterMisfire()</code> method will be called
  139        * on the <code>Trigger</code> to determine the mis-fire instruction.
  140        * </p>
  141        * 
  142        * <p>
  143        * In order to see if this instruction fits your needs, you should look at
  144        * the documentation for the <code>getSmartMisfirePolicy()</code> method
  145        * on the particular <code>Trigger</code> implementation you are using.
  146        * </p>
  147        */
  148       public static final int MISFIRE_INSTRUCTION_SMART_POLICY = 0;
  149   
  150       /**
  151        * <p>
  152        * Indicates that the <code>Trigger</code> is in the "normal" state.
  153        * </p>
  154        */
  155       public static final int STATE_NORMAL = 0;
  156   
  157       /**
  158        * <p>
  159        * Indicates that the <code>Trigger</code> is in the "paused" state.
  160        * </p>
  161        */
  162       public static final int STATE_PAUSED = 1;
  163   
  164       /**
  165        * <p>
  166        * Indicates that the <code>Trigger</code> is in the "complete" state.
  167        * </p>
  168        * 
  169        * <p>
  170        * "Complete" indicates that the trigger has not remaining fire-times in
  171        * its schedule.
  172        * </p>
  173        */
  174       public static final int STATE_COMPLETE = 2;
  175   
  176       /**
  177        * <p>
  178        * Indicates that the <code>Trigger</code> is in the "error" state.
  179        * </p>
  180        * 
  181        * <p>
  182        * A <code>Trigger</code> arrives at the error state when the scheduler
  183        * attempts to fire it, but cannot due to an error creating and executing
  184        * its related job. Often this is due to the <code>Job</code>'s
  185        * class not existing in the classpath.
  186        * </p>
  187        * 
  188        * <p>
  189        * When the trigger is in the error state, the scheduler will make no
  190        * attempts to fire it.
  191        * </p>
  192        */
  193       public static final int STATE_ERROR = 3;
  194   
  195   
  196       /**
  197        * <p>
  198        * Indicates that the <code>Trigger</code> is in the "blocked" state.
  199        * </p>
  200        * 
  201        * <p>
  202        * A <code>Trigger</code> arrives at the blocked state when the job that
  203        * it is associated with is a <code>StatefulJob</code> and it is 
  204        * currently executing.
  205        * </p>
  206        *
  207        * @see StatefulJob
  208        */
  209       public static final int STATE_BLOCKED = 4;
  210   
  211       /**
  212        * <p>
  213        * Indicates that the <code>Trigger</code> does not exist.
  214        * </p>
  215        */
  216       public static final int STATE_NONE = -1;
  217   
  218       /**
  219        * The default value for priority.
  220        */
  221       public static final int DEFAULT_PRIORITY = 5;
  222   
  223       /*
  224       * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  225       *
  226       * Data members.
  227       *
  228       * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  229       */
  230   
  231       private String name;
  232   
  233       private String group = Scheduler.DEFAULT_GROUP;
  234   
  235       private String jobName;
  236   
  237       private String jobGroup = Scheduler.DEFAULT_GROUP;
  238   
  239       private String description;
  240   
  241       private JobDataMap jobDataMap;
  242   
  243       private boolean volatility = false;
  244   
  245       private String calendarName = null;
  246   
  247       private String fireInstanceId = null;
  248   
  249       private int misfireInstruction = MISFIRE_INSTRUCTION_SMART_POLICY;
  250   
  251       private LinkedList triggerListeners = new LinkedList();
  252   
  253       private int priority = DEFAULT_PRIORITY;
  254   
  255       private transient Key key = null;
  256   
  257       /*
  258       * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  259       *
  260       * Constructors.
  261       *
  262       * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  263       */
  264   
  265   
  266   
  267       /**
  268        * <p>
  269        * Create a <code>Trigger</code> with no specified name, group, or <code>{@link org.quartz.JobDetail}</code>.
  270        * </p>
  271        * 
  272        * <p>
  273        * Note that the {@link #setName(String)},{@link #setGroup(String)}and
  274        * the {@link #setJobName(String)}and {@link #setJobGroup(String)}methods
  275        * must be called before the <code>Trigger</code> can be placed into a
  276        * {@link Scheduler}.
  277        * </p>
  278        */
  279       public Trigger() {
  280           // do nothing...
  281       }
  282   
  283       /**
  284        * <p>
  285        * Create a <code>Trigger</code> with the given name, and group.
  286        * </p>
  287        * 
  288        * <p>
  289        * Note that the {@link #setJobName(String)}and
  290        * {@link #setJobGroup(String)}methods must be called before the <code>Trigger</code>
  291        * can be placed into a {@link Scheduler}.
  292        * </p>
  293        * 
  294        * @param group if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
  295        * 
  296        * @exception IllegalArgumentException
  297        *              if name is null or empty, or the group is an empty string.
  298        */
  299       public Trigger(String name, String group) {
  300           setName(name);
  301           setGroup(group);
  302       }
  303   
  304       /**
  305        * <p>
  306        * Create a <code>Trigger</code> with the given name, and group.
  307        * </p>
  308        * 
  309        * @param group if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
  310        * 
  311        * @exception IllegalArgumentException
  312        *              if name is null or empty, or the group is an empty string.
  313        */
  314       public Trigger(String name, String group, String jobName, String jobGroup) {
  315           setName(name);
  316           setGroup(group);
  317           setJobName(jobName);
  318           setJobGroup(jobGroup);
  319       }
  320   
  321       /*
  322        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  323        * 
  324        * Interface.
  325        * 
  326        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  327        */
  328   
  329       /**
  330        * <p>
  331        * Get the name of this <code>Trigger</code>.
  332        * </p>
  333        */
  334       public String getName() {
  335           return name;
  336       }
  337   
  338       /**
  339        * <p>
  340        * Set the name of this <code>Trigger</code>.
  341        * </p>
  342        * 
  343        * @exception IllegalArgumentException
  344        *              if name is null or empty.
  345        */
  346       public void setName(String name) {
  347           if (name == null || name.trim().length() == 0) {
  348               throw new IllegalArgumentException(
  349                       "Trigger name cannot be null or empty.");
  350           }
  351   
  352           this.name = name;
  353       }
  354   
  355       /**
  356        * <p>
  357        * Get the group of this <code>Trigger</code>.
  358        * </p>
  359        */
  360       public String getGroup() {
  361           return group;
  362       }
  363   
  364       /**
  365        * <p>
  366        * Set the name of this <code>Trigger</code>. 
  367        * </p>
  368        * 
  369        * @param group if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
  370        * 
  371        * @exception IllegalArgumentException
  372        *              if group is an empty string.
  373        */
  374       public void setGroup(String group) {
  375           if (group != null && group.trim().length() == 0) {
  376               throw new IllegalArgumentException(
  377                       "Group name cannot be an empty string.");
  378           }
  379   
  380           if(group == null) {
  381               group = Scheduler.DEFAULT_GROUP;
  382           }
  383   
  384           this.group = group;
  385       }
  386   
  387       /**
  388        * <p>
  389        * Get the name of the associated <code>{@link org.quartz.JobDetail}</code>.
  390        * </p>
  391        */
  392       public String getJobName() {
  393           return jobName;
  394       }
  395   
  396       /**
  397        * <p>
  398        * Set the name of the associated <code>{@link org.quartz.JobDetail}</code>.
  399        * </p>
  400        * 
  401        * @exception IllegalArgumentException
  402        *              if jobName is null or empty.
  403        */
  404       public void setJobName(String jobName) {
  405           if (jobName == null || jobName.trim().length() == 0) {
  406               throw new IllegalArgumentException(
  407                       "Job name cannot be null or empty.");
  408           }
  409   
  410           this.jobName = jobName;
  411       }
  412   
  413       /**
  414        * <p>
  415        * Get the name of the associated <code>{@link org.quartz.JobDetail}</code>'s
  416        * group.
  417        * </p>
  418        */
  419       public String getJobGroup() {
  420           return jobGroup;
  421       }
  422   
  423       /**
  424        * <p>
  425        * Set the name of the associated <code>{@link org.quartz.JobDetail}</code>'s
  426        * group.
  427        * </p>
  428        * 
  429        * @param jobGroup if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
  430        * 
  431        * @exception IllegalArgumentException
  432        *              if group is an empty string.
  433        */
  434       public void setJobGroup(String jobGroup) {
  435           if (jobGroup != null && jobGroup.trim().length() == 0) {
  436               throw new IllegalArgumentException(
  437                       "Group name cannot be null or empty.");
  438           }
  439   
  440           if(jobGroup == null) {
  441               jobGroup = Scheduler.DEFAULT_GROUP;
  442           }
  443   
  444           this.jobGroup = jobGroup;
  445       }
  446   
  447       /**
  448        * <p>
  449        * Returns the 'full name' of the <code>Trigger</code> in the format
  450        * "group.name".
  451        * </p>
  452        */
  453       public String getFullName() {
  454           return group + "." + name;
  455       }
  456   
  457       public Key getKey() {
  458           if(key == null) {
  459               key = new Key(getName(), getGroup());
  460           }
  461   
  462           return key;
  463       }
  464   
  465       /**
  466        * <p>
  467        * Returns the 'full name' of the <code>Job</code> that the <code>Trigger</code>
  468        * points to, in the format "group.name".
  469        * </p>
  470        */
  471       public String getFullJobName() {
  472           return jobGroup + "." + jobName;
  473       }
  474   
  475       /**
  476        * <p>
  477        * Return the description given to the <code>Trigger</code> instance by
  478        * its creator (if any).
  479        * </p>
  480        * 
  481        * @return null if no description was set.
  482        */
  483       public String getDescription() {
  484           return description;
  485       }
  486   
  487       /**
  488        * <p>
  489        * Set a description for the <code>Trigger</code> instance - may be
  490        * useful for remembering/displaying the purpose of the trigger, though the
  491        * description has no meaning to Quartz.
  492        * </p>
  493        */
  494       public void setDescription(String description) {
  495           this.description = description;
  496       }
  497   
  498       /**
  499        * <p>
  500        * Set whether or not the <code>Trigger</code> should be persisted in the
  501        * <code>{@link org.quartz.spi.JobStore}</code> for re-use after program
  502        * restarts.
  503        * </p>
  504        */
  505       public void setVolatility(boolean volatility) {
  506           this.volatility = volatility;
  507       }
  508   
  509       /**
  510        * <p>
  511        * Associate the <code>{@link Calendar}</code> with the given name with
  512        * this Trigger.
  513        * </p>
  514        * 
  515        * @param calendarName
  516        *          use <code>null</code> to dis-associate a Calendar.
  517        */
  518       public void setCalendarName(String calendarName) {
  519           this.calendarName = calendarName;
  520       }
  521   
  522       /**
  523        * <p>
  524        * Get the name of the <code>{@link Calendar}</code> associated with this
  525        * Trigger.
  526        * </p>
  527        * 
  528        * @return <code>null</code> if there is no associated Calendar.
  529        */
  530       public String getCalendarName() {
  531           return calendarName;
  532       }
  533   
  534       /**
  535        * <p>
  536        * Get the <code>JobDataMap</code> that is associated with the 
  537        * <code>Trigger</code>.
  538        * </p>
  539        * 
  540        * <p>
  541        * Changes made to this map during job execution are not re-persisted, and
  542        * in fact typically result in an <code>IllegalStateException</code>.
  543        * </p>
  544        */
  545       public JobDataMap getJobDataMap() {
  546           if (jobDataMap == null) {
  547               jobDataMap = new JobDataMap();
  548           }
  549           return jobDataMap;
  550       }
  551   
  552   
  553       /**
  554        * <p>
  555        * Set the <code>JobDataMap</code> to be associated with the 
  556        * <code>Trigger</code>.
  557        * </p>
  558        */
  559       public void setJobDataMap(JobDataMap jobDataMap) {
  560           this.jobDataMap = jobDataMap;
  561       }
  562   
  563       /**
  564        * <p>
  565        * Whether or not the <code>Trigger</code> should be persisted in the
  566        * <code>{@link org.quartz.spi.JobStore}</code> for re-use after program
  567        * restarts.
  568        * </p>
  569        * 
  570        * <p>
  571        * If not explicitly set, the default value is <code>false</code>.
  572        * </p>
  573        * 
  574        * @return <code>true</code> if the <code>Trigger</code> should be
  575        *         garbage collected along with the <code>{@link Scheduler}</code>.
  576        */
  577       public boolean isVolatile() {
  578           return volatility;
  579       }
  580   
  581       /**
  582        * The priority of a <code>Trigger</code> acts as a tiebreaker such that if 
  583        * two <code>Trigger</code>s have the same scheduled fire time, then the
  584        * one with the higher priority will get first access to a worker
  585        * thread.
  586        * 
  587        * <p>
  588        * If not explicitly set, the default value is <code>5</code>.
  589        * </p>
  590        * 
  591        * @see #DEFAULT_PRIORITY
  592        */
  593       public int getPriority() {
  594           return priority;
  595       }
  596   
  597   
  598       /**
  599        * The priority of a <code>Trigger</code> acts as a tiebreaker such that if 
  600        * two <code>Trigger</code>s have the same scheduled fire time, then the
  601        * one with the higher priority will get first access to a worker
  602        * thread.
  603        * 
  604        * <p>
  605        * If not explicitly set, the default value is <code>5</code>.
  606        * </p>
  607        * 
  608        * @see #DEFAULT_PRIORITY
  609        */
  610       public void setPriority(int priority) {
  611           this.priority = priority;
  612       }
  613   
  614       /**
  615        * <p>
  616        * Add the specified name of a <code>{@link TriggerListener}</code> to
  617        * the end of the <code>Trigger</code>'s list of listeners.
  618        * </p>
  619        */
  620       public void addTriggerListener(String name) {
  621           if (triggerListeners.contains(name)) {
  622               throw new IllegalArgumentException(
  623                   "Trigger listener '" + name + "' is already registered for trigger: " + getFullName());
  624           }
  625   
  626           triggerListeners.add(name);
  627       }
  628   
  629       /**
  630        * <p>
  631        * Remove the specified name of a <code>{@link TriggerListener}</code>
  632        * from the <code>Trigger</code>'s list of listeners.
  633        * </p>
  634        * 
  635        * @return true if the given name was found in the list, and removed
  636        */
  637       public boolean removeTriggerListener(String name) {
  638           return triggerListeners.remove(name);
  639       }
  640   
  641       /**
  642        * <p>
  643        * Returns an array of <code>String</code>  containing the names of all
  644        * <code>{@link TriggerListener}</code>s assigned to the <code>Trigger</code>,
  645        * in the order in which they should be notified.
  646        * </p>
  647        */
  648       public String[] getTriggerListenerNames() {
  649           return (String[])triggerListeners.toArray(new String[triggerListeners.size()]);
  650       }
  651   
  652       /**
  653        * Remove all <code>{@link TriggerListener}</code>s from the <code>Trigger</code>.
  654        */
  655       public void clearAllTriggerListeners() {
  656           triggerListeners.clear();
  657       }
  658   
  659       /**
  660        * <p>
  661        * This method should not be used by the Quartz client.
  662        * </p>
  663        * 
  664        * <p>
  665        * Called when the <code>{@link Scheduler}</code> has decided to 'fire'
  666        * the trigger (execute the associated <code>Job</code>), in order to
  667        * give the <code>Trigger</code> a chance to update itself for its next
  668        * triggering (if any).
  669        * </p>
  670        * 
  671        * @see #executionComplete(JobExecutionContext, JobExecutionException)
  672        */
  673       public abstract void triggered(Calendar calendar);
  674   
  675       /**
  676        * <p>
  677        * This method should not be used by the Quartz client.
  678        * </p>
  679        * 
  680        * <p>
  681        * Called by the scheduler at the time a <code>Trigger</code> is first
  682        * added to the scheduler, in order to have the <code>Trigger</code>
  683        * compute its first fire time, based on any associated calendar.
  684        * </p>
  685        * 
  686        * <p>
  687        * After this method has been called, <code>getNextFireTime()</code>
  688        * should return a valid answer.
  689        * </p>
  690        * 
  691        * @return the first time at which the <code>Trigger</code> will be fired
  692        *         by the scheduler, which is also the same value <code>getNextFireTime()</code>
  693        *         will return (until after the first firing of the <code>Trigger</code>).
  694        *         </p>
  695        */
  696       public abstract Date computeFirstFireTime(Calendar calendar);
  697   
  698       /**
  699        * <p>
  700        * This method should not be used by the Quartz client.
  701        * </p>
  702        * 
  703        * <p>
  704        * Called after the <code>{@link Scheduler}</code> has executed the
  705        * <code>{@link org.quartz.JobDetail}</code> associated with the <code>Trigger</code>
  706        * in order to get the final instruction code from the trigger.
  707        * </p>
  708        * 
  709        * @param context
  710        *          is the <code>JobExecutionContext</code> that was used by the
  711        *          <code>Job</code>'s<code>execute(xx)</code> method.
  712        * @param result
  713        *          is the <code>JobExecutionException</code> thrown by the
  714        *          <code>Job</code>, if any (may be null).
  715        * @return one of the Trigger.INSTRUCTION_XXX constants.
  716        * 
  717        * @see #INSTRUCTION_NOOP
  718        * @see #INSTRUCTION_RE_EXECUTE_JOB
  719        * @see #INSTRUCTION_DELETE_TRIGGER
  720        * @see #INSTRUCTION_SET_TRIGGER_COMPLETE
  721        * @see #triggered(Calendar)
  722        */
  723       public abstract int executionComplete(JobExecutionContext context,
  724                                             JobExecutionException result);
  725   
  726       /**
  727        * <p>
  728        * Used by the <code>{@link Scheduler}</code> to determine whether or not
  729        * it is possible for this <code>Trigger</code> to fire again.
  730        * </p>
  731        * 
  732        * <p>
  733        * If the returned value is <code>false</code> then the <code>Scheduler</code>
  734        * may remove the <code>Trigger</code> from the <code>{@link org.quartz.spi.JobStore}</code>.
  735        * </p>
  736        */
  737       public abstract boolean mayFireAgain();
  738   
  739       /**
  740        * <p>
  741        * Get the time at which the <code>Trigger</code> should occur.
  742        * </p>
  743        */
  744       public abstract Date getStartTime();
  745   
  746       public abstract void setStartTime(Date startTime);
  747   
  748       public abstract void setEndTime(Date endTime);
  749   
  750       /**
  751        * <p>
  752        * Get the time at which the <code>Trigger</code> should quit repeating -
  753        * even if an assigned 'repeatCount' isn't yet satisfied.
  754        * </p>
  755        * 
  756        * @see #getFinalFireTime()
  757        */
  758       public abstract Date getEndTime();
  759   
  760       /**
  761        * <p>
  762        * Returns the next time at which the <code>Trigger</code> will fire. If
  763        * the trigger will not fire again, <code>null</code> will be returned.
  764        * The value returned is not guaranteed to be valid until after the <code>Trigger</code>
  765        * has been added to the scheduler.
  766        * </p>
  767        */
  768       public abstract Date getNextFireTime();
  769   
  770       /**
  771        * <p>
  772        * Returns the previous time at which the <code>Trigger</code> will fire.
  773        * If the trigger has not yet fired, <code>null</code> will be returned.
  774        */
  775       public abstract Date getPreviousFireTime();
  776   
  777       /**
  778        * <p>
  779        * Returns the next time at which the <code>Trigger</code> will fire,
  780        * after the given time. If the trigger will not fire after the given time,
  781        * <code>null</code> will be returned.
  782        * </p>
  783        */
  784       public abstract Date getFireTimeAfter(Date afterTime);
  785   
  786       /**
  787        * <p>
  788        * Returns the last time at which the <code>Trigger</code> will fire, if
  789        * the Trigger will repeat indefinitely, null will be returned.
  790        * </p>
  791        * 
  792        * <p>
  793        * Note that the return time *may* be in the past.
  794        * </p>
  795        */
  796       public abstract Date getFinalFireTime();
  797   
  798       /**
  799        * <p>
  800        * Set the instruction the <code>Scheduler</code> should be given for
  801        * handling misfire situations for this <code>Trigger</code>- the
  802        * concrete <code>Trigger</code> type that you are using will have
  803        * defined a set of additional <code>MISFIRE_INSTRUCTION_XXX</code>
  804        * constants that may be passed to this method.
  805        * </p>
  806        * 
  807        * <p>
  808        * If not explicitly set, the default value is <code>MISFIRE_INSTRUCTION_SMART_POLICY</code>.
  809        * </p>
  810        * 
  811        * @see #MISFIRE_INSTRUCTION_SMART_POLICY
  812        * @see #updateAfterMisfire(Calendar)
  813        * @see SimpleTrigger
  814        * @see CronTrigger
  815        */
  816       public void setMisfireInstruction(int misfireInstruction) {
  817           if (!validateMisfireInstruction(misfireInstruction)) {
  818               throw new IllegalArgumentException(
  819                           "The misfire instruction code is invalid for this type of trigger.");
  820           }
  821           this.misfireInstruction = misfireInstruction;
  822       }
  823   
  824       protected abstract boolean validateMisfireInstruction(int misfireInstruction);
  825   
  826       /**
  827        * <p>
  828        * Get the instruction the <code>Scheduler</code> should be given for
  829        * handling misfire situations for this <code>Trigger</code>- the
  830        * concrete <code>Trigger</code> type that you are using will have
  831        * defined a set of additional <code>MISFIRE_INSTRUCTION_XXX</code>
  832        * constants that may be passed to this method.
  833        * </p>
  834        * 
  835        * <p>
  836        * If not explicitly set, the default value is <code>MISFIRE_INSTRUCTION_SMART_POLICY</code>.
  837        * </p>
  838        * 
  839        * @see #MISFIRE_INSTRUCTION_SMART_POLICY
  840        * @see #updateAfterMisfire(Calendar)
  841        * @see SimpleTrigger
  842        * @see CronTrigger
  843        */
  844       public int getMisfireInstruction() {
  845           return misfireInstruction;
  846       }
  847   
  848       /**
  849        * <p>
  850        * This method should not be used by the Quartz client.
  851        * </p>
  852        * 
  853        * <p>
  854        * To be implemented by the concrete classes that extend this class.
  855        * </p>
  856        * 
  857        * <p>
  858        * The implementation should update the <code>Trigger</code>'s state
  859        * based on the MISFIRE_INSTRUCTION_XXX that was selected when the <code>Trigger</code>
  860        * was created.
  861        * </p>
  862        */
  863       public abstract void updateAfterMisfire(Calendar cal);
  864   
  865       /**
  866        * <p>
  867        * This method should not be used by the Quartz client.
  868        * </p>
  869        * 
  870        * <p>
  871        * To be implemented by the concrete class.
  872        * </p>
  873        * 
  874        * <p>
  875        * The implementation should update the <code>Trigger</code>'s state
  876        * based on the given new version of the associated <code>Calendar</code>
  877        * (the state should be updated so that it's next fire time is appropriate
  878        * given the Calendar's new settings). 
  879        * </p>
  880        * 
  881        * @param cal
  882        */
  883       public abstract void updateWithNewCalendar(Calendar cal, long misfireThreshold);
  884   
  885       /**
  886        * <p>
  887        * Validates whether the properties of the <code>JobDetail</code> are
  888        * valid for submission into a <code>Scheduler</code>.
  889        * 
  890        * @throws IllegalStateException
  891        *           if a required property (such as Name, Group, Class) is not
  892        *           set.
  893        */
  894       public void validate() throws SchedulerException {
  895           if (name == null) {
  896               throw new SchedulerException("Trigger's name cannot be null",
  897                           SchedulerException.ERR_CLIENT_ERROR);
  898           }
  899   
  900           if (group == null) {
  901               throw new SchedulerException("Trigger's group cannot be null",
  902                           SchedulerException.ERR_CLIENT_ERROR);
  903           }
  904   
  905           if (jobName == null) {
  906               throw new SchedulerException(
  907                           "Trigger's related Job's name cannot be null",
  908                           SchedulerException.ERR_CLIENT_ERROR);
  909           }
  910   
  911           if (jobGroup == null) {
  912               throw new SchedulerException(
  913                           "Trigger's related Job's group cannot be null",
  914                           SchedulerException.ERR_CLIENT_ERROR);
  915           }
  916       }
  917   
  918       /**
  919        * <p>
  920        * This method should not be used by the Quartz client.
  921        * </p>
  922        * 
  923        * <p>
  924        * Usable by <code>{@link org.quartz.spi.JobStore}</code>
  925        * implementations, in order to facilitate 'recognizing' instances of fired
  926        * <code>Trigger</code> s as their jobs complete execution.
  927        * </p>
  928        * 
  929        *  
  930        */
  931       public void setFireInstanceId(String id) {
  932           this.fireInstanceId = id;
  933       }
  934   
  935       /**
  936        * <p>
  937        * This method should not be used by the Quartz client.
  938        * </p>
  939        */
  940       public String getFireInstanceId() {
  941           return fireInstanceId;
  942       }
  943   
  944       /**
  945        * <p>
  946        * Return a simple string representation of this object.
  947        * </p>
  948        */
  949       public String toString() {
  950           return "Trigger '" + getFullName() + "':  triggerClass: '"
  951                   + getClass().getName() + " isVolatile: " + isVolatile()
  952                   + " calendar: '" + getCalendarName() + "' misfireInstruction: "
  953                   + getMisfireInstruction() + " nextFireTime: " + getNextFireTime();
  954       }
  955   
  956       /**
  957        * <p>
  958        * Compare the next fire time of this <code>Trigger</code> to that of
  959        * another.
  960        * </p>
  961        */
  962       public int compareTo(Object obj) {
  963           Trigger other = (Trigger) obj;
  964   
  965           Date myTime = getNextFireTime();
  966           Date otherTime = other.getNextFireTime();
  967   
  968           if (myTime == null && otherTime == null) {
  969               return 0;
  970           }
  971   
  972           if (myTime == null) {
  973               return 1;
  974           }
  975   
  976           if (otherTime == null) {
  977               return -1;
  978           }
  979   
  980           if(myTime.before(otherTime)) {
  981               return -1;
  982           }
  983   
  984           if(myTime.after(otherTime)) {
  985               return 1;
  986           }
  987   
  988           return 0;
  989       }
  990   
  991       public boolean equals(Object obj) {
  992           if (!(obj instanceof Trigger)) {
  993               return false;
  994           }
  995   
  996           Trigger other = (Trigger) obj;
  997   
  998           if (!other.getName().equals(getName())) {
  999               return false;
 1000           }
 1001           if (!other.getGroup().equals(getGroup())) {
 1002               return false;
 1003           }
 1004   
 1005           return true;
 1006       }
 1007   
 1008   
 1009       public int hashCode() {
 1010           return getFullName().hashCode();
 1011       }
 1012   
 1013       public Object clone() {
 1014           Trigger copy;
 1015           try {
 1016               copy = (Trigger) super.clone();
 1017   
 1018               copy.triggerListeners = (LinkedList)triggerListeners.clone();
 1019   
 1020               // Shallow copy the jobDataMap.  Note that this means that if a user
 1021               // modifies a value object in this map from the cloned Trigger
 1022               // they will also be modifying this Trigger. 
 1023               if (jobDataMap != null) {
 1024                   copy.jobDataMap = (JobDataMap)jobDataMap.clone();
 1025               }
 1026   
 1027           } catch (CloneNotSupportedException ex) {
 1028               throw new IncompatibleClassChangeError("Not Cloneable.");
 1029           }
 1030           return copy;
 1031       }
 1032   }

Home » quartz-1.6.0 » org » quartz » [javadoc | source]