All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.quartz.Trigger Maven / Gradle / Ivy

Go to download

SDK for dev_appserver (local development) with some of the dependencies shaded (repackaged)

There is a newer version: 2.0.31
Show newest version

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

/*
 * Previously Copyright (c) 2001-2004 James House
 */
package org.quartz;

import java.util.Date;
import java.util.LinkedList;


/**
 * 

* The base abstract class to be extended by all Triggers. *

* *

* Triggers s have a name and group associated with them, which * should uniquely identify them within a single {@link Scheduler}. *

* *

* Triggers are the 'mechanism' by which Job s * are scheduled. Many Trigger s can point to the same Job, * but a single Trigger can only point to one Job. *

* *

* Triggers can 'send' parameters/data to Jobs by placing contents * into the JobDataMap on the Trigger. *

* * @see SimpleTrigger * @see CronTrigger * @see NthIncludedDayTrigger * @see TriggerUtils * @see JobDataMap * @see JobExecutionContext * * @author James House * @author Sharada Jambula */ public abstract class Trigger implements java.io.Serializable, Cloneable, Comparable { private static final long serialVersionUID = -3904243490805975570L; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constants. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Instructs the {@link Scheduler} that the {@link Trigger} * has no further instructions. *

*/ public static final int INSTRUCTION_NOOP = 0; /** *

* Instructs the {@link Scheduler} that the {@link Trigger} * wants the {@link org.quartz.JobDetail} to re-execute * immediately. If not in a 'RECOVERING' or 'FAILED_OVER' situation, the * execution context will be re-used (giving the Job the * abilitiy to 'see' anything placed in the context by its last execution). *

*/ public static final int INSTRUCTION_RE_EXECUTE_JOB = 1; /** *

* Instructs the {@link Scheduler} that the {@link Trigger} * should be put in the COMPLETE state. *

*/ public static final int INSTRUCTION_SET_TRIGGER_COMPLETE = 2; /** *

* Instructs the {@link Scheduler} that the {@link Trigger} * wants itself deleted. *

*/ public static final int INSTRUCTION_DELETE_TRIGGER = 3; /** *

* Instructs the {@link Scheduler} that all Trigger * s referencing the same {@link org.quartz.JobDetail} as * this one should be put in the COMPLETE state. *

*/ public static final int INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE = 4; /** *

* Instructs the {@link Scheduler} that all Trigger * s referencing the same {@link org.quartz.JobDetail} as * this one should be put in the ERROR state. *

*/ public static final int INSTRUCTION_SET_TRIGGER_ERROR = 5; /** *

* Instructs the {@link Scheduler} that the Trigger * should be put in the ERROR state. *

*/ public static final int INSTRUCTION_SET_ALL_JOB_TRIGGERS_ERROR = 6; /** *

* Instructs the {@link Scheduler} that upon a mis-fire * situation, the updateAfterMisfire() method will be called * on the Trigger to determine the mis-fire instruction. *

* *

* In order to see if this instruction fits your needs, you should look at * the documentation for the getSmartMisfirePolicy() method * on the particular Trigger implementation you are using. *

*/ public static final int MISFIRE_INSTRUCTION_SMART_POLICY = 0; /** *

* Indicates that the Trigger is in the "normal" state. *

*/ public final static int STATE_NORMAL = 0; /** *

* Indicates that the Trigger is in the "paused" state. *

*/ public final static int STATE_PAUSED = 1; /** *

* Indicates that the Trigger is in the "complete" state. *

* *

* "Complete" indicates that the trigger has not remaining fire-times in * its schedule. *

*/ public final static int STATE_COMPLETE = 2; /** *

* Indicates that the Trigger is in the "error" state. *

* *

* A Trigger arrives at the error state when the scheduler * attempts to fire it, but cannot due to an error creating and executing * its related job. Often this is due to the Job's * class not existing in the classpath. *

* *

* When the trigger is in the error state, the scheduler will make no * attempts to fire it. *

*/ public final static int STATE_ERROR = 3; /** *

* Indicates that the Trigger is in the "blocked" state. *

* *

* A Trigger arrives at the blocked state when the job that * it is associated with is a StatefulJob and it is * currently executing. *

* * @see StatefulJob */ public final static int STATE_BLOCKED = 4; /** *

* Indicates that the Trigger does not exist. *

*/ public final static int STATE_NONE = -1; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Data members. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ private String name; private String group = Scheduler.DEFAULT_GROUP; private String jobName; private String jobGroup = Scheduler.DEFAULT_GROUP; private String description; private JobDataMap jobDataMap; private boolean volatility = false; private String calendarName = null; private String fireInstanceId = null; private int misfireInstruction = MISFIRE_INSTRUCTION_SMART_POLICY; private LinkedList triggerListeners = new LinkedList(); /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constructors. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Create a Trigger with no specified name, group, or {@link org.quartz.JobDetail}. *

* *

* Note that the {@link #setName(String)},{@link #setGroup(String)}and * the {@link #setJobName(String)}and {@link #setJobGroup(String)}methods * must be called before the Trigger can be placed into a * {@link Scheduler}. *

*/ public Trigger() { // do nothing... } /** *

* Create a Trigger with the given name, and group. *

* *

* Note that the {@link #setJobName(String)}and * {@link #setJobGroup(String)}methods must be called before the Trigger * can be placed into a {@link Scheduler}. *

* * @param group if null, Scheduler.DEFAULT_GROUP will be used. * * @exception IllegalArgumentException * if name is null or empty, or the group is an empty string. */ public Trigger(String name, String group) { setName(name); setGroup(group); } /** *

* Create a Trigger with the given name, and group. *

* * @param group if null, Scheduler.DEFAULT_GROUP will be used. * * @exception IllegalArgumentException * if name is null or empty, or the group is an empty string. */ public Trigger(String name, String group, String jobName, String jobGroup) { setName(name); setGroup(group); setJobName(jobName); setJobGroup(jobGroup); } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Get the name of this Trigger. *

*/ public String getName() { return name; } /** *

* Set the name of this Trigger. *

* * @exception IllegalArgumentException * if name is null or empty. */ public void setName(String name) { if (name == null || name.trim().length() == 0) throw new IllegalArgumentException( "Trigger name cannot be null or empty."); this.name = name; } /** *

* Get the group of this Trigger. *

*/ public String getGroup() { return group; } /** *

* Set the name of this Trigger. *

* * @param group if null, Scheduler.DEFAULT_GROUP will be used. * * @exception IllegalArgumentException * if group is an empty string. */ public void setGroup(String group) { if (group != null && group.trim().length() == 0) throw new IllegalArgumentException( "Group name cannot be an empty string."); if(group == null) group = Scheduler.DEFAULT_GROUP; this.group = group; } /** *

* Get the name of the associated {@link org.quartz.JobDetail}. *

*/ public String getJobName() { return jobName; } /** *

* Set the name of the associated {@link org.quartz.JobDetail}. *

* * @exception IllegalArgumentException * if jobName is null or empty. */ public void setJobName(String jobName) { if (jobName == null || jobName.trim().length() == 0) throw new IllegalArgumentException( "Job name cannot be null or empty."); this.jobName = jobName; } /** *

* Get the name of the associated {@link org.quartz.JobDetail}'s * group. *

*/ public String getJobGroup() { return jobGroup; } /** *

* Set the name of the associated {@link org.quartz.JobDetail}'s * group. *

* * @param group if null, Scheduler.DEFAULT_GROUP will be used. * * @exception IllegalArgumentException * if group is an empty string. */ public void setJobGroup(String jobGroup) { if (jobGroup != null && jobGroup.trim().length() == 0) throw new IllegalArgumentException( "Group name cannot be null or empty."); if(jobGroup == null) jobGroup = Scheduler.DEFAULT_GROUP; this.jobGroup = jobGroup; } /** *

* Returns the 'full name' of the Trigger in the format * "group.name". *

*/ public String getFullName() { return group + "." + name; } /** *

* Returns the 'full name' of the Job that the Trigger * points to, in the format "group.name". *

*/ public String getFullJobName() { return jobGroup + "." + jobName; } /** *

* Return the description given to the Trigger instance by * its creator (if any). *

* * @return null if no description was set. */ public String getDescription() { return description; } /** *

* Set a description for the Trigger instance - may be * useful for remembering/displaying the purpose of the trigger, though the * description has no meaning to Quartz. *

*/ public void setDescription(String description) { this.description = description; } /** *

* Set whether or not the Trigger should be persisted in the * {@link org.quartz.spi.JobStore} for re-use after program * restarts. *

*/ public void setVolatility(boolean volatility) { this.volatility = volatility; } /** *

* Associate the {@link Calendar} with the given name with * this Trigger. *

* * @param calendarName * use null to dis-associate a Calendar. */ public void setCalendarName(String calendarName) { this.calendarName = calendarName; } /** *

* Get the name of the {@link Calendar} associated with this * Trigger. *

* * @return null if there is no associated Calendar. */ public String getCalendarName() { return calendarName; } /** *

* Get the JobDataMap that is associated with the * Trigger. *

* *

* Changes made to this map during job execution are not re-persisted, and * in fact typically result in an IllegalStateException. *

*/ public JobDataMap getJobDataMap() { if (jobDataMap == null) jobDataMap = new JobDataMap(); return jobDataMap; } /** *

* Set the JobDataMap to be associated with the * Trigger. *

*/ public void setJobDataMap(JobDataMap jobDataMap) { this.jobDataMap = jobDataMap; } /** *

* Whether or not the Trigger should be persisted in the * {@link org.quartz.spi.JobStore} for re-use after program * restarts. *

* *

* If not explicitly set, the default value is false. *

* * @return true if the Trigger should be * garbage collected along with the {@link Scheduler}. */ public boolean isVolatile() { return volatility; } /** *

* Add the specified name of a {@link TriggerListener} to * the end of the Trigger's list of listeners. *

*/ public void addTriggerListener(String name) { triggerListeners.add(name); } /** *

* Remove the specified name of a {@link TriggerListener} * from the Trigger's list of listeners. *

* * @return true if the given name was found in the list, and removed */ public boolean removeTriggerListener(String name) { return triggerListeners.remove(name); } /** *

* Returns an array of String s containing the names of all * {@link TriggerListener} assigned to the Trigger, * in the order in which they should be notified. *

*/ public String[] getTriggerListenerNames() { String[] outNames = new String[triggerListeners.size()]; return (String[]) triggerListeners.toArray(outNames); } /** *

* This method should not be used by the Quartz client. *

* *

* Called when the {@link Scheduler} has decided to 'fire' * the trigger (execute the associated Job), in order to * give the Trigger a chance to update itself for its next * triggering (if any). *

* * @see #executionComplete(JobExecutionContext, JobExecutionException) */ public abstract void triggered(Calendar calendar); /** *

* This method should not be used by the Quartz client. *

* *

* Called by the scheduler at the time a Trigger is first * added to the scheduler, in order to have the Trigger * compute its first fire time, based on any associated calendar. *

* *

* After this method has been called, getNextFireTime() * should return a valid answer. *

* * @return the first time at which the Trigger will be fired * by the scheduler, which is also the same value getNextFireTime() * will return (until after the first firing of the Trigger). *

*/ public abstract Date computeFirstFireTime(Calendar calendar); /** *

* This method should not be used by the Quartz client. *

* *

* Called after the {@link Scheduler} has executed the * {@link org.quartz.JobDetail} associated with the Trigger * in order to get the final instruction code from the trigger. *

* * @param context * is the JobExecutionContext that was used by the * Job'sexecute(xx) method. * @param result * is the JobExecutionException thrown by the * Job, if any (may be null). * @return one of the Trigger.INSTRUCTION_XXX constants. * * @see #INSTRUCTION_NOOP * @see #INSTRUCTION_RE_EXECUTE_JOB * @see #INSTRUCTION_DELETE_TRIGGER * @see #INSTRUCTION_SET_TRIGGER_COMPLETE * @see #triggered(Calendar) */ public abstract int executionComplete(JobExecutionContext context, JobExecutionException result); /** *

* Used by the {@link Scheduler} to determine whether or not * it is possible for this Trigger to fire again. *

* *

* If the returned value is false then the Scheduler * may remove the Trigger from the {@link org.quartz.spi.JobStore}. *

*/ public abstract boolean mayFireAgain(); /** *

* Get the time at which the Trigger should occur. *

*/ public abstract Date getStartTime(); public abstract void setStartTime(Date startTime); public abstract void setEndTime(Date endTime); /** *

* Get the time at which the Trigger should quit repeating - * even if an assigned 'repeatCount' isn't yet satisfied. *

* * @see #getFinalFireTime() */ public abstract Date getEndTime(); /** *

* Returns the next time at which the Trigger will fire. If * the trigger will not fire again, null will be returned. * The value returned is not guaranteed to be valid until after the Trigger * has been added to the scheduler. *

*/ public abstract Date getNextFireTime(); /** *

* Returns the previous time at which the Trigger will fire. * If the trigger has not yet fired, null will be returned. */ public abstract Date getPreviousFireTime(); /** *

* Returns the next time at which the Trigger will fire, * after the given time. If the trigger will not fire after the given time, * null will be returned. *

*/ public abstract Date getFireTimeAfter(Date afterTime); /** *

* Returns the last time at which the Trigger will fire, if * the Trigger will repeat indefinitely, null will be returned. *

* *

* Note that the return time *may* be in the past. *

*/ public abstract Date getFinalFireTime(); /** *

* Set the instruction the Scheduler should be given for * handling misfire situations for this Trigger- the * concrete Trigger type that you are using will have * defined a set of additional MISFIRE_INSTRUCTION_XXX * constants that may be passed to this method. *

* *

* If not explicitly set, the default value is MISFIRE_INSTRUCTION_SMART_POLICY. *

* * @see #MISFIRE_INSTRUCTION_SMART_POLICY * @see #updateAfterMisfire(Calendar) * @see SimpleTrigger * @see CronTrigger */ public void setMisfireInstruction(int misfireInstruction) { if (!validateMisfireInstruction(misfireInstruction)) throw new IllegalArgumentException( "The misfire instruction code is invalid for this type of trigger."); this.misfireInstruction = misfireInstruction; } protected abstract boolean validateMisfireInstruction(int misfireInstruction); /** *

* Get the instruction the Scheduler should be given for * handling misfire situations for this Trigger- the * concrete Trigger type that you are using will have * defined a set of additional MISFIRE_INSTRUCTION_XXX * constants that may be passed to this method. *

* *

* If not explicitly set, the default value is MISFIRE_INSTRUCTION_SMART_POLICY. *

* * @see #MISFIRE_INSTRUCTION_SMART_POLICY * @see #updateAfterMisfire(Calendar) * @see SimpleTrigger * @see CronTrigger */ public int getMisfireInstruction() { return misfireInstruction; } /** *

* This method should not be used by the Quartz client. *

* *

* To be implemented by the concrete classes that extend this class. *

* *

* The implementation should update the Trigger's state * based on the MISFIRE_INSTRUCTION_XXX that was selected when the Trigger * was created. *

*/ public abstract void updateAfterMisfire(Calendar cal); /** *

* This method should not be used by the Quartz client. *

* *

* To be implemented by the concrete class. *

* *

* The implementation should update the Trigger's state * based on the given new version of the associated Calendar * (the state should be updated so that it's next fire time is appropriate * given the Calendar's new settings). *

* * @param cal */ public abstract void updateWithNewCalendar(Calendar cal, long misfireThreshold); /** *

* Validates whether the properties of the JobDetail are * valid for submission into a Scheduler. * * @throws IllegalStateException * if a required property (such as Name, Group, Class) is not * set. */ public void validate() throws SchedulerException { if (name == null) throw new SchedulerException("Trigger's name cannot be null", SchedulerException.ERR_CLIENT_ERROR); if (group == null) throw new SchedulerException("Trigger's group cannot be null", SchedulerException.ERR_CLIENT_ERROR); if (jobName == null) throw new SchedulerException( "Trigger's related Job's name cannot be null", SchedulerException.ERR_CLIENT_ERROR); if (jobGroup == null) throw new SchedulerException( "Trigger's related Job's group cannot be null", SchedulerException.ERR_CLIENT_ERROR); } /** *

* This method should not be used by the Quartz client. *

* *

* Usable by {@link org.quartz.spi.JobStore} * implementations, in order to facilitate 'recognizing' instances of fired * Trigger s as their jobs complete execution. *

* * */ public void setFireInstanceId(String id) { this.fireInstanceId = id; } /** *

* This method should not be used by the Quartz client. *

*/ public String getFireInstanceId() { return fireInstanceId; } /** *

* Return a simple string representation of this object. *

*/ public String toString() { return "Trigger '" + getFullName() + "': triggerClass: '" + getClass().getName() + " isVolatile: " + isVolatile() + " calendar: '" + getCalendarName() + "' misfireInstruction: " + getMisfireInstruction() + " nextFireTime: " + getNextFireTime(); } /** *

* Compare the next fire time of this Trigger to that of * another. *

*/ public int compareTo(Object obj) { Trigger other = (Trigger) obj; Date myTime = getNextFireTime(); Date otherTime = other.getNextFireTime(); if (myTime == null && otherTime == null) return 0; if (myTime == null) return 1; if (otherTime == null) return -1; if(myTime.before(otherTime)) return -1; if(myTime.after(otherTime)) return 1; return 0; } public boolean equals(Object obj) { if (!(obj instanceof Trigger)) return false; Trigger other = (Trigger) obj; if (!other.getName().equals(getName())) return false; if (!other.getGroup().equals(getGroup())) return false; return true; } public int hashCode() { return getFullName().hashCode(); } public Object clone() { Trigger copy; try { copy = (Trigger) super.clone(); } catch (CloneNotSupportedException ex) { throw new IncompatibleClassChangeError("Not Cloneable."); } return copy; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy