Index: 3rdParty_sources/quartz/org/quartz/Calendar.java =================================================================== diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b --- 3rdParty_sources/quartz/org/quartz/Calendar.java (.../Calendar.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff) +++ 3rdParty_sources/quartz/org/quartz/Calendar.java (.../Calendar.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b) @@ -1,6 +1,6 @@ /* - * Copyright 2004-2005 OpenSymphony + * Copyright 2001-2009 Terracotta, Inc. * * 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 @@ -16,24 +16,29 @@ * */ -/* - * Previously Copyright (c) 2001-2004 James House - */ - - package org.quartz; /** - *
- * An interface to be implemented by objects that define spaces of time that
- * should be included or excluded from a {@link Trigger}'s
- * normal 'firing' schedule.
- *
{@link Trigger} may (not) fire. Calendars
+ * do not define actual fire times, but rather are used to limit a
+ * Trigger from firing on its normal schedule if necessary. Most
+ * Calendars include all times by default and allow the user to specify times
+ * to exclude.
*
+ * As such, it is often useful to think of Calendars as being used to exclude a block
+ * of time - as opposed to include a block of time. (i.e. the
+ * schedule "fire every five minutes except on Sundays" could be
+ * implemented with a SimpleTrigger and a
+ * WeeklyCalendar which excludes Sundays)
Implementations MUST take care of being properly Cloneable
+ * and Serializable.
* Get the base calendar. Will be null, if not set. *
*/ - public Calendar getBaseCalendar(); + Calendar getBaseCalendar(); /** ** Determine whether the given time (in milliseconds) is 'included' by the * Calendar. *
*/ - public boolean isTimeIncluded(long timeStamp); + boolean isTimeIncluded(long timeStamp); /** ** Determine the next time (in milliseconds) that is 'included' by the * Calendar after the given time. *
*/ - public long getNextIncludedTime(long timeStamp); + long getNextIncludedTime(long timeStamp); /** *@@ -91,7 +96,7 @@ * * @return null if no description was set. */ - public String getDescription(); + String getDescription(); /** *
@@ -100,5 +105,7 @@ * the description has no meaning to Quartz. *
*/ - public void setDescription(String description); + void setDescription(String description); + + Object clone(); } Index: 3rdParty_sources/quartz/org/quartz/CalendarIntervalScheduleBuilder.java =================================================================== diff -u --- 3rdParty_sources/quartz/org/quartz/CalendarIntervalScheduleBuilder.java (revision 0) +++ 3rdParty_sources/quartz/org/quartz/CalendarIntervalScheduleBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b) @@ -0,0 +1,339 @@ +/* + * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved. + * + * 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. + * + */ + +package org.quartz; + +import java.util.TimeZone; + +import org.quartz.DateBuilder.IntervalUnit; +import org.quartz.impl.triggers.CalendarIntervalTriggerImpl; +import org.quartz.spi.MutableTrigger; + +/** + *CalendarIntervalScheduleBuilder is a {@link ScheduleBuilder}
+ * that defines calendar time (day, week, month, year) interval-based
+ * schedules for Triggers.
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(withIntervalInDays(3))
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ * @see DailyTimeIntervalScheduleBuilder
+ * @see CronScheduleBuilder
+ * @see ScheduleBuilder
+ * @see SimpleScheduleBuilder
+ * @see TriggerBuilder
+ */
+public class CalendarIntervalScheduleBuilder extends ScheduleBuilder {
+
+ private int interval = 1;
+ private IntervalUnit intervalUnit = IntervalUnit.DAY;
+
+ private int misfireInstruction = CalendarIntervalTrigger.MISFIRE_INSTRUCTION_SMART_POLICY;
+ private TimeZone timeZone;
+ private boolean preserveHourOfDayAcrossDaylightSavings;
+ private boolean skipDayIfHourDoesNotExist;
+
+ protected CalendarIntervalScheduleBuilder() {
+ }
+
+ /**
+ * Create a CalendarIntervalScheduleBuilder.
+ *
+ * @return the new CalendarIntervalScheduleBuilder
+ */
+ public static CalendarIntervalScheduleBuilder calendarIntervalSchedule() {
+ return new CalendarIntervalScheduleBuilder();
+ }
+
+ /**
+ * Build the actual Trigger -- NOT intended to be invoked by end users,
+ * but will rather be invoked by a TriggerBuilder which this
+ * ScheduleBuilder is given to.
+ *
+ * @see TriggerBuilder#withSchedule(ScheduleBuilder)
+ */
+ @Override
+ public MutableTrigger build() {
+
+ CalendarIntervalTriggerImpl st = new CalendarIntervalTriggerImpl();
+ st.setRepeatInterval(interval);
+ st.setRepeatIntervalUnit(intervalUnit);
+ st.setMisfireInstruction(misfireInstruction);
+ st.setTimeZone(timeZone);
+ st.setPreserveHourOfDayAcrossDaylightSavings(preserveHourOfDayAcrossDaylightSavings);
+ st.setSkipDayIfHourDoesNotExist(skipDayIfHourDoesNotExist);
+
+ return st;
+ }
+
+ /**
+ * Specify the time unit and interval for the Trigger to be produced.
+ *
+ * @param timeInterval the interval at which the trigger should repeat.
+ * @param unit the time unit (IntervalUnit) of the interval.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withInterval(int timeInterval, IntervalUnit unit) {
+ if(unit == null)
+ throw new IllegalArgumentException("TimeUnit must be specified.");
+ validateInterval(timeInterval);
+ this.interval = timeInterval;
+ this.intervalUnit = unit;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.SECOND that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInSeconds the number of seconds at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInSeconds(int intervalInSeconds) {
+ validateInterval(intervalInSeconds);
+ this.interval = intervalInSeconds;
+ this.intervalUnit = IntervalUnit.SECOND;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.MINUTE that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInMinutes the number of minutes at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInMinutes(int intervalInMinutes) {
+ validateInterval(intervalInMinutes);
+ this.interval = intervalInMinutes;
+ this.intervalUnit = IntervalUnit.MINUTE;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.HOUR that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInHours the number of hours at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInHours(int intervalInHours) {
+ validateInterval(intervalInHours);
+ this.interval = intervalInHours;
+ this.intervalUnit = IntervalUnit.HOUR;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.DAY that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInDays the number of days at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInDays(int intervalInDays) {
+ validateInterval(intervalInDays);
+ this.interval = intervalInDays;
+ this.intervalUnit = IntervalUnit.DAY;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.WEEK that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInWeeks the number of weeks at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInWeeks(int intervalInWeeks) {
+ validateInterval(intervalInWeeks);
+ this.interval = intervalInWeeks;
+ this.intervalUnit = IntervalUnit.WEEK;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.MONTH that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInMonths the number of months at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInMonths(int intervalInMonths) {
+ validateInterval(intervalInMonths);
+ this.interval = intervalInMonths;
+ this.intervalUnit = IntervalUnit.MONTH;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.YEAR that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInYears the number of years at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getRepeatInterval()
+ * @see CalendarIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public CalendarIntervalScheduleBuilder withIntervalInYears(int intervalInYears) {
+ validateInterval(intervalInYears);
+ this.interval = intervalInYears;
+ this.intervalUnit = IntervalUnit.YEAR;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY} instruction.
+ *
+ * @return the updated CronScheduleBuilder
+ * @see Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
+ */
+ public CalendarIntervalScheduleBuilder withMisfireHandlingInstructionIgnoreMisfires() {
+ misfireInstruction = Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link CalendarIntervalTrigger#MISFIRE_INSTRUCTION_DO_NOTHING} instruction.
+ *
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#MISFIRE_INSTRUCTION_DO_NOTHING
+ */
+ public CalendarIntervalScheduleBuilder withMisfireHandlingInstructionDoNothing() {
+ misfireInstruction = CalendarIntervalTrigger.MISFIRE_INSTRUCTION_DO_NOTHING;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link CalendarIntervalTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW} instruction.
+ *
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
+ */
+ public CalendarIntervalScheduleBuilder withMisfireHandlingInstructionFireAndProceed() {
+ misfireInstruction = CalendarIntervalTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW;
+ return this;
+ }
+ /**
+ * The TimeZone in which to base the schedule.
+ *
+ * @param timezone the time-zone for the schedule.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see CalendarIntervalTrigger#getTimeZone()
+ */
+ public CalendarIntervalScheduleBuilder inTimeZone(TimeZone timezone) {
+ this.timeZone = timezone;
+ return this;
+ }
+
+ /**
+ * If intervals are a day or greater, this property (set to true) will
+ * cause the firing of the trigger to always occur at the same time of day,
+ * (the time of day of the startTime) regardless of daylight saving time
+ * transitions. Default value is false.
+ *
+ *
+ * For example, without the property set, your trigger may have a start
+ * time of 9:00 am on March 1st, and a repeat interval of 2 days. But
+ * after the daylight saving transition occurs, the trigger may start
+ * firing at 8:00 am every other day.
+ *
+ *
+ *
+ * If however, the time of day does not exist on a given day to fire
+ * (e.g. 2:00 am in the United States on the days of daylight saving
+ * transition), the trigger will go ahead and fire one hour off on
+ * that day, and then resume the normal hour on other days. If
+ * you wish for the trigger to never fire at the "wrong" hour, then
+ * you should set the property skipDayIfHourDoesNotExist.
+ *
+ *
+ * @see #skipDayIfHourDoesNotExist(boolean)
+ * @see #inTimeZone(TimeZone)
+ * @see TriggerBuilder#startAt(java.util.Date)
+ */
+ public CalendarIntervalScheduleBuilder preserveHourOfDayAcrossDaylightSavings(boolean preserveHourOfDay) {
+ this.preserveHourOfDayAcrossDaylightSavings = preserveHourOfDay;
+ return this;
+ }
+
+ /**
+ * If intervals are a day or greater, and
+ * preserveHourOfDayAcrossDaylightSavings property is set to true, and the
+ * hour of the day does not exist on a given day for which the trigger
+ * would fire, the day will be skipped and the trigger advanced a second
+ * interval if this property is set to true. Defaults to false.
+ *
+ *
+ * CAUTION! If you enable this property, and your hour of day happens
+ * to be that of daylight savings transition (e.g. 2:00 am in the United
+ * States) and the trigger's interval would have had the trigger fire on
+ * that day, then you may actually completely miss a firing on the day of
+ * transition if that hour of day does not exist on that day! In such a
+ * case the next fire time of the trigger will be computed as double (if
+ * the interval is 2 days, then a span of 4 days between firings will
+ * occur).
+ *
+ *
+ * @see #preserveHourOfDayAcrossDaylightSavings(boolean)
+ */
+ public CalendarIntervalScheduleBuilder skipDayIfHourDoesNotExist(boolean skipDay) {
+ this.skipDayIfHourDoesNotExist = skipDay;
+ return this;
+ }
+
+ private void validateInterval(int timeInterval) {
+ if(timeInterval <= 0)
+ throw new IllegalArgumentException("Interval must be a positive value.");
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/CalendarIntervalTrigger.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/CalendarIntervalTrigger.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/CalendarIntervalTrigger.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,159 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import org.quartz.DateBuilder.IntervalUnit;
+
+/**
+ * A concrete {@link Trigger} that is used to fire a {@link org.quartz.JobDetail}
+ * based upon repeating calendar time intervals.
+ *
+ * The trigger will fire every N (see {@link #getRepeatInterval()} ) units of calendar time
+ * (see {@link #getRepeatIntervalUnit()}) as specified in the trigger's definition.
+ * This trigger can achieve schedules that are not possible with {@link SimpleTrigger} (e.g
+ * because months are not a fixed number of seconds) or {@link CronTrigger} (e.g. because
+ * "every 5 months" is not an even divisor of 12).
+ *
+ * If you use an interval unit of MONTH then care should be taken when setting
+ * a startTime value that is on a day near the end of the month. For example,
+ * if you choose a start time that occurs on January 31st, and have a trigger with unit
+ * MONTH and interval 1, then the next fire time will be February 28th,
+ * and the next time after that will be March 28th - and essentially each subsequent firing will
+ * occur on the 28th of the month, even if a 31st day exists. If you want a trigger that always
+ * fires on the last day of the month - regardless of the number of days in the month,
+ * you should use CronTrigger.
+ *
+ * @see TriggerBuilder
+ * @see CalendarIntervalScheduleBuilder
+ * @see SimpleScheduleBuilder
+ * @see CronScheduleBuilder
+ *
+ * @author James House
+ */
+public interface CalendarIntervalTrigger extends Trigger {
+
+ /**
+ *
+ * Instructs the {@link Scheduler} that upon a mis-fire
+ * situation, the {@link CalendarIntervalTrigger} wants to be
+ * fired now by Scheduler.
+ *
+ */
+ public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
+ /**
+ *
+ * Instructs the {@link Scheduler} that upon a mis-fire
+ * situation, the {@link CalendarIntervalTrigger} wants to have it's
+ * next-fire-time updated to the next time in the schedule after the
+ * current time (taking into account any associated {@link Calendar},
+ * but it does not want to be fired now.
+ *
+ */
+ public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
+
+ /**
+ * Get the interval unit - the time unit on with the interval applies.
+ */
+ public IntervalUnit getRepeatIntervalUnit();
+
+ /**
+ *
+ * Get the the time interval that will be added to the DateIntervalTrigger's
+ * fire time (in the set repeat interval unit) in order to calculate the time of the
+ * next trigger repeat.
+ *
+ */
+ public int getRepeatInterval();
+
+ /**
+ *
+ * Get the number of times the DateIntervalTrigger has already
+ * fired.
+ *
+ */
+ public int getTimesTriggered();
+
+ /**
+ *
+ * Gets the time zone within which time calculations related to this
+ * trigger will be performed.
+ *
+ *
+ *
+ * If null, the system default TimeZone will be used.
+ *
+ */
+ public TimeZone getTimeZone();
+
+
+ /**
+ * If intervals are a day or greater, this property (set to true) will
+ * cause the firing of the trigger to always occur at the same time of day,
+ * (the time of day of the startTime) regardless of daylight saving time
+ * transitions. Default value is false.
+ *
+ *
+ * For example, without the property set, your trigger may have a start
+ * time of 9:00 am on March 1st, and a repeat interval of 2 days. But
+ * after the daylight saving transition occurs, the trigger may start
+ * firing at 8:00 am every other day.
+ *
+ *
+ *
+ * If however, the time of day does not exist on a given day to fire
+ * (e.g. 2:00 am in the United States on the days of daylight saving
+ * transition), the trigger will go ahead and fire one hour off on
+ * that day, and then resume the normal hour on other days. If
+ * you wish for the trigger to never fire at the "wrong" hour, then
+ * you should set the property skipDayIfHourDoesNotExist.
+ *
+ *
+ * @see #isSkipDayIfHourDoesNotExist()
+ * @see #getStartTime()
+ * @see #getTimeZone()
+ */
+ public boolean isPreserveHourOfDayAcrossDaylightSavings();
+
+ /**
+ * If intervals are a day or greater, and
+ * preserveHourOfDayAcrossDaylightSavings property is set to true, and the
+ * hour of the day does not exist on a given day for which the trigger
+ * would fire, the day will be skipped and the trigger advanced a second
+ * interval if this property is set to true. Defaults to false.
+ *
+ *
+ * CAUTION! If you enable this property, and your hour of day happens
+ * to be that of daylight savings transition (e.g. 2:00 am in the United
+ * States) and the trigger's interval would have had the trigger fire on
+ * that day, then you may actually completely miss a firing on the day of
+ * transition if that hour of day does not exist on that day! In such a
+ * case the next fire time of the trigger will be computed as double (if
+ * the interval is 2 days, then a span of 4 days between firings will
+ * occur).
+ *
+ *
+ * @see #isPreserveHourOfDayAcrossDaylightSavings()
+ */
+ public boolean isSkipDayIfHourDoesNotExist();
+
+
+ TriggerBuilder getTriggerBuilder();
+}
Fisheye: Tag c208628989d52041b3765784f4c8cbfd6c80d47b refers to a dead (removed) revision in file `3rdParty_sources/quartz/org/quartz/CriticalSchedulerException.java'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/quartz/org/quartz/CronExpression.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/CronExpression.java (.../CronExpression.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/CronExpression.java (.../CronExpression.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,3 +1,20 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
package org.quartz;
import java.io.Serializable;
@@ -56,7 +73,7 @@
*
* 1-31
*
- * , - * ? / L W C
+ * , - * ? / L W
*
*
* Month
@@ -75,7 +92,7 @@
*
* Year (Optional)
*
- * empty, 1970-2099
+ * empty, 1970-2199
*
* , - * /
*
@@ -86,7 +103,7 @@
*
* The '?' character is allowed for the day-of-month and day-of-week fields. It
* is used to specify 'no specific value'. This is useful when you need to
- * specify something in one of the two fileds, but not the other.
+ * specify something in one of the two fields, but not the other.
*
* The '-' character is used to specify ranges For example "10-12" in
* the hour field means "the hours 10, 11 and 12".
@@ -115,9 +132,10 @@
* day-of-week field by itself, it simply means "7" or
* "SAT". But if used in the day-of-week field after another value, it
* means "the last xxx day of the month" - for example "6L"
- * means "the last friday of the month". When using the 'L' option, it
- * is important not to specify lists, or ranges of values, as you'll get
- * confusing results.
+ * means "the last friday of the month". You can also specify an offset
+ * from the last day of the month, such as "L-3" which would mean the third-to-last
+ * day of the calendar month. When using the 'L' option, it is important not to
+ * specify lists, or ranges of values, as you'll get confusing/unexpected results.
*
* The 'W' character is allowed for the day-of-month field. This character
* is used to specify the weekday (Monday-Friday) nearest the given day. As an
@@ -142,15 +160,17 @@
* Other examples: "2#1" = the first Monday of the month and
* "4#5" = the fifth Wednesday of the month. Note that if you specify
* "#5" and there is not 5 of the given day-of-week in the month, then
- * no firing will occur that month.
+ * no firing will occur that month. If the '#' character is used, there can
+ * only be one expression in the day-of-week field ("3#1,6#3" is
+ * not valid, since there are two expressions).
*
*
+ * means "the first day included by the calendar on or after Sunday".-->
*
* The legal characters and the names of months and days of the week are not
* case sensitive.
@@ -159,8 +179,15 @@
* NOTES:
*
* - Support for specifying both a day-of-week and a day-of-month value is
- * not complete (you'll need to use the '?' character in on of these fields).
+ * not complete (you'll need to use the '?' character in one of these fields).
*
+ * - Overflowing ranges is supported - that is, having a larger number on
+ * the left hand side than the right. You might do 22-2 to catch 10 o'clock
+ * at night until 2 o'clock in the morning, or you might have NOV-FEB. It is
+ * very important to note that overuse of overflowing ranges creates ranges
+ * that don't make sense and no effort has been made to determine which
+ * interpretation CronExpression chooses. An example would be
+ * "0 0 14-6 ? * FRI-MON".
*
*
*
@@ -169,11 +196,11 @@
* @author Contributions from Mads Henderson
* @author Refactoring from CronTrigger to CronExpression by Aaron Craven
*/
-public class CronExpression implements Serializable, Cloneable {
+public final class CronExpression implements Serializable, Cloneable {
- private static final long serialVersionUID = 12423409423L;
-
- protected static final int SECOND = 0;
+ private static final long serialVersionUID = 12423409423L;
+
+ protected static final int SECOND = 0;
protected static final int MINUTE = 1;
protected static final int HOUR = 2;
protected static final int DAY_OF_MONTH = 3;
@@ -182,158 +209,225 @@
protected static final int YEAR = 6;
protected static final int ALL_SPEC_INT = 99; // '*'
protected static final int NO_SPEC_INT = 98; // '?'
- protected static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT);
- protected static final Integer NO_SPEC = new Integer(NO_SPEC_INT);
+ protected static final Integer ALL_SPEC = ALL_SPEC_INT;
+ protected static final Integer NO_SPEC = NO_SPEC_INT;
- protected static Map monthMap = new HashMap(20);
- protected static Map dayMap = new HashMap(60);
+ protected static final Map monthMap = new HashMap(20);
+ protected static final Map dayMap = new HashMap(60);
static {
- monthMap.put("JAN", new Integer(0));
- monthMap.put("FEB", new Integer(1));
- monthMap.put("MAR", new Integer(2));
- monthMap.put("APR", new Integer(3));
- monthMap.put("MAY", new Integer(4));
- monthMap.put("JUN", new Integer(5));
- monthMap.put("JUL", new Integer(6));
- monthMap.put("AUG", new Integer(7));
- monthMap.put("SEP", new Integer(8));
- monthMap.put("OCT", new Integer(9));
- monthMap.put("NOV", new Integer(10));
- monthMap.put("DEC", new Integer(11));
+ monthMap.put("JAN", 0);
+ monthMap.put("FEB", 1);
+ monthMap.put("MAR", 2);
+ monthMap.put("APR", 3);
+ monthMap.put("MAY", 4);
+ monthMap.put("JUN", 5);
+ monthMap.put("JUL", 6);
+ monthMap.put("AUG", 7);
+ monthMap.put("SEP", 8);
+ monthMap.put("OCT", 9);
+ monthMap.put("NOV", 10);
+ monthMap.put("DEC", 11);
- dayMap.put("SUN", new Integer(1));
- dayMap.put("MON", new Integer(2));
- dayMap.put("TUE", new Integer(3));
- dayMap.put("WED", new Integer(4));
- dayMap.put("THU", new Integer(5));
- dayMap.put("FRI", new Integer(6));
- dayMap.put("SAT", new Integer(7));
+ dayMap.put("SUN", 1);
+ dayMap.put("MON", 2);
+ dayMap.put("TUE", 3);
+ dayMap.put("WED", 4);
+ dayMap.put("THU", 5);
+ dayMap.put("FRI", 6);
+ dayMap.put("SAT", 7);
}
- private String cronExpression = null;
+ private final String cronExpression;
private TimeZone timeZone = null;
- protected transient TreeSet seconds;
- protected transient TreeSet minutes;
- protected transient TreeSet hours;
- protected transient TreeSet daysOfMonth;
- protected transient TreeSet months;
- protected transient TreeSet daysOfWeek;
- protected transient TreeSet years;
+ protected transient TreeSet seconds;
+ protected transient TreeSet minutes;
+ protected transient TreeSet hours;
+ protected transient TreeSet daysOfMonth;
+ protected transient TreeSet months;
+ protected transient TreeSet daysOfWeek;
+ protected transient TreeSet years;
protected transient boolean lastdayOfWeek = false;
protected transient int nthdayOfWeek = 0;
protected transient boolean lastdayOfMonth = false;
protected transient boolean nearestWeekday = false;
- protected transient boolean calendardayOfWeek = false;
- protected transient boolean calendardayOfMonth = false;
+ protected transient int lastdayOffset = 0;
protected transient boolean expressionParsed = false;
-
+
+ public static final int MAX_YEAR = Calendar.getInstance().get(Calendar.YEAR) + 100;
+
/**
- * Constructs a new CronExpression based on the specified
- * parameter.
- *
- * @param cronExpression String representation of the cron expression the
- * new object should represent
- * @throws java.text.ParseException
- * if the string expression cannot be parsed into a valid
- * CronExpression
- */
- public CronExpression(String cronExpression) throws ParseException {
- if (cronExpression == null) {
- throw new IllegalArgumentException("cronExpression cannot be null");
- }
-
- this.cronExpression = cronExpression;
-
- buildExpression(cronExpression.toUpperCase(Locale.US));
- }
-
- /**
- * Indicates whether the given date satisfies the cron expression. Note that
- * milliseconds are ignored, so two Dates falling on different milliseconds
- * of the same second will always have the same result here.
- *
- * @param date the date to evaluate
- * @return a boolean indicating whether the given date satisfies the cron
- * expression
- */
- public boolean isSatisfiedBy(Date date) {
- Calendar testDateCal = Calendar.getInstance();
- testDateCal.setTime(date);
- testDateCal.set(Calendar.MILLISECOND, 0);
- Date originalDate = testDateCal.getTime();
-
- testDateCal.add(Calendar.SECOND, -1);
-
- if (getTimeAfter(testDateCal.getTime()).equals(originalDate)) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Returns the next date/time after the given date/time which
- * satisfies the cron expression.
- *
- * @param date the date/time at which to begin the search for the next valid
- * date/time
- * @return the next valid date/time
- */
- public Date getNextValidTimeAfter(Date date) {
- return getTimeAfter(date);
- }
-
+ * Constructs a new CronExpression based on the specified
+ * parameter.
+ *
+ * @param cronExpression String representation of the cron expression the
+ * new object should represent
+ * @throws java.text.ParseException
+ * if the string expression cannot be parsed into a valid
+ * CronExpression
+ */
+ public CronExpression(String cronExpression) throws ParseException {
+ if (cronExpression == null) {
+ throw new IllegalArgumentException("cronExpression cannot be null");
+ }
+
+ this.cronExpression = cronExpression.toUpperCase(Locale.US);
+
+ buildExpression(this.cronExpression);
+ }
+
/**
- *
- * Returns the time zone for which the cronExpression of
- * this CronTrigger will be resolved.
- *
+ * Constructs a new {@code CronExpression} as a copy of an existing
+ * instance.
+ *
+ * @param expression
+ * The existing cron expression to be copied
*/
+ public CronExpression(CronExpression expression) {
+ /*
+ * We don't call the other constructor here since we need to swallow the
+ * ParseException. We also elide some of the sanity checking as it is
+ * not logically trippable.
+ */
+ this.cronExpression = expression.getCronExpression();
+ try {
+ buildExpression(cronExpression);
+ } catch (ParseException ex) {
+ throw new AssertionError();
+ }
+ if (expression.getTimeZone() != null) {
+ setTimeZone((TimeZone) expression.getTimeZone().clone());
+ }
+ }
+
+ /**
+ * Indicates whether the given date satisfies the cron expression. Note that
+ * milliseconds are ignored, so two Dates falling on different milliseconds
+ * of the same second will always have the same result here.
+ *
+ * @param date the date to evaluate
+ * @return a boolean indicating whether the given date satisfies the cron
+ * expression
+ */
+ public boolean isSatisfiedBy(Date date) {
+ Calendar testDateCal = Calendar.getInstance(getTimeZone());
+ testDateCal.setTime(date);
+ testDateCal.set(Calendar.MILLISECOND, 0);
+ Date originalDate = testDateCal.getTime();
+
+ testDateCal.add(Calendar.SECOND, -1);
+
+ Date timeAfter = getTimeAfter(testDateCal.getTime());
+
+ return ((timeAfter != null) && (timeAfter.equals(originalDate)));
+ }
+
+ /**
+ * Returns the next date/time after the given date/time which
+ * satisfies the cron expression.
+ *
+ * @param date the date/time at which to begin the search for the next valid
+ * date/time
+ * @return the next valid date/time
+ */
+ public Date getNextValidTimeAfter(Date date) {
+ return getTimeAfter(date);
+ }
+
+ /**
+ * Returns the next date/time after the given date/time which does
+ * not satisfy the expression
+ *
+ * @param date the date/time at which to begin the search for the next
+ * invalid date/time
+ * @return the next valid date/time
+ */
+ public Date getNextInvalidTimeAfter(Date date) {
+ long difference = 1000;
+
+ //move back to the nearest second so differences will be accurate
+ Calendar adjustCal = Calendar.getInstance(getTimeZone());
+ adjustCal.setTime(date);
+ adjustCal.set(Calendar.MILLISECOND, 0);
+ Date lastDate = adjustCal.getTime();
+
+ Date newDate;
+
+ //FUTURE_TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to this problem. Performance will be very bad here, depending on the cron expression. It is, however A solution.
+
+ //keep getting the next included time until it's farther than one second
+ // apart. At that point, lastDate is the last valid fire time. We return
+ // the second immediately following it.
+ while (difference == 1000) {
+ newDate = getTimeAfter(lastDate);
+ if(newDate == null)
+ break;
+
+ difference = newDate.getTime() - lastDate.getTime();
+
+ if (difference == 1000) {
+ lastDate = newDate;
+ }
+ }
+
+ return new Date(lastDate.getTime() + 1000);
+ }
+
+ /**
+ * Returns the time zone for which this CronExpression
+ * will be resolved.
+ */
public TimeZone getTimeZone() {
- if (timeZone == null) timeZone = TimeZone.getDefault();
+ if (timeZone == null) {
+ timeZone = TimeZone.getDefault();
+ }
return timeZone;
}
/**
- *
- * Sets the time zone for which the cronExpression of this
- * CronTrigger will be resolved.
- *
+ * Sets the time zone for which this CronExpression
+ * will be resolved.
*/
public void setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
}
-
- /**
- * Returns the string representation of the CronExpression
- *
- * @return a string representation of the CronExpression
- */
- public String toString() {
- return cronExpression;
- }
-
- /**
- * Indicates whether the specified cron expression can be parsed into a
- * valid cron expression
- *
- * @param cronExpression the expression to evaluate
- * @return a boolean indicating whether the given expression is a valid cron
- * expression
- */
- public static boolean isValidExpression(String cronExpression) {
-
- try {
- new CronExpression(cronExpression);
- } catch (ParseException pe) {
- return false;
- }
-
- return true;
- }
-
+
+ /**
+ * Returns the string representation of the CronExpression
+ *
+ * @return a string representation of the CronExpression
+ */
+ @Override
+ public String toString() {
+ return cronExpression;
+ }
+
+ /**
+ * Indicates whether the specified cron expression can be parsed into a
+ * valid cron expression
+ *
+ * @param cronExpression the expression to evaluate
+ * @return a boolean indicating whether the given expression is a valid cron
+ * expression
+ */
+ public static boolean isValidExpression(String cronExpression) {
+
+ try {
+ new CronExpression(cronExpression);
+ } catch (ParseException pe) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void validateExpression(String cronExpression) throws ParseException {
+
+ new CronExpression(cronExpression);
+ }
+
+
////////////////////////////////////////////////////////////////////////////
//
// Expression Parsing Functions
@@ -345,13 +439,27 @@
try {
- if (seconds == null) seconds = new TreeSet();
- if (minutes == null) minutes = new TreeSet();
- if (hours == null) hours = new TreeSet();
- if (daysOfMonth == null) daysOfMonth = new TreeSet();
- if (months == null) months = new TreeSet();
- if (daysOfWeek == null) daysOfWeek = new TreeSet();
- if (years == null) years = new TreeSet();
+ if (seconds == null) {
+ seconds = new TreeSet();
+ }
+ if (minutes == null) {
+ minutes = new TreeSet();
+ }
+ if (hours == null) {
+ hours = new TreeSet();
+ }
+ if (daysOfMonth == null) {
+ daysOfMonth = new TreeSet();
+ }
+ if (months == null) {
+ months = new TreeSet();
+ }
+ if (daysOfWeek == null) {
+ daysOfWeek = new TreeSet();
+ }
+ if (years == null) {
+ years = new TreeSet();
+ }
int exprOn = SECOND;
@@ -360,6 +468,19 @@
while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {
String expr = exprsTok.nextToken().trim();
+
+ // throw an exception if L is used with other days of the month
+ if(exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
+ throw new ParseException("Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1);
+ }
+ // throw an exception if L is used with other days of the week
+ if(exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
+ throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1);
+ }
+ if(exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') +1) != -1) {
+ throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1);
+ }
+
StringTokenizer vTok = new StringTokenizer(expr, ",");
while (vTok.hasMoreTokens()) {
String v = vTok.nextToken();
@@ -369,12 +490,28 @@
exprOn++;
}
- if (exprOn <= DAY_OF_WEEK)
- throw new ParseException("Unexpected end of expression.",
+ if (exprOn <= DAY_OF_WEEK) {
+ throw new ParseException("Unexpected end of expression.",
expression.length());
+ }
- if (exprOn <= YEAR) storeExpressionVals(0, "*", YEAR);
+ if (exprOn <= YEAR) {
+ storeExpressionVals(0, "*", YEAR);
+ }
+ TreeSet dow = getSet(DAY_OF_WEEK);
+ TreeSet dom = getSet(DAY_OF_MONTH);
+
+ // Copying the logic from the UnsupportedOperationException below
+ boolean dayOfMSpec = !dom.contains(NO_SPEC);
+ boolean dayOfWSpec = !dow.contains(NO_SPEC);
+
+ if (!dayOfMSpec || dayOfWSpec) {
+ if (!dayOfWSpec || dayOfMSpec) {
+ throw new ParseException(
+ "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0);
+ }
+ }
} catch (ParseException pe) {
throw pe;
} catch (Exception e) {
@@ -384,57 +521,58 @@
}
protected int storeExpressionVals(int pos, String s, int type)
- throws ParseException {
+ throws ParseException {
+
int incr = 0;
int i = skipWhiteSpace(pos, s);
- if (i >= s.length()) return i;
+ if (i >= s.length()) {
+ return i;
+ }
char c = s.charAt(i);
- if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW"))) {
+ if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) {
String sub = s.substring(i, i + 3);
int sval = -1;
int eval = -1;
if (type == MONTH) {
sval = getMonthNumber(sub) + 1;
- if (sval < 0)
- throw new ParseException("Invalid Month value: '" + sub
- + "'", i);
+ if (sval <= 0) {
+ throw new ParseException("Invalid Month value: '" + sub + "'", i);
+ }
if (s.length() > i + 3) {
c = s.charAt(i + 3);
if (c == '-') {
i += 4;
sub = s.substring(i, i + 3);
eval = getMonthNumber(sub) + 1;
- if (eval < 0)
- throw new ParseException(
- "Invalid Month value: '" + sub + "'", i);
+ if (eval <= 0) {
+ throw new ParseException("Invalid Month value: '" + sub + "'", i);
+ }
}
}
} else if (type == DAY_OF_WEEK) {
sval = getDayOfWeekNumber(sub);
- if (sval < 0)
- throw new ParseException("Invalid Day-of-Week value: '"
+ if (sval < 0) {
+ throw new ParseException("Invalid Day-of-Week value: '"
+ sub + "'", i);
+ }
if (s.length() > i + 3) {
c = s.charAt(i + 3);
if (c == '-') {
i += 4;
sub = s.substring(i, i + 3);
eval = getDayOfWeekNumber(sub);
- if (eval < 0)
+ if (eval < 0) {
throw new ParseException(
"Invalid Day-of-Week value: '" + sub
+ "'", i);
- if (sval > eval)
- throw new ParseException(
- "Invalid Day-of-Week sequence: " + sval
- + " > " + eval, i);
-
+ }
} else if (c == '#') {
try {
i += 4;
nthdayOfWeek = Integer.parseInt(s.substring(i));
- if (nthdayOfWeek < 1 || nthdayOfWeek > 5)
- throw new Exception();
+ if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
+ throw new Exception();
+ }
} catch (Exception e) {
throw new ParseException(
"A numeric value between 1 and 5 must follow the '#' option",
@@ -451,27 +589,32 @@
"Illegal characters for this position: '" + sub + "'",
i);
}
- if (eval != -1) incr = 1;
+ if (eval != -1) {
+ incr = 1;
+ }
addToSet(sval, eval, incr, type);
return (i + 3);
}
if (c == '?') {
i++;
- if ((i + 1) < s.length()
- && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t'))
- throw new ParseException("Illegal character after '?': "
+ if ((i + 1) < s.length()
+ && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) {
+ throw new ParseException("Illegal character after '?': "
+ s.charAt(i), i);
- if (type != DAY_OF_WEEK && type != DAY_OF_MONTH)
- throw new ParseException(
+ }
+ if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {
+ throw new ParseException(
"'?' can only be specfied for Day-of-Month or Day-of-Week.",
i);
+ }
if (type == DAY_OF_WEEK && !lastdayOfMonth) {
- int val = ((Integer) daysOfMonth.last()).intValue();
- if (val == NO_SPEC_INT)
- throw new ParseException(
+ int val = daysOfMonth.last();
+ if (val == NO_SPEC_INT) {
+ throw new ParseException(
"'?' can only be specfied for Day-of-Month -OR- Day-of-Week.",
i);
+ }
}
addToSet(NO_SPEC_INT, -1, 0, type);
@@ -484,51 +627,73 @@
return i + 1;
} else if (c == '/'
&& ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s
- .charAt(i + 1) == '\t')) throw new ParseException(
- "'/' must be followed by an integer.", i);
- else if (c == '*') i++;
+ .charAt(i + 1) == '\t')) {
+ throw new ParseException("'/' must be followed by an integer.", i);
+ } else if (c == '*') {
+ i++;
+ }
c = s.charAt(i);
if (c == '/') { // is an increment specified?
i++;
- if (i >= s.length())
- throw new ParseException("Unexpected end of string.", i);
+ if (i >= s.length()) {
+ throw new ParseException("Unexpected end of string.", i);
+ }
incr = getNumericValue(s, i);
i++;
- if (incr > 10) i++;
- if (incr > 59 && (type == SECOND || type == MINUTE)) throw new ParseException(
- "Increment > 60 : " + incr, i);
- else if (incr > 23 && (type == HOUR)) throw new ParseException(
- "Increment > 24 : " + incr, i);
- else if (incr > 31 && (type == DAY_OF_MONTH)) throw new ParseException(
- "Increment > 31 : " + incr, i);
- else if (incr > 7 && (type == DAY_OF_WEEK)) throw new ParseException(
- "Increment > 7 : " + incr, i);
- else if (incr > 12 && (type == MONTH))
- throw new ParseException("Increment > 12 : " + incr, i);
- } else
+ if (incr > 10) {
+ i++;
+ }
+ if (incr > 59 && (type == SECOND || type == MINUTE)) {
+ throw new ParseException("Increment > 60 : " + incr, i);
+ } else if (incr > 23 && (type == HOUR)) {
+ throw new ParseException("Increment > 24 : " + incr, i);
+ } else if (incr > 31 && (type == DAY_OF_MONTH)) {
+ throw new ParseException("Increment > 31 : " + incr, i);
+ } else if (incr > 7 && (type == DAY_OF_WEEK)) {
+ throw new ParseException("Increment > 7 : " + incr, i);
+ } else if (incr > 12 && (type == MONTH)) {
+ throw new ParseException("Increment > 12 : " + incr, i);
+ }
+ } else {
incr = 1;
+ }
addToSet(ALL_SPEC_INT, -1, incr, type);
return i;
} else if (c == 'L') {
i++;
- if (type == DAY_OF_MONTH) lastdayOfMonth = true;
- if (type == DAY_OF_WEEK) addToSet(7, 7, 0, type);
+ if (type == DAY_OF_MONTH) {
+ lastdayOfMonth = true;
+ }
+ if (type == DAY_OF_WEEK) {
+ addToSet(7, 7, 0, type);
+ }
if(type == DAY_OF_MONTH && s.length() > i) {
c = s.charAt(i);
- if(c == 'W') {
- nearestWeekday = true;
- i++;
+ if(c == '-') {
+ ValueSet vs = getValue(0, s, i+1);
+ lastdayOffset = vs.value;
+ if(lastdayOffset > 30)
+ throw new ParseException("Offset from last day must be <= 30", i+1);
+ i = vs.pos;
+ }
+ if(s.length() > i) {
+ c = s.charAt(i);
+ if(c == 'W') {
+ nearestWeekday = true;
+ i++;
+ }
}
}
return i;
} else if (c >= '0' && c <= '9') {
int val = Integer.parseInt(String.valueOf(c));
i++;
- if (i >= s.length()) addToSet(val, -1, -1, type);
- else {
+ if (i >= s.length()) {
+ addToSet(val, -1, -1, type);
+ } else {
c = s.charAt(i);
if (c >= '0' && c <= '9') {
ValueSet vs = getValue(val, s, i);
@@ -538,14 +703,16 @@
i = checkNext(i, s, val, type);
return i;
}
- } else
+ } else {
throw new ParseException("Unexpected character: " + c, i);
+ }
return i;
}
protected int checkNext(int pos, String s, int val, int type)
- throws ParseException {
+ throws ParseException {
+
int end = -1;
int i = pos;
@@ -557,60 +724,55 @@
char c = s.charAt(pos);
if (c == 'L') {
- if (type == DAY_OF_WEEK) lastdayOfWeek = true;
- else
- throw new ParseException("'L' option is not valid here. (pos="
- + i + ")", i);
- TreeSet set = getSet(type);
- set.add(new Integer(val));
+ if (type == DAY_OF_WEEK) {
+ if(val < 1 || val > 7)
+ throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
+ lastdayOfWeek = true;
+ } else {
+ throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
+ }
+ TreeSet set = getSet(type);
+ set.add(val);
i++;
return i;
}
if (c == 'W') {
- if(type == DAY_OF_MONTH) nearestWeekday = true;
- else
- throw new ParseException("'W' option is not valid here. (pos="
- + i + ")", i);
- TreeSet set = getSet(type);
- set.add(new Integer(val));
+ if (type == DAY_OF_MONTH) {
+ nearestWeekday = true;
+ } else {
+ throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
+ }
+ if(val > 31)
+ throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
+ TreeSet set = getSet(type);
+ set.add(val);
i++;
return i;
}
if (c == '#') {
- if (type != DAY_OF_WEEK)
- throw new ParseException(
- "'#' option is not valid here. (pos=" + i + ")", i);
+ if (type != DAY_OF_WEEK) {
+ throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i);
+ }
i++;
try {
nthdayOfWeek = Integer.parseInt(s.substring(i));
- if (nthdayOfWeek < 1 || nthdayOfWeek > 5)
- throw new Exception();
+ if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
+ throw new Exception();
+ }
} catch (Exception e) {
throw new ParseException(
"A numeric value between 1 and 5 must follow the '#' option",
i);
}
- TreeSet set = getSet(type);
- set.add(new Integer(val));
+ TreeSet set = getSet(type);
+ set.add(val);
i++;
return i;
}
- if (c == 'C') {
- if (type == DAY_OF_WEEK) calendardayOfWeek = true;
- else if (type == DAY_OF_MONTH) calendardayOfMonth = true;
- else
- throw new ParseException("'C' option is not valid here. (pos="
- + i + ")", i);
- TreeSet set = getSet(type);
- set.add(new Integer(val));
- i++;
- return i;
- }
-
if (c == '-') {
i++;
c = s.charAt(i);
@@ -624,8 +786,7 @@
c = s.charAt(i);
if (c >= '0' && c <= '9') {
ValueSet vs = getValue(v, s, i);
- int v1 = vs.value;
- end = v1;
+ end = vs.value;
i = vs.pos;
}
if (i < s.length() && ((c = s.charAt(i)) == '/')) {
@@ -670,9 +831,9 @@
addToSet(val, end, v3, type);
i = vs.pos;
return i;
- } else
- throw new ParseException("Unexpected character '" + c
- + "' after '/'", i);
+ } else {
+ throw new ParseException("Unexpected character '" + c + "' after '/'", i);
+ }
}
addToSet(val, end, 0, type);
@@ -681,11 +842,11 @@
}
public String getCronExpression() {
- return cronExpression;
+ return cronExpression;
}
public String getExpressionSummary() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append("seconds: ");
buf.append(getExpressionSetSummary(seconds));
@@ -717,52 +878,58 @@
buf.append("lastdayOfMonth: ");
buf.append(lastdayOfMonth);
buf.append("\n");
- buf.append("calendardayOfWeek: ");
- buf.append(calendardayOfWeek);
- buf.append("\n");
- buf.append("calendardayOfMonth: ");
- buf.append(calendardayOfMonth);
- buf.append("\n");
buf.append("years: ");
buf.append(getExpressionSetSummary(years));
buf.append("\n");
return buf.toString();
}
- protected String getExpressionSetSummary(java.util.Set set) {
+ protected String getExpressionSetSummary(java.util.Set set) {
- if (set.contains(NO_SPEC)) return "?";
- if (set.contains(ALL_SPEC)) return "*";
+ if (set.contains(NO_SPEC)) {
+ return "?";
+ }
+ if (set.contains(ALL_SPEC)) {
+ return "*";
+ }
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
- Iterator itr = set.iterator();
+ Iterator itr = set.iterator();
boolean first = true;
while (itr.hasNext()) {
- Integer iVal = (Integer) itr.next();
+ Integer iVal = itr.next();
String val = iVal.toString();
- if (!first) buf.append(",");
+ if (!first) {
+ buf.append(",");
+ }
buf.append(val);
first = false;
}
return buf.toString();
}
- protected String getExpressionSetSummary(java.util.ArrayList list) {
+ protected String getExpressionSetSummary(java.util.ArrayList list) {
- if (list.contains(NO_SPEC)) return "?";
- if (list.contains(ALL_SPEC)) return "*";
+ if (list.contains(NO_SPEC)) {
+ return "?";
+ }
+ if (list.contains(ALL_SPEC)) {
+ return "*";
+ }
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
- Iterator itr = list.iterator();
+ Iterator itr = list.iterator();
boolean first = true;
while (itr.hasNext()) {
- Integer iVal = (Integer) itr.next();
+ Integer iVal = itr.next();
String val = iVal.toString();
- if (!first) buf.append(",");
+ if (!first) {
+ buf.append(",");
+ }
buf.append(val);
first = false;
}
@@ -771,52 +938,63 @@
}
protected int skipWhiteSpace(int i, String s) {
- for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++)
+ for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) {
;
+ }
return i;
}
protected int findNextWhiteSpace(int i, String s) {
- for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++)
+ for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) {
;
+ }
return i;
}
protected void addToSet(int val, int end, int incr, int type)
- throws ParseException {
- TreeSet set = getSet(type);
+ throws ParseException {
+
+ TreeSet set = getSet(type);
if (type == SECOND || type == MINUTE) {
- if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT))
- throw new ParseException(
- "Minute and Second values must be between 0 and 59",
- -1);
+ if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {
+ throw new ParseException(
+ "Minute and Second values must be between 0 and 59",
+ -1);
+ }
} else if (type == HOUR) {
- if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT))
- throw new ParseException(
- "Hour values must be between 0 and 23", -1);
+ if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {
+ throw new ParseException(
+ "Hour values must be between 0 and 23", -1);
+ }
} else if (type == DAY_OF_MONTH) {
- if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)
- && (val != NO_SPEC_INT))
- throw new ParseException(
- "Day of month values must be between 1 and 31", -1);
+ if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)
+ && (val != NO_SPEC_INT)) {
+ throw new ParseException(
+ "Day of month values must be between 1 and 31", -1);
+ }
} else if (type == MONTH) {
- if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT))
- throw new ParseException(
- "Month values must be between 1 and 12", -1);
+ if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {
+ throw new ParseException(
+ "Month values must be between 1 and 12", -1);
+ }
} else if (type == DAY_OF_WEEK) {
if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT)
- && (val != NO_SPEC_INT))
- throw new ParseException(
- "Day-of-Week values must be between 1 and 7", -1);
+ && (val != NO_SPEC_INT)) {
+ throw new ParseException(
+ "Day-of-Week values must be between 1 and 7", -1);
+ }
}
if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) {
- if (val != -1) set.add(new Integer(val));
- else
+ if (val != -1) {
+ set.add(val);
+ } else {
set.add(NO_SPEC);
+ }
+
return;
}
@@ -829,64 +1007,121 @@
}
if (type == SECOND || type == MINUTE) {
- if (stopAt == -1) stopAt = 59;
- if (startAt == -1 || startAt == ALL_SPEC_INT) startAt = 0;
+ if (stopAt == -1) {
+ stopAt = 59;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 0;
+ }
} else if (type == HOUR) {
- if (stopAt == -1) stopAt = 23;
- if (startAt == -1 || startAt == ALL_SPEC_INT) startAt = 0;
+ if (stopAt == -1) {
+ stopAt = 23;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 0;
+ }
} else if (type == DAY_OF_MONTH) {
- if (stopAt == -1) stopAt = 31;
- if (startAt == -1 || startAt == ALL_SPEC_INT) startAt = 1;
+ if (stopAt == -1) {
+ stopAt = 31;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1;
+ }
} else if (type == MONTH) {
- if (stopAt == -1) stopAt = 12;
- if (startAt == -1 || startAt == ALL_SPEC_INT) startAt = 1;
+ if (stopAt == -1) {
+ stopAt = 12;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1;
+ }
} else if (type == DAY_OF_WEEK) {
- if (stopAt == -1) stopAt = 7;
- if (startAt == -1 || startAt == ALL_SPEC_INT) startAt = 1;
+ if (stopAt == -1) {
+ stopAt = 7;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1;
+ }
} else if (type == YEAR) {
- if (stopAt == -1) stopAt = 2099;
- if (startAt == -1 || startAt == ALL_SPEC_INT) startAt = 1970;
+ if (stopAt == -1) {
+ stopAt = MAX_YEAR;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1970;
+ }
}
- for (int i = startAt; i <= stopAt; i += incr)
- set.add(new Integer(i));
+ // if the end of the range is before the start, then we need to overflow into
+ // the next day, month etc. This is done by adding the maximum amount for that
+ // type, and using modulus max to determine the value being added.
+ int max = -1;
+ if (stopAt < startAt) {
+ switch (type) {
+ case SECOND : max = 60; break;
+ case MINUTE : max = 60; break;
+ case HOUR : max = 24; break;
+ case MONTH : max = 12; break;
+ case DAY_OF_WEEK : max = 7; break;
+ case DAY_OF_MONTH : max = 31; break;
+ case YEAR : throw new IllegalArgumentException("Start year must be less than stop year");
+ default : throw new IllegalArgumentException("Unexpected type encountered");
+ }
+ stopAt += max;
+ }
+
+ for (int i = startAt; i <= stopAt; i += incr) {
+ if (max == -1) {
+ // ie: there's no max to overflow over
+ set.add(i);
+ } else {
+ // take the modulus to get the real value
+ int i2 = i % max;
+
+ // 1-indexed ranges should not include 0, and should include their max
+ if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH) ) {
+ i2 = max;
+ }
+
+ set.add(i2);
+ }
+ }
}
- protected TreeSet getSet(int type) {
+ TreeSet getSet(int type) {
switch (type) {
- case SECOND:
- return seconds;
- case MINUTE:
- return minutes;
- case HOUR:
- return hours;
- case DAY_OF_MONTH:
- return daysOfMonth;
- case MONTH:
- return months;
- case DAY_OF_WEEK:
- return daysOfWeek;
- case YEAR:
- return years;
- default:
- return null;
+ case SECOND:
+ return seconds;
+ case MINUTE:
+ return minutes;
+ case HOUR:
+ return hours;
+ case DAY_OF_MONTH:
+ return daysOfMonth;
+ case MONTH:
+ return months;
+ case DAY_OF_WEEK:
+ return daysOfWeek;
+ case YEAR:
+ return years;
+ default:
+ return null;
}
}
protected ValueSet getValue(int v, String s, int i) {
char c = s.charAt(i);
- String s1 = String.valueOf(v);
+ StringBuilder s1 = new StringBuilder(String.valueOf(v));
while (c >= '0' && c <= '9') {
- s1 += c;
+ s1.append(c);
i++;
- if (i >= s.length()) break;
+ if (i >= s.length()) {
+ break;
+ }
c = s.charAt(i);
}
ValueSet val = new ValueSet();
- if (i < s.length()) val.pos = i;
- else
- val.pos = i + 1;
- val.value = Integer.parseInt(s1);
+
+ val.pos = (i < s.length()) ? i : i + 1;
+ val.value = Integer.parseInt(s1.toString());
return val;
}
@@ -897,48 +1132,35 @@
}
protected int getMonthNumber(String s) {
- Integer integer = (Integer) monthMap.get(s);
+ Integer integer = monthMap.get(s);
- if (integer == null) return -1;
+ if (integer == null) {
+ return -1;
+ }
- return integer.intValue();
+ return integer;
}
protected int getDayOfWeekNumber(String s) {
- Integer integer = (Integer) dayMap.get(s);
+ Integer integer = dayMap.get(s);
- if (integer == null) return -1;
+ if (integer == null) {
+ return -1;
+ }
- return integer.intValue();
+ return integer;
}
- protected Date getTime(int sc, int mn, int hr, int dayofmn, int mon) {
- try {
- Calendar cl = Calendar.getInstance(getTimeZone());
- //cl.add(Calendar.DAY_OF_MONTH,);
- if (hr >= 0 && hr <= 12) cl.set(Calendar.AM_PM, Calendar.AM);
- if (hr >= 13 && hr <= 23) cl.set(Calendar.AM_PM, Calendar.PM);
- cl.setLenient(false);
- if (sc != -1) cl.set(Calendar.SECOND, sc);
- if (mn != -1) cl.set(Calendar.MINUTE, mn);
- if (hr != -1) cl.set(Calendar.HOUR_OF_DAY, hr);
- if (dayofmn != -1) cl.set(Calendar.DAY_OF_MONTH, dayofmn);
- if (mon != -1) cl.set(Calendar.MONTH, mon);
- return cl.getTime();
- } catch (Exception e) {
- return null;
- }
- }
-
////////////////////////////////////////////////////////////////////////////
//
// Computation Functions
//
////////////////////////////////////////////////////////////////////////////
- protected Date getTimeAfter(Date afterTime) {
+ public Date getTimeAfter(Date afterTime) {
- Calendar cl = Calendar.getInstance(getTimeZone());
+ // Computation is based on Gregorian year only.
+ Calendar cl = new java.util.GregorianCalendar(getTimeZone());
// move ahead one second, since we're computing the time *after* the
// given time
@@ -952,19 +1174,22 @@
while (!gotOne) {
//if (endTime != null && cl.getTime().after(endTime)) return null;
+ if(cl.get(Calendar.YEAR) > 2999) { // prevent endless loop...
+ return null;
+ }
- SortedSet st = null;
+ SortedSet st = null;
int t = 0;
int sec = cl.get(Calendar.SECOND);
int min = cl.get(Calendar.MINUTE);
// get second.................................................
- st = seconds.tailSet(new Integer(sec));
+ st = seconds.tailSet(sec);
if (st != null && st.size() != 0) {
- sec = ((Integer) st.first()).intValue();
+ sec = st.first();
} else {
- sec = ((Integer) seconds.first()).intValue();
+ sec = seconds.first();
min++;
cl.set(Calendar.MINUTE, min);
}
@@ -975,12 +1200,12 @@
t = -1;
// get minute.................................................
- st = minutes.tailSet(new Integer(min));
+ st = minutes.tailSet(min);
if (st != null && st.size() != 0) {
t = min;
- min = ((Integer) st.first()).intValue();
+ min = st.first();
} else {
- min = ((Integer) minutes.first()).intValue();
+ min = minutes.first();
hr++;
}
if (min != t) {
@@ -996,12 +1221,12 @@
t = -1;
// get hour...................................................
- st = hours.tailSet(new Integer(hr));
+ st = hours.tailSet(hr);
if (st != null && st.size() != 0) {
t = hr;
- hr = ((Integer) st.first()).intValue();
+ hr = st.first();
} else {
- hr = ((Integer) hours.first()).intValue();
+ hr = hours.first();
day++;
}
if (hr != t) {
@@ -1024,17 +1249,27 @@
boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC);
boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC);
if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule
- st = daysOfMonth.tailSet(new Integer(day));
+ st = daysOfMonth.tailSet(day);
if (lastdayOfMonth) {
if(!nearestWeekday) {
t = day;
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
- }
- else {
+ day -= lastdayOffset;
+ if(t > day) {
+ mon++;
+ if(mon > 12) {
+ mon = 1;
+ tmon = 3333; // ensure test of mon != tmon further below fails
+ cl.add(Calendar.YEAR, 1);
+ }
+ day = 1;
+ }
+ } else {
t = day;
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ day -= lastdayOffset;
- java.util.Calendar tcal = java.util.Calendar.getInstance();
+ java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0);
tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 0);
@@ -1045,14 +1280,15 @@
int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
int dow = tcal.get(Calendar.DAY_OF_WEEK);
- if(dow == Calendar.SATURDAY && day == 1)
+ if(dow == Calendar.SATURDAY && day == 1) {
day += 2;
- else if(dow == Calendar.SATURDAY)
+ } else if(dow == Calendar.SATURDAY) {
day -= 1;
- else if(dow == Calendar.SUNDAY && day == ldom)
+ } else if(dow == Calendar.SUNDAY && day == ldom) {
day -= 2;
- else if(dow == Calendar.SUNDAY)
+ } else if(dow == Calendar.SUNDAY) {
day += 1;
+ }
tcal.set(Calendar.SECOND, sec);
tcal.set(Calendar.MINUTE, min);
@@ -1067,9 +1303,9 @@
}
} else if(nearestWeekday) {
t = day;
- day = ((Integer) daysOfMonth.first()).intValue();
+ day = daysOfMonth.first();
- java.util.Calendar tcal = java.util.Calendar.getInstance();
+ java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0);
tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 0);
@@ -1080,14 +1316,15 @@
int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
int dow = tcal.get(Calendar.DAY_OF_WEEK);
- if(dow == Calendar.SATURDAY && day == 1)
+ if(dow == Calendar.SATURDAY && day == 1) {
day += 2;
- else if(dow == Calendar.SATURDAY)
+ } else if(dow == Calendar.SATURDAY) {
day -= 1;
- else if(dow == Calendar.SUNDAY && day == ldom)
+ } else if(dow == Calendar.SUNDAY && day == ldom) {
day -= 2;
- else if(dow == Calendar.SUNDAY)
+ } else if(dow == Calendar.SUNDAY) {
day += 1;
+ }
tcal.set(Calendar.SECOND, sec);
@@ -1097,15 +1334,20 @@
tcal.set(Calendar.MONTH, mon - 1);
Date nTime = tcal.getTime();
if(nTime.before(afterTime)) {
- day = ((Integer) daysOfMonth.first()).intValue();;
+ day = daysOfMonth.first();
mon++;
}
- }
- else if (st != null && st.size() != 0) {
+ } else if (st != null && st.size() != 0) {
t = day;
- day = ((Integer) st.first()).intValue();
+ day = st.first();
+ // make sure we don't over-run a short month, such as february
+ int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ if (day > lastDay) {
+ day = daysOfMonth.first();
+ mon++;
+ }
} else {
- day = ((Integer) daysOfMonth.first()).intValue();
+ day = daysOfMonth.first();
mon++;
}
@@ -1122,12 +1364,16 @@
} else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule
if (lastdayOfWeek) { // are we looking for the last XXX day of
// the month?
- int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
+ int dow = daysOfWeek.first(); // desired
// d-o-w
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
int daysToAdd = 0;
- if (cDow < dow) daysToAdd = dow - cDow;
- if (cDow > dow) daysToAdd = dow + (7 - cDow);
+ if (cDow < dow) {
+ daysToAdd = dow - cDow;
+ }
+ if (cDow > dow) {
+ daysToAdd = dow + (7 - cDow);
+ }
int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
@@ -1142,9 +1388,10 @@
continue;
}
- // find date of last occurance of this day in this month...
- while ((day + daysToAdd + 7) <= lDay)
+ // find date of last occurrence of this day in this month...
+ while ((day + daysToAdd + 7) <= lDay) {
daysToAdd += 7;
+ }
day += daysToAdd;
@@ -1160,19 +1407,26 @@
} else if (nthdayOfWeek != 0) {
// are we looking for the Nth XXX day in the month?
- int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
+ int dow = daysOfWeek.first(); // desired
// d-o-w
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
int daysToAdd = 0;
- if (cDow < dow) daysToAdd = dow - cDow;
- else if (cDow > dow) daysToAdd = dow + (7 - cDow);
+ if (cDow < dow) {
+ daysToAdd = dow - cDow;
+ } else if (cDow > dow) {
+ daysToAdd = dow + (7 - cDow);
+ }
boolean dayShifted = false;
- if (daysToAdd > 0) dayShifted = true;
+ if (daysToAdd > 0) {
+ dayShifted = true;
+ }
day += daysToAdd;
int weekOfMonth = day / 7;
- if (day % 7 > 0) weekOfMonth++;
+ if (day % 7 > 0) {
+ weekOfMonth++;
+ }
daysToAdd = (nthdayOfWeek - weekOfMonth) * 7;
day += daysToAdd;
@@ -1197,16 +1451,20 @@
}
} else {
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
- int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
+ int dow = daysOfWeek.first(); // desired
// d-o-w
- st = daysOfWeek.tailSet(new Integer(cDow));
+ st = daysOfWeek.tailSet(cDow);
if (st != null && st.size() > 0) {
- dow = ((Integer) st.first()).intValue();
+ dow = st.first();
}
int daysToAdd = 0;
- if (cDow < dow) daysToAdd = dow - cDow;
- if (cDow > dow) daysToAdd = dow + (7 - cDow);
+ if (cDow < dow) {
+ daysToAdd = dow - cDow;
+ }
+ if (cDow > dow) {
+ daysToAdd = dow + (7 - cDow);
+ }
int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
@@ -1233,7 +1491,6 @@
} else { // dayOfWSpec && !dayOfMSpec
throw new UnsupportedOperationException(
"Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.");
- // TODO:
}
cl.set(Calendar.DAY_OF_MONTH, day);
@@ -1245,15 +1502,17 @@
// test for expressions that never generate a valid fire date,
// but keep looping...
- if (year > 2099) return null;
+ if (year > MAX_YEAR) {
+ return null;
+ }
// get month...................................................
- st = months.tailSet(new Integer(mon));
+ st = months.tailSet(mon);
if (st != null && st.size() != 0) {
t = mon;
- mon = ((Integer) st.first()).intValue();
+ mon = st.first();
} else {
- mon = ((Integer) months.first()).intValue();
+ mon = months.first();
year++;
}
if (mon != t) {
@@ -1275,12 +1534,13 @@
t = -1;
// get year...................................................
- st = years.tailSet(new Integer(year));
+ st = years.tailSet(year);
if (st != null && st.size() != 0) {
t = year;
- year = ((Integer) st.first()).intValue();
- } else
+ year = st.first();
+ } else {
return null; // ran out of years...
+ }
if (year != t) {
cl.set(Calendar.SECOND, 0);
@@ -1305,8 +1565,8 @@
* Advance the calendar to the particular hour paying particular attention
* to daylight saving problems.
*
- * @param cal
- * @param hour
+ * @param cal the calendar to operate on
+ * @param hour the hour to set
*/
protected void setCalendarHour(Calendar cal, int hour) {
cal.set(java.util.Calendar.HOUR_OF_DAY, hour);
@@ -1315,74 +1575,81 @@
}
}
- protected Date getTimeBefore(Date endTime) // TODO: implement
- {
+ /**
+ * NOT YET IMPLEMENTED: Returns the time before the given time
+ * that the CronExpression matches.
+ */
+ public Date getTimeBefore(Date endTime) {
+ // FUTURE_TODO: implement QUARTZ-423
return null;
}
+ /**
+ * NOT YET IMPLEMENTED: Returns the final time that the
+ * CronExpression will match.
+ */
+ public Date getFinalFireTime() {
+ // FUTURE_TODO: implement QUARTZ-423
+ return null;
+ }
+
protected boolean isLeapYear(int year) {
- if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return true;
- else
- return false;
+ return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}
protected int getLastDayOfMonth(int monthNum, int year) {
switch (monthNum) {
- case 1:
- return 31;
- case 2:
- return (isLeapYear(year)) ? 29 : 28;
- case 3:
- return 31;
- case 4:
- return 30;
- case 5:
- return 31;
- case 6:
- return 30;
- case 7:
- return 31;
- case 8:
- return 31;
- case 9:
- return 30;
- case 10:
- return 31;
- case 11:
- return 30;
- case 12:
- return 31;
- default:
- throw new IllegalArgumentException("Illegal month number: "
- + monthNum);
+ case 1:
+ return 31;
+ case 2:
+ return (isLeapYear(year)) ? 29 : 28;
+ case 3:
+ return 31;
+ case 4:
+ return 30;
+ case 5:
+ return 31;
+ case 6:
+ return 30;
+ case 7:
+ return 31;
+ case 8:
+ return 31;
+ case 9:
+ return 30;
+ case 10:
+ return 31;
+ case 11:
+ return 30;
+ case 12:
+ return 31;
+ default:
+ throw new IllegalArgumentException("Illegal month number: "
+ + monthNum);
}
}
private void readObject(java.io.ObjectInputStream stream)
- throws java.io.IOException, ClassNotFoundException {
+ throws java.io.IOException, ClassNotFoundException {
+
stream.defaultReadObject();
try {
buildExpression(cronExpression);
} catch (Exception ignore) {
} // never happens
}
+ @Override
+ @Deprecated
public Object clone() {
- CronExpression copy = null;
- try {
- copy = new CronExpression(getCronExpression());
- copy.setTimeZone(getTimeZone());
- } catch (ParseException ex) { // never happens since the source is valid...
- throw new IncompatibleClassChangeError("Not Cloneable.");
- }
- return copy;
- }
+ return new CronExpression(this);
+ }
}
class ValueSet {
public int value;
public int pos;
-}
\ No newline at end of file
+}
Index: 3rdParty_sources/quartz/org/quartz/CronScheduleBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/CronScheduleBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/CronScheduleBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,328 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.text.ParseException;
+import java.util.TimeZone;
+
+import org.quartz.impl.triggers.CronTriggerImpl;
+import org.quartz.spi.MutableTrigger;
+
+/**
+ * CronScheduleBuilder is a {@link ScheduleBuilder} that defines
+ * {@link CronExpression}-based schedules for Triggers.
+ *
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be utilized
+ * through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey and
+ * the various ScheduleBuilder implementations.
+ *
+ *
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ *
+ *
+ * JobDetail job = newJob(MyJob.class).withIdentity("myJob").build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(dailyAtHourAndMinute(10, 0))
+ * .startAt(futureDate(10, MINUTES)).build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ *
+ * @see CronExpression
+ * @see CronTrigger
+ * @see ScheduleBuilder
+ * @see SimpleScheduleBuilder
+ * @see CalendarIntervalScheduleBuilder
+ * @see TriggerBuilder
+ */
+public class CronScheduleBuilder extends ScheduleBuilder {
+
+ private CronExpression cronExpression;
+ private int misfireInstruction = CronTrigger.MISFIRE_INSTRUCTION_SMART_POLICY;
+
+ protected CronScheduleBuilder(CronExpression cronExpression) {
+ if (cronExpression == null) {
+ throw new NullPointerException("cronExpression cannot be null");
+ }
+ this.cronExpression = cronExpression;
+ }
+
+ /**
+ * Build the actual Trigger -- NOT intended to be invoked by end users, but
+ * will rather be invoked by a TriggerBuilder which this ScheduleBuilder is
+ * given to.
+ *
+ * @see TriggerBuilder#withSchedule(ScheduleBuilder)
+ */
+ @Override
+ public MutableTrigger build() {
+
+ CronTriggerImpl ct = new CronTriggerImpl();
+
+ ct.setCronExpression(cronExpression);
+ ct.setTimeZone(cronExpression.getTimeZone());
+ ct.setMisfireInstruction(misfireInstruction);
+
+ return ct;
+ }
+
+ /**
+ * Create a CronScheduleBuilder with the given cron-expression string -
+ * which is presumed to b e valid cron expression (and hence only a
+ * RuntimeException will be thrown if it is not).
+ *
+ * @param cronExpression
+ * the cron expression string to base the schedule on.
+ * @return the new CronScheduleBuilder
+ * @throws RuntimeException
+ * wrapping a ParseException if the expression is invalid
+ * @see CronExpression
+ */
+ public static CronScheduleBuilder cronSchedule(String cronExpression) {
+ try {
+ return cronSchedule(new CronExpression(cronExpression));
+ } catch (ParseException e) {
+ // all methods of construction ensure the expression is valid by
+ // this point...
+ throw new RuntimeException("CronExpression '" + cronExpression
+ + "' is invalid.", e);
+ }
+ }
+
+ /**
+ * Create a CronScheduleBuilder with the given cron-expression string -
+ * which may not be a valid cron expression (and hence a ParseException will
+ * be thrown if it is not).
+ *
+ * @param cronExpression
+ * the cron expression string to base the schedule on.
+ * @return the new CronScheduleBuilder
+ * @throws ParseException
+ * if the expression is invalid
+ * @see CronExpression
+ */
+ public static CronScheduleBuilder cronScheduleNonvalidatedExpression(
+ String cronExpression) throws ParseException {
+ return cronSchedule(new CronExpression(cronExpression));
+ }
+
+ private static CronScheduleBuilder cronScheduleNoParseException(
+ String presumedValidCronExpression) {
+ try {
+ return cronSchedule(new CronExpression(presumedValidCronExpression));
+ } catch (ParseException e) {
+ // all methods of construction ensure the expression is valid by
+ // this point...
+ throw new RuntimeException(
+ "CronExpression '"
+ + presumedValidCronExpression
+ + "' is invalid, which should not be possible, please report bug to Quartz developers.",
+ e);
+ }
+ }
+
+ /**
+ * Create a CronScheduleBuilder with the given cron-expression.
+ *
+ * @param cronExpression
+ * the cron expression to base the schedule on.
+ * @return the new CronScheduleBuilder
+ * @see CronExpression
+ */
+ public static CronScheduleBuilder cronSchedule(CronExpression cronExpression) {
+ return new CronScheduleBuilder(cronExpression);
+ }
+
+ /**
+ * Create a CronScheduleBuilder with a cron-expression that sets the
+ * schedule to fire every day at the given time (hour and minute).
+ *
+ * @param hour
+ * the hour of day to fire
+ * @param minute
+ * the minute of the given hour to fire
+ * @return the new CronScheduleBuilder
+ * @see CronExpression
+ */
+ public static CronScheduleBuilder dailyAtHourAndMinute(int hour, int minute) {
+ DateBuilder.validateHour(hour);
+ DateBuilder.validateMinute(minute);
+
+ String cronExpression = String.format("0 %d %d ? * *", minute, hour);
+
+ return cronScheduleNoParseException(cronExpression);
+ }
+
+ /**
+ * Create a CronScheduleBuilder with a cron-expression that sets the
+ * schedule to fire at the given day at the given time (hour and minute) on
+ * the given days of the week.
+ *
+ * @param daysOfWeek
+ * the dasy of the week to fire
+ * @param hour
+ * the hour of day to fire
+ * @param minute
+ * the minute of the given hour to fire
+ * @return the new CronScheduleBuilder
+ * @see CronExpression
+ * @see DateBuilder#MONDAY
+ * @see DateBuilder#TUESDAY
+ * @see DateBuilder#WEDNESDAY
+ * @see DateBuilder#THURSDAY
+ * @see DateBuilder#FRIDAY
+ * @see DateBuilder#SATURDAY
+ * @see DateBuilder#SUNDAY
+ */
+
+ public static CronScheduleBuilder atHourAndMinuteOnGivenDaysOfWeek(
+ int hour, int minute, Integer... daysOfWeek) {
+ if (daysOfWeek == null || daysOfWeek.length == 0)
+ throw new IllegalArgumentException(
+ "You must specify at least one day of week.");
+ for (int dayOfWeek : daysOfWeek)
+ DateBuilder.validateDayOfWeek(dayOfWeek);
+ DateBuilder.validateHour(hour);
+ DateBuilder.validateMinute(minute);
+
+ String cronExpression = String.format("0 %d %d ? * %d", minute, hour,
+ daysOfWeek[0]);
+
+ for (int i = 1; i < daysOfWeek.length; i++)
+ cronExpression = cronExpression + "," + daysOfWeek[i];
+
+ return cronScheduleNoParseException(cronExpression);
+ }
+
+ /**
+ * Create a CronScheduleBuilder with a cron-expression that sets the
+ * schedule to fire one per week on the given day at the given time (hour
+ * and minute).
+ *
+ * @param dayOfWeek
+ * the day of the week to fire
+ * @param hour
+ * the hour of day to fire
+ * @param minute
+ * the minute of the given hour to fire
+ * @return the new CronScheduleBuilder
+ * @see CronExpression
+ * @see DateBuilder#MONDAY
+ * @see DateBuilder#TUESDAY
+ * @see DateBuilder#WEDNESDAY
+ * @see DateBuilder#THURSDAY
+ * @see DateBuilder#FRIDAY
+ * @see DateBuilder#SATURDAY
+ * @see DateBuilder#SUNDAY
+ */
+ public static CronScheduleBuilder weeklyOnDayAndHourAndMinute(
+ int dayOfWeek, int hour, int minute) {
+ DateBuilder.validateDayOfWeek(dayOfWeek);
+ DateBuilder.validateHour(hour);
+ DateBuilder.validateMinute(minute);
+
+ String cronExpression = String.format("0 %d %d ? * %d", minute, hour,
+ dayOfWeek);
+
+ return cronScheduleNoParseException(cronExpression);
+ }
+
+ /**
+ * Create a CronScheduleBuilder with a cron-expression that sets the
+ * schedule to fire one per month on the given day of month at the given
+ * time (hour and minute).
+ *
+ * @param dayOfMonth
+ * the day of the month to fire
+ * @param hour
+ * the hour of day to fire
+ * @param minute
+ * the minute of the given hour to fire
+ * @return the new CronScheduleBuilder
+ * @see CronExpression
+ */
+ public static CronScheduleBuilder monthlyOnDayAndHourAndMinute(
+ int dayOfMonth, int hour, int minute) {
+ DateBuilder.validateDayOfMonth(dayOfMonth);
+ DateBuilder.validateHour(hour);
+ DateBuilder.validateMinute(minute);
+
+ String cronExpression = String.format("0 %d %d %d * ?", minute, hour,
+ dayOfMonth);
+
+ return cronScheduleNoParseException(cronExpression);
+ }
+
+ /**
+ * The TimeZone in which to base the schedule.
+ *
+ * @param timezone
+ * the time-zone for the schedule.
+ * @return the updated CronScheduleBuilder
+ * @see CronExpression#getTimeZone()
+ */
+ public CronScheduleBuilder inTimeZone(TimeZone timezone) {
+ cronExpression.setTimeZone(timezone);
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY} instruction.
+ *
+ * @return the updated CronScheduleBuilder
+ * @see Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
+ */
+ public CronScheduleBuilder withMisfireHandlingInstructionIgnoreMisfires() {
+ misfireInstruction = Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link CronTrigger#MISFIRE_INSTRUCTION_DO_NOTHING} instruction.
+ *
+ * @return the updated CronScheduleBuilder
+ * @see CronTrigger#MISFIRE_INSTRUCTION_DO_NOTHING
+ */
+ public CronScheduleBuilder withMisfireHandlingInstructionDoNothing() {
+ misfireInstruction = CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link CronTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW} instruction.
+ *
+ * @return the updated CronScheduleBuilder
+ * @see CronTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
+ */
+ public CronScheduleBuilder withMisfireHandlingInstructionFireAndProceed() {
+ misfireInstruction = CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW;
+ return this;
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/CronTrigger.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/CronTrigger.java (.../CronTrigger.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/CronTrigger.java (.../CronTrigger.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,5 +1,5 @@
-/*
- * Copyright 2004-2005 OpenSymphony
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*
* 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
@@ -15,22 +15,15 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
-import java.text.ParseException;
import java.util.Calendar;
-import java.util.Date;
import java.util.TimeZone;
-
/**
- *
- * A concrete {@link Trigger} that is used to fire a {@link org.quartz.JobDetail}
- * at given moments in time, defined with Unix 'cron-like' definitions.
- *
+ * The public interface for inspecting settings specific to a CronTrigger, .
+ * which is used to fire a {@link org.quartz.Job}
+ * at given moments in time, defined with Unix 'cron-like' schedule definitions.
*
*
* For those unfamiliar with "cron", this means being able to create a firing
@@ -139,7 +132,7 @@
*
* "0 15 10 ? * 6L 2002-2005"
*
- * Fire at 10:15am on every last friday of every month during the years 2002, 2003, 2004 and 2005
+ * Fire at 10:15am on every last Friday of every month during the years 2002, 2003, 2004 and 2005
*
*
*
@@ -168,23 +161,16 @@
*
*
*
- * @see Trigger
- * @see SimpleTrigger
- * @see TriggerUtils
+ * @see CronScheduleBuilder
+ * @see TriggerBuilder
*
- * @author Sharada Jambula, James House
+ * @author jhouse
* @author Contributions from Mads Henderson
*/
-public class CronTrigger extends Trigger {
+public interface CronTrigger extends Trigger {
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constants.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
+ public static final long serialVersionUID = -8644953146451592766L;
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
@@ -193,7 +179,7 @@
*
*/
public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
-
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
@@ -205,765 +191,17 @@
*/
public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
+ public String getCronExpression();
- private CronExpression cronEx = null;
- private Date startTime = null;
- private Date endTime = null;
- private Date nextFireTime = null;
- private Date previousFireTime = null;
- private transient TimeZone timeZone = null;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
/**
*
- * Create a CronTrigger with no settings.
- *
- *
- *
- * The start-time will also be set to the current time, and the time zone
- * will be set the the system's default time zone.
- *
- */
- public CronTrigger() {
- super();
- setStartTime(new Date());
- setTimeZone(TimeZone.getDefault());
- }
-
- /**
- *
- * Create a CronTrigger with the given name and group.
- *
- *
- *
- * The start-time will also be set to the current time, and the time zone
- * will be set the the system's default time zone.
- *
- */
- public CronTrigger(String name, String group) {
- super(name, group);
- setStartTime(new Date());
- setTimeZone(TimeZone.getDefault());
- }
-
- /**
- *
- * Create a CronTrigger with the given name, group and
- * expression.
- *
- *
- *
- * The start-time will also be set to the current time, and the time zone
- * will be set the the system's default time zone.
- *
- */
- public CronTrigger(String name, String group, String cronExpression)
- throws ParseException {
- super(name, group);
-
- setCronExpression(cronExpression);
-
- setStartTime(new Date());
- setTimeZone(TimeZone.getDefault());
- }
-
- /**
- *
- * Create a CronTrigger with the given name and group, and
- * associated with the identified {@link org.quartz.JobDetail}.
- *
- *
- *
- * The start-time will also be set to the current time, and the time zone
- * will be set the the system's default time zone.
- *
- */
- public CronTrigger(String name, String group, String jobName,
- String jobGroup) {
- super(name, group, jobName, jobGroup);
- setStartTime(new Date());
- setTimeZone(TimeZone.getDefault());
- }
-
- /**
- *
- * Create a CronTrigger with the given name and group,
- * associated with the identified {@link org.quartz.JobDetail},
- * and with the given "cron" expression.
- *
- *
- *
- * The start-time will also be set to the current time, and the time zone
- * will be set the the system's default time zone.
- *
- */
- public CronTrigger(String name, String group, String jobName,
- String jobGroup, String cronExpression) throws ParseException {
- this(name, group, jobName, jobGroup, null, null, cronExpression,
- TimeZone.getDefault());
- }
-
- /**
- *
- * Create a CronTrigger with the given name and group,
- * associated with the identified {@link org.quartz.JobDetail},
- * and with the given "cron" expression resolved with respect to the TimeZone.
- *
- */
- public CronTrigger(String name, String group, String jobName,
- String jobGroup, String cronExpression, TimeZone timeZone)
- throws ParseException {
- this(name, group, jobName, jobGroup, null, null, cronExpression,
- timeZone);
- }
-
- /**
- *
- * Create a CronTrigger that will occur at the given time,
- * until the given end time.
- *
- *
- *
- * If null, the start-time will also be set to the current time, the time
- * zone will be set the the system's default.
- *
- *
- * @param startTime
- * A Date set to the time for the Trigger
- * to fire.
- * @param endTime
- * A Date set to the time for the Trigger
- * to quit repeat firing.
- */
- public CronTrigger(String name, String group, String jobName,
- String jobGroup, Date startTime, Date endTime, String cronExpression)
- throws ParseException {
- super(name, group, jobName, jobGroup);
-
- setCronExpression(cronExpression);
-
- if (startTime == null) startTime = new Date();
- setStartTime(startTime);
- if (endTime != null) setEndTime(endTime);
- setTimeZone(TimeZone.getDefault());
-
- }
-
- /**
- *
- * Create a CronTrigger with fire time dictated by the
- * cronExpression resolved with respect to the specified
- * timeZone occuring from the startTime until
- * the given endTime.
- *
- *
- *
- * If null, the start-time will also be set to the current time. If null,
- * the time zone will be set to the system's default.
- *
- *
- * @param name
- * of the Trigger
- * @param group
- * of the Trigger
- * @param jobName,
- * name of the {@link org.quartz.JobDetail}
- * executed on firetime
- * @param jobGroup,
- * group of the {@link org.quartz.JobDetail}
- * executed on firetime
- * @param startTime
- * A Date set to the earliest time for the Trigger
- * to start firing.
- * @param endTime
- * A Date set to the time for the Trigger
- * to quit repeat firing.
- * @param cronExpression,
- * A cron expression dictating the firing sequence of the Trigger
- * @param timeZone,
- * Specifies for which time zone the cronExpression
- * should be interprted, i.e. the expression 0 0 10 * * ?, is
- * resolved to 10:00 am in this time zone.
- * @throws ParseException
- * if the cronExpression is invalid.
- */
- public CronTrigger(String name, String group, String jobName,
- String jobGroup, Date startTime, Date endTime,
- String cronExpression, TimeZone timeZone) throws ParseException {
- super(name, group, jobName, jobGroup);
-
- setCronExpression(cronExpression);
-
- if (startTime == null) startTime = new Date();
- setStartTime(startTime);
- if (endTime != null) setEndTime(endTime);
- if (timeZone == null) {
- setTimeZone(TimeZone.getDefault());
- } else {
- setTimeZone(timeZone);
- }
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public Object clone() {
- CronTrigger copy = (CronTrigger) super.clone();
- copy.setCronExpression((CronExpression)cronEx.clone());
- return copy;
- }
-
- public void setCronExpression(String cronExpression) throws ParseException {
- this.cronEx = new CronExpression(cronExpression);
- this.cronEx.setTimeZone(getTimeZone());
- }
-
- public String getCronExpression() {
- return cronEx == null ? null : cronEx.getCronExpression();
- }
-
- public void setCronExpression(CronExpression cronExpression) {
- this.cronEx = cronExpression;
- this.timeZone = cronExpression.getTimeZone();
- }
-
- /**
- *
- * Get the time at which the CronTrigger should occur.
- *
- */
- public Date getStartTime() {
- return this.startTime;
- }
-
- public void setStartTime(Date startTime) {
- if (startTime == null)
- throw new IllegalArgumentException("Start time cannot be null");
-
- Date eTime = getEndTime();
- if (eTime != null && startTime != null && eTime.before(startTime))
- throw new IllegalArgumentException(
- "End time cannot be before start time");
-
- // round off millisecond...
- // Note timeZone is not needed here as parameter for
- // Calendar.getInstance(),
- // since time zone is implicit when using a Date in the setTime method.
- Calendar cl = Calendar.getInstance();
- cl.setTime(startTime);
- cl.set(Calendar.MILLISECOND, 0);
-
- this.startTime = cl.getTime();
- }
-
- /**
- *
- * Get the time at which the CronTrigger should quit
- * repeating - even if repeastCount isn't yet satisfied.
- *
- *
- * @see #getFinalFireTime()
- */
- public Date getEndTime() {
- return this.endTime;
- }
-
- public void setEndTime(Date endTime) {
- Date sTime = getStartTime();
- if (sTime != null && endTime != null && sTime.after(endTime))
- throw new IllegalArgumentException(
- "End time cannot be before start time");
-
- this.endTime = endTime;
- }
-
- /**
- *
- * Returns the next time at which the CronTrigger 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 Date getNextFireTime() {
- return this.nextFireTime;
- }
-
- /**
- *
- * Returns the previous time at which the CronTrigger will
- * fire. If the trigger has not yet fired, null will be
- * returned.
- */
- public Date getPreviousFireTime() {
- return this.previousFireTime;
- }
-
- /**
- *
- * Sets the next time at which the CronTrigger will fire.
- * This method should not be invoked by client code.
- *
- */
- public void setNextFireTime(Date nextFireTime) {
- this.nextFireTime = nextFireTime;
- }
-
- /**
- *
- * Set the previous time at which the SimpleTrigger fired.
- *
- *
- *
- * This method should not be invoked by client code.
- *
- */
- public void setPreviousFireTime(Date previousFireTime) {
- this.previousFireTime = previousFireTime;
- }
-
- /**
- *
* Returns the time zone for which the cronExpression of
* this CronTrigger will be resolved.
*
*/
- public TimeZone getTimeZone() {
-
- if(cronEx != null) return cronEx.getTimeZone();
-
- if (timeZone == null) timeZone = TimeZone.getDefault();
- return timeZone;
- }
+ public TimeZone getTimeZone();
- /**
- *
- * Sets the time zone for which the cronExpression of this
- * CronTrigger will be resolved.
- *
- */
- public void setTimeZone(TimeZone timeZone) {
- if(cronEx != null) cronEx.setTimeZone(timeZone);
- this.timeZone = timeZone;
- }
+ public String getExpressionSummary();
- /**
- *
- * Returns the next time at which the CronTrigger will fire,
- * after the given time. If the trigger will not fire after the given time,
- * null will be returned.
- *
- *
- *
- * Note that the date returned is NOT validated against the related
- * org.quartz.Calendar (if any)
- *
- */
- public Date getFireTimeAfter(Date afterTime) {
- if (afterTime == null) afterTime = new Date();
-
- if (startTime.after(afterTime))
- afterTime = new Date(startTime.getTime() - 1000l);
-
- Date pot = getTimeAfter(afterTime);
- if (endTime != null && pot != null && pot.after(endTime)) return null;
-
- return pot;
- }
-
- /**
- *
- * Returns the final time at which the CronTrigger will
- * fire.
- *
- *
- *
- * Note that the return time *may* be in the past. and the date returned is
- * not validated against org.quartz.calendar
- *
- */
- public Date getFinalFireTime() {
- if (this.endTime != null) return getTimeBefore(this.endTime);
- else
- return null;
- }
-
- /**
- *
- * Determines whether or not the CronTrigger will occur
- * again.
- *
- */
- public boolean mayFireAgain() {
- return (getNextFireTime() != null);
- }
-
- protected boolean validateMisfireInstruction(int misfireInstruction) {
- if (misfireInstruction < MISFIRE_INSTRUCTION_SMART_POLICY)
- return false;
-
- if (misfireInstruction > MISFIRE_INSTRUCTION_DO_NOTHING) return false;
-
- return true;
- }
-
- /**
- *
- * Updates the CronTrigger's state based on the
- * MISFIRE_INSTRUCTION_XXX that was selected when the SimpleTrigger
- * was created.
- *
- *
- *
- * If the misfire instruction is set to MISFIRE_INSTRUCTION_SMART_POLICY,
- * then the following scheme will be used:
- *
- * - The instruction will be interpreted as
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
- *
- *
- */
- public void updateAfterMisfire(org.quartz.Calendar cal) {
- int instr = getMisfireInstruction();
-
- if (instr == MISFIRE_INSTRUCTION_SMART_POLICY)
- instr = MISFIRE_INSTRUCTION_FIRE_ONCE_NOW;
-
- if (instr == MISFIRE_INSTRUCTION_DO_NOTHING) {
- Date newFireTime = getFireTimeAfter(new Date());
- while (newFireTime != null && cal != null
- && !cal.isTimeIncluded(newFireTime.getTime())) {
- newFireTime = getFireTimeAfter(newFireTime);
- }
- setNextFireTime(newFireTime);
- } else if (instr == MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) {
- setNextFireTime(new Date());
- }
- }
-
- /**
- *
- * Determines whether the date and (optionally) time of the given Calendar
- * instance falls on a scheduled fire-time of this trigger.
- *
- *
- *
- * Equivalent to calling willFireOn(cal, false).
- *
- *
- * @param test the date to compare
- *
- * @see #willFireOn(Calendar, boolean)
- */
- public boolean willFireOn(Calendar test) {
- return willFireOn(test, false);
- }
-
- /**
- *
- * Determines whether the date and (optionally) time of the given Calendar
- * instance falls on a scheduled fire-time of this trigger.
- *
- *
- *
- * Note that the value returned is NOT validated against the related
- * org.quartz.Calendar (if any)
- *
- *
- * @param test the date to compare
- * @param dayOnly if set to true, the method will only determine if the
- * trigger will fire during the day represented by the given Calendar
- * (hours, minutes and seconds will be ignored).
- * @see #willFireOn(Calendar)
- */
- public boolean willFireOn(Calendar test, boolean dayOnly) {
-
- test = (Calendar) test.clone();
-
- test.set(Calendar.MILLISECOND, 0); // don't compare millis.
-
- if(dayOnly) {
- test.set(Calendar.HOUR, 0);
- test.set(Calendar.MINUTE, 0);
- test.set(Calendar.SECOND, 0);
- }
-
- Date testTime = test.getTime();
-
- Date fta = getFireTimeAfter(new Date(test.getTime().getTime() - 1000));
-
- Calendar p = Calendar.getInstance(test.getTimeZone());
- p.setTime(fta);
-
- int year = p.get(Calendar.YEAR);
- int month = p.get(Calendar.MONTH);
- int day = p.get(Calendar.DATE);
-
- if(dayOnly) {
- return (year == test.get(Calendar.YEAR)
- && month == test.get(Calendar.MONTH)
- && day == test.get(Calendar.DATE));
- }
-
- while(fta.before(testTime)) {
- fta = getFireTimeAfter(fta);
- }
-
- if(fta.equals(testTime))
- return true;
-
- return false;
- }
-
- /**
- *
- * 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 int executionComplete(JobExecutionContext context,
- JobExecutionException result) {
- if (result != null && result.refireImmediately())
- return INSTRUCTION_RE_EXECUTE_JOB;
-
- if (result != null && result.unscheduleFiringTrigger())
- return INSTRUCTION_SET_TRIGGER_COMPLETE;
-
- if (result != null && result.unscheduleAllTriggers())
- return INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE;
-
- if (!mayFireAgain()) return INSTRUCTION_DELETE_TRIGGER;
-
- return INSTRUCTION_NOOP;
- }
-
- /**
- *
- * 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 void triggered(org.quartz.Calendar calendar) {
- previousFireTime = nextFireTime;
- nextFireTime = getFireTimeAfter(nextFireTime);
-
- while (nextFireTime != null && calendar != null
- && !calendar.isTimeIncluded(nextFireTime.getTime())) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- }
- }
-
- /**
- *
- * @see org.quartz.Trigger#updateWithNewCalendar(org.quartz.Calendar, long)
- */
- public void updateWithNewCalendar(org.quartz.Calendar calendar, long misfireThreshold)
- {
- nextFireTime = getFireTimeAfter(previousFireTime);
-
- Date now = new Date();
- do {
- while (nextFireTime != null && calendar != null
- && !calendar.isTimeIncluded(nextFireTime.getTime())) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- }
-
- if(nextFireTime != null && nextFireTime.before(now)) {
- long diff = now.getTime() - nextFireTime.getTime();
- if(diff >= misfireThreshold) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- continue;
- }
- }
- }while(false);
- }
-
- /**
- *
- * 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 Date computeFirstFireTime(org.quartz.Calendar calendar) {
- nextFireTime = getFireTimeAfter(new Date(startTime.getTime() - 1000l));
-
- while (nextFireTime != null && calendar != null
- && !calendar.isTimeIncluded(nextFireTime.getTime())) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- }
-
- return nextFireTime;
- }
-
- public String getExpressionSummary() {
- return cronEx == null ? null : cronEx.getExpressionSummary();
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Computation Functions
- //
- ////////////////////////////////////////////////////////////////////////////
-
- protected Date getTimeAfter(Date afterTime) {
- return cronEx.getTimeAfter(afterTime);
- }
-
- protected Date getTimeBefore(Date endTime)
- {
- return null;
- }
-
- public static void main(String[] args) // TODO: remove method after good
- // unit testing
- throws Exception {
-
- String expr = "15 10 0/4 * * ?";
- if(args != null && args.length > 0 && args[0] != null)
- expr = args[0];
-
- CronTrigger ct = new CronTrigger("t", "g", "j", "g", new Date(), null, expr);
- ct.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
- System.err.println(ct.getExpressionSummary());
- System.err.println("tz=" + ct.getTimeZone().getID());
- System.err.println();
-
- java.util.List times = TriggerUtils.computeFireTimes(ct, null, 25);
-
- for (int i = 0; i < times.size(); i++) {
- System.err.println("firetime = " + times.get(i));
- }
-
- Calendar tt = Calendar.getInstance();
- tt.set(Calendar.DATE, 17);
- tt.set(Calendar.MONTH, 5 - 1);
- tt.set(Calendar.HOUR, 11);
- tt.set(Calendar.MINUTE, 0);
- tt.set(Calendar.SECOND, 7);
-
- System.err.println("\nWill fire on: " + tt.getTime() + " -- " + ct.willFireOn(tt, false));
-
-
-// CRON Expression: 0 0 9 * * ?
-//
-// TimeZone.getDefault().getDisplayName() = Central African Time
-// TimeZone.getDefault().getID() = Africa/Harare
- //
-//// System.err.println();
-//// System.err.println();
-//// System.err.println();
-//// System.err.println("Daylight test:");
-////
-//// CronTrigger trigger = new CronTrigger();
-////
-//// TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles");
-//// // TimeZone timeZone = TimeZone.getDefault();
-////
-//// trigger.setTimeZone(timeZone);
-//// trigger.setCronExpression("0 0 1 ? 4 *");
-////
-//// Date start = new Date(1056319200000L);
-//// Date end = new Date(1087682399000L);
-////
-//// trigger.setStartTime(start);
-//// trigger.setEndTime(end);
-////
-//// Date next = new Date(1056232800000L);
-//// while (next != null) {
-//// next = trigger.getFireTimeAfter(next);
-//// if (next != null) {
-//// Calendar cal = Calendar.getInstance();
-//// cal.setTimeZone(timeZone);
-//// cal.setTime(next);
-//// System.err.println(cal.get(Calendar.MONTH) + "/"
-//// + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR)
-//// + " - " + cal.get(Calendar.HOUR_OF_DAY) + ":"
-//// + cal.get(Calendar.MINUTE));
-//// }
-//// }
-////
-//// System.err.println();
-//// System.err.println();
-//// System.err.println();
-//// System.err.println("Midnight test:");
-////
-//// trigger = new CronTrigger();
-////
-//// timeZone = TimeZone.getTimeZone("Asia/Jerusalem");
-//// // timeZone = TimeZone.getTimeZone("America/Los_Angeles");
-//// // TimeZone timeZone = TimeZone.getDefault();
-////
-//// trigger.setTimeZone(timeZone);
-//// trigger.setCronExpression("0 /15 * ? 4 *");
-////
-//// start = new Date(1056319200000L);
-//// end = new Date(1087682399000L);
-////
-//// trigger.setStartTime(start);
-//// trigger.setEndTime(end);
-////
-//// next = new Date(1056232800000L);
-//// while (next != null) {
-//// next = trigger.getFireTimeAfter(next);
-//// if (next != null) {
-//// Calendar cal = Calendar.getInstance();
-//// cal.setTimeZone(timeZone);
-//// cal.setTime(next);
-//// System.err.println(cal.get(Calendar.MONTH) + "/"
-//// + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR)
-//// + " - " + cal.get(Calendar.HOUR_OF_DAY) + ":"
-//// + cal.get(Calendar.MINUTE));
-//// }
-//// }
-
- }
+ TriggerBuilder getTriggerBuilder();
}
-
Index: 3rdParty_sources/quartz/org/quartz/DailyTimeIntervalScheduleBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/DailyTimeIntervalScheduleBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/DailyTimeIntervalScheduleBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,413 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+package org.quartz;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.quartz.DateBuilder.IntervalUnit;
+import org.quartz.impl.triggers.DailyTimeIntervalTriggerImpl;
+import org.quartz.spi.MutableTrigger;
+
+/**
+ * A {@link ScheduleBuilder} implementation that build schedule for DailyTimeIntervalTrigger.
+ *
+ * This builder provide an extra convenient method for you to set the trigger's endTimeOfDay. You may
+ * use either endingDailyAt() or endingDailyAfterCount() to set the value. The later will auto calculate
+ * your endTimeOfDay by using the interval, intervalUnit and startTimeOfDay to perform the calculation.
+ *
+ *
When using endingDailyAfterCount(), you should note that it is used to calculating endTimeOfDay. So
+ * if your startTime on the first day is already pass by a time that would not add up to the count you
+ * expected, until the next day comes. Remember that DailyTimeIntervalTrigger will use startTimeOfDay
+ * and endTimeOfDay as fresh per each day!
+ *
+ *
Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(onDaysOfTheWeek(MONDAY, THURSDAY))
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ * @since 2.1.0
+ *
+ * @author James House
+ * @author Zemian Deng
+ */
+public class DailyTimeIntervalScheduleBuilder extends ScheduleBuilder {
+
+ private int interval = 1;
+ private IntervalUnit intervalUnit = IntervalUnit.MINUTE;
+ private Set daysOfWeek;
+ private TimeOfDay startTimeOfDay;
+ private TimeOfDay endTimeOfDay;
+ private int repeatCount = DailyTimeIntervalTrigger.REPEAT_INDEFINITELY;
+
+ private int misfireInstruction = CalendarIntervalTrigger.MISFIRE_INSTRUCTION_SMART_POLICY;
+
+ /**
+ * A set of all days of the week.
+ *
+ * The set contains all values between {@link java.util.Calendar#SUNDAY} and {@link java.util.Calendar#SATURDAY}
+ * (the integers from 1 through 7).
+ */
+ public static final Set ALL_DAYS_OF_THE_WEEK;
+
+ /**
+ * A set of the business days of the week (for locales similar to the USA).
+ *
+ * The set contains all values between {@link java.util.Calendar#MONDAY} and {@link java.util.Calendar#FRIDAY}
+ * (the integers from 2 through 6).
+ */
+ public static final Set MONDAY_THROUGH_FRIDAY;
+
+ /**
+ * A set of the weekend days of the week (for locales similar to the USA).
+ *
+ * The set contains {@link java.util.Calendar#SATURDAY} and {@link java.util.Calendar#SUNDAY}
+ */
+ public static final Set SATURDAY_AND_SUNDAY;
+
+ static {
+ Set t = new HashSet(7);
+ for(int i=Calendar.SUNDAY; i <= Calendar.SATURDAY; i++)
+ t.add(i);
+ ALL_DAYS_OF_THE_WEEK = Collections.unmodifiableSet(t);
+
+ t = new HashSet(5);
+ for(int i=Calendar.MONDAY; i <= Calendar.FRIDAY; i++)
+ t.add(i);
+ MONDAY_THROUGH_FRIDAY = Collections.unmodifiableSet(t);
+
+ t = new HashSet(2);
+ t.add(Calendar.SUNDAY);
+ t.add(Calendar.SATURDAY);
+ SATURDAY_AND_SUNDAY = Collections.unmodifiableSet(t);
+ }
+
+ protected DailyTimeIntervalScheduleBuilder() {
+ }
+
+ /**
+ * Create a DailyTimeIntervalScheduleBuilder.
+ *
+ * @return the new DailyTimeIntervalScheduleBuilder
+ */
+ public static DailyTimeIntervalScheduleBuilder dailyTimeIntervalSchedule() {
+ return new DailyTimeIntervalScheduleBuilder();
+ }
+
+ /**
+ * Build the actual Trigger -- NOT intended to be invoked by end users,
+ * but will rather be invoked by a TriggerBuilder which this
+ * ScheduleBuilder is given to.
+ *
+ * @see TriggerBuilder#withSchedule(ScheduleBuilder)
+ */
+ @Override
+ public MutableTrigger build() {
+
+ DailyTimeIntervalTriggerImpl st = new DailyTimeIntervalTriggerImpl();
+ st.setRepeatInterval(interval);
+ st.setRepeatIntervalUnit(intervalUnit);
+ st.setMisfireInstruction(misfireInstruction);
+ st.setRepeatCount(repeatCount);
+
+ if(daysOfWeek != null)
+ st.setDaysOfWeek(daysOfWeek);
+ else
+ st.setDaysOfWeek(ALL_DAYS_OF_THE_WEEK);
+
+ if(startTimeOfDay != null)
+ st.setStartTimeOfDay(startTimeOfDay);
+ else
+ st.setStartTimeOfDay(TimeOfDay.hourAndMinuteOfDay(0, 0));
+
+ if(endTimeOfDay != null)
+ st.setEndTimeOfDay(endTimeOfDay);
+ else
+ st.setEndTimeOfDay(TimeOfDay.hourMinuteAndSecondOfDay(23, 59, 59));
+
+ return st;
+ }
+
+ /**
+ * Specify the time unit and interval for the Trigger to be produced.
+ *
+ * @param timeInterval the interval at which the trigger should repeat.
+ * @param unit the time unit (IntervalUnit) of the interval. The only intervals that are valid for this type of
+ * trigger are {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}.
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ * @see DailyTimeIntervalTrigger#getRepeatInterval()
+ * @see DailyTimeIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public DailyTimeIntervalScheduleBuilder withInterval(int timeInterval, IntervalUnit unit) {
+ if (unit == null || !(unit.equals(IntervalUnit.SECOND) ||
+ unit.equals(IntervalUnit.MINUTE) ||unit.equals(IntervalUnit.HOUR)))
+ throw new IllegalArgumentException("Invalid repeat IntervalUnit (must be SECOND, MINUTE or HOUR).");
+ validateInterval(timeInterval);
+ this.interval = timeInterval;
+ this.intervalUnit = unit;
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.SECOND that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInSeconds the number of seconds at which the trigger should repeat.
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ * @see DailyTimeIntervalTrigger#getRepeatInterval()
+ * @see DailyTimeIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public DailyTimeIntervalScheduleBuilder withIntervalInSeconds(int intervalInSeconds) {
+ withInterval(intervalInSeconds, IntervalUnit.SECOND);
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.MINUTE that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInMinutes the number of minutes at which the trigger should repeat.
+ * @return the updated CalendarIntervalScheduleBuilder
+ * @see DailyTimeIntervalTrigger#getRepeatInterval()
+ * @see DailyTimeIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public DailyTimeIntervalScheduleBuilder withIntervalInMinutes(int intervalInMinutes) {
+ withInterval(intervalInMinutes, IntervalUnit.MINUTE);
+ return this;
+ }
+
+ /**
+ * Specify an interval in the IntervalUnit.HOUR that the produced
+ * Trigger will repeat at.
+ *
+ * @param intervalInHours the number of hours at which the trigger should repeat.
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ * @see DailyTimeIntervalTrigger#getRepeatInterval()
+ * @see DailyTimeIntervalTrigger#getRepeatIntervalUnit()
+ */
+ public DailyTimeIntervalScheduleBuilder withIntervalInHours(int intervalInHours) {
+ withInterval(intervalInHours, IntervalUnit.HOUR);
+ return this;
+ }
+
+ /**
+ * Set the trigger to fire on the given days of the week.
+ *
+ * @param onDaysOfWeek a Set containing the integers representing the days of the week, per the values 1-7 as defined by
+ * {@link java.util.Calendar#SUNDAY} - {@link java.util.Calendar#SATURDAY}.
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder onDaysOfTheWeek(Set onDaysOfWeek) {
+ if(onDaysOfWeek == null || onDaysOfWeek.size() == 0)
+ throw new IllegalArgumentException("Days of week must be an non-empty set.");
+ for (Integer day : onDaysOfWeek)
+ if (!ALL_DAYS_OF_THE_WEEK.contains(day))
+ throw new IllegalArgumentException("Invalid value for day of week: " + day);
+
+ this.daysOfWeek = onDaysOfWeek;
+ return this;
+ }
+
+ /**
+ * Set the trigger to fire on the given days of the week.
+ *
+ * @param onDaysOfWeek a variable length list of Integers representing the days of the week, per the values 1-7 as
+ * defined by {@link java.util.Calendar#SUNDAY} - {@link java.util.Calendar#SATURDAY}.
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder onDaysOfTheWeek(Integer ... onDaysOfWeek) {
+ Set daysAsSet = new HashSet(12);
+ Collections.addAll(daysAsSet, onDaysOfWeek);
+ return onDaysOfTheWeek(daysAsSet);
+ }
+
+ /**
+ * Set the trigger to fire on the days from Monday through Friday.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder onMondayThroughFriday() {
+ this.daysOfWeek = MONDAY_THROUGH_FRIDAY;
+ return this;
+ }
+
+ /**
+ * Set the trigger to fire on the days Saturday and Sunday.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder onSaturdayAndSunday() {
+ this.daysOfWeek = SATURDAY_AND_SUNDAY;
+ return this;
+ }
+
+ /**
+ * Set the trigger to fire on all days of the week.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder onEveryDay() {
+ this.daysOfWeek = ALL_DAYS_OF_THE_WEEK;
+ return this;
+ }
+
+ /**
+ * Set the trigger to begin firing each day at the given time.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder startingDailyAt(TimeOfDay timeOfDay) {
+ if(timeOfDay == null)
+ throw new IllegalArgumentException("Start time of day cannot be null!");
+
+ this.startTimeOfDay = timeOfDay;
+ return this;
+ }
+
+ /**
+ * Set the startTimeOfDay for this trigger to end firing each day at the given time.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder endingDailyAt(TimeOfDay timeOfDay) {
+ this.endTimeOfDay = timeOfDay;
+ return this;
+ }
+
+ /**
+ * Calculate and set the endTimeOfDay using count, interval and starTimeOfDay. This means
+ * that these must be set before this method is call.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder endingDailyAfterCount(int count) {
+ if(count <=0)
+ throw new IllegalArgumentException("Ending daily after count must be a positive number!");
+
+ if(startTimeOfDay == null)
+ throw new IllegalArgumentException("You must set the startDailyAt() before calling this endingDailyAfterCount()!");
+
+ Date today = new Date();
+ Date startTimeOfDayDate = startTimeOfDay.getTimeOfDayForDate(today);
+ Date maxEndTimeOfDayDate = TimeOfDay.hourMinuteAndSecondOfDay(23, 59, 59).getTimeOfDayForDate(today);
+ long remainingMillisInDay = maxEndTimeOfDayDate.getTime() - startTimeOfDayDate.getTime();
+ long intervalInMillis;
+ if (intervalUnit == IntervalUnit.SECOND)
+ intervalInMillis = interval * 1000L;
+ else if (intervalUnit == IntervalUnit.MINUTE)
+ intervalInMillis = interval * 1000L * 60;
+ else if (intervalUnit == IntervalUnit.HOUR)
+ intervalInMillis = interval * 1000L * 60 * 24;
+ else
+ throw new IllegalArgumentException("The IntervalUnit: " + intervalUnit + " is invalid for this trigger.");
+
+ if (remainingMillisInDay - intervalInMillis <= 0)
+ throw new IllegalArgumentException("The startTimeOfDay is too late with given Interval and IntervalUnit values.");
+
+ long maxNumOfCount = (remainingMillisInDay / intervalInMillis);
+ if (count > maxNumOfCount)
+ throw new IllegalArgumentException("The given count " + count + " is too large! The max you can set is " + maxNumOfCount);
+
+ long incrementInMillis = (count - 1) * intervalInMillis;
+ Date endTimeOfDayDate = new Date(startTimeOfDayDate.getTime() + incrementInMillis);
+
+ if (endTimeOfDayDate.getTime() > maxEndTimeOfDayDate.getTime())
+ throw new IllegalArgumentException("The given count " + count + " is too large! The max you can set is " + maxNumOfCount);
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(endTimeOfDayDate);
+ int hour = cal.get(Calendar.HOUR_OF_DAY);
+ int minute = cal.get(Calendar.MINUTE);
+ int second = cal.get(Calendar.SECOND);
+
+ endTimeOfDay = TimeOfDay.hourMinuteAndSecondOfDay(hour, minute, second);
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY} instruction.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ * @see Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
+ */
+ public DailyTimeIntervalScheduleBuilder withMisfireHandlingInstructionIgnoreMisfires() {
+ misfireInstruction = Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link DailyTimeIntervalTrigger#MISFIRE_INSTRUCTION_DO_NOTHING} instruction.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ * @see DailyTimeIntervalTrigger#MISFIRE_INSTRUCTION_DO_NOTHING
+ */
+ public DailyTimeIntervalScheduleBuilder withMisfireHandlingInstructionDoNothing() {
+ misfireInstruction = DailyTimeIntervalTrigger.MISFIRE_INSTRUCTION_DO_NOTHING;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link DailyTimeIntervalTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW} instruction.
+ *
+ * @return the updated DailyTimeIntervalScheduleBuilder
+ * @see DailyTimeIntervalTrigger#MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
+ */
+ public DailyTimeIntervalScheduleBuilder withMisfireHandlingInstructionFireAndProceed() {
+ misfireInstruction = CalendarIntervalTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW;
+ return this;
+ }
+
+ /**
+ * Set number of times for interval to repeat.
+ *
+ * Note: if you want total count = 1 (at start time) + repeatCount
+ *
+ * @return the new DailyTimeIntervalScheduleBuilder
+ */
+ public DailyTimeIntervalScheduleBuilder withRepeatCount(int repeatCount) {
+ this.repeatCount = repeatCount;
+ return this;
+ }
+
+ private void validateInterval(int timeInterval) {
+ if(timeInterval <= 0)
+ throw new IllegalArgumentException("Interval must be a positive value.");
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/DailyTimeIntervalTrigger.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/DailyTimeIntervalTrigger.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/DailyTimeIntervalTrigger.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,138 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+package org.quartz;
+
+import java.util.Calendar;
+import java.util.Set;
+
+import org.quartz.DateBuilder.IntervalUnit;
+
+/**
+ * A {@link Trigger} that is used to fire a {@link org.quartz.JobDetail}
+ * based upon daily repeating time intervals.
+ *
+ * The trigger will fire every N (see {@link #getRepeatInterval()} ) seconds, minutes or hours
+ * (see {@link #getRepeatIntervalUnit()}) during a given time window on specified days of the week.
+ *
+ * For example#1, a trigger can be set to fire every 72 minutes between 8:00 and 11:00 everyday. It's fire times would
+ * be 8:00, 9:12, 10:24, then next day would repeat: 8:00, 9:12, 10:24 again.
+ *
+ * For example#2, a trigger can be set to fire every 23 minutes between 9:20 and 16:47 Monday through Friday.
+ *
+ * On each day, the starting fire time is reset to startTimeOfDay value, and then it will add repeatInterval value to it until
+ * the endTimeOfDay is reached. If you set daysOfWeek values, then fire time will only occur during those week days period.
+ *
+ * The default values for fields if not set are: startTimeOfDay defaults to 00:00:00, the endTimeOfDay default to 23:59:59,
+ * and daysOfWeek is default to every day. The startTime default to current time-stamp now, while endTime has not value.
+ *
+ * If startTime is before startTimeOfDay, then it has no affect. Else if startTime after startTimeOfDay, then the first fire time
+ * for that day will be normal startTimeOfDay incremental values after startTime value. Same reversal logic is applied to endTime
+ * with endTimeOfDay.
+ *
+ * @see DailyTimeIntervalScheduleBuilder
+ *
+ * @since 2.1.0
+ *
+ * @author James House
+ * @author Zemian Deng
+ */
+public interface DailyTimeIntervalTrigger extends Trigger {
+
+ /**
+ *
+ * Used to indicate the 'repeat count' of the trigger is indefinite. Or in
+ * other words, the trigger should repeat continually until the trigger's
+ * ending timestamp.
+ *
+ */
+ public static final int REPEAT_INDEFINITELY = -1;
+
+ /**
+ *
+ * Instructs the {@link Scheduler} that upon a mis-fire
+ * situation, the {@link DailyTimeIntervalTrigger} wants to be
+ * fired now by Scheduler.
+ *
+ */
+ public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
+
+ /**
+ *
+ * Instructs the {@link Scheduler} that upon a mis-fire
+ * situation, the {@link DailyTimeIntervalTrigger} wants to have it's
+ * next-fire-time updated to the next time in the schedule after the
+ * current time (taking into account any associated {@link Calendar},
+ * but it does not want to be fired now.
+ *
+ */
+ public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
+
+ /**
+ * Get the interval unit - the time unit on with the interval applies.
+ *
+ * The only intervals that are valid for this type of trigger are {@link IntervalUnit#SECOND},
+ * {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}.
+ */
+ public IntervalUnit getRepeatIntervalUnit();
+
+ /**
+ *
+ * Get the the number of times for interval this trigger should
+ * repeat, after which it will be automatically deleted.
+ *
+ *
+ * @see #REPEAT_INDEFINITELY
+ */
+ public int getRepeatCount();
+
+ /**
+ *
+ * Get the the time interval that will be added to the DateIntervalTrigger's
+ * fire time (in the set repeat interval unit) in order to calculate the time of the
+ * next trigger repeat.
+ *
+ */
+ public int getRepeatInterval();
+
+ /**
+ * The time of day to start firing at the given interval.
+ */
+ public TimeOfDay getStartTimeOfDay();
+
+ /**
+ * The time of day to complete firing at the given interval.
+ */
+ public TimeOfDay getEndTimeOfDay();
+
+ /**
+ * The days of the week upon which to fire.
+ *
+ * @return a Set containing the integers representing the days of the week, per the values 1-7 as defined by
+ * {@link java.util.Calendar#SUNDAY} - {@link java.util.Calendar#SATURDAY}.
+ */
+ public Set getDaysOfWeek();
+
+ /**
+ *
+ * Get the number of times the DateIntervalTrigger has already
+ * fired.
+ *
+ */
+ public int getTimesTriggered();
+
+ public TriggerBuilder getTriggerBuilder();
+}
Index: 3rdParty_sources/quartz/org/quartz/DateBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/DateBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/DateBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,1021 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * DateBuilder is used to conveniently create
+ * java.util.Date instances that meet particular criteria.
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(simpleSchedule()
+ * .withIntervalInHours(1)
+ * .repeatForever())
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ * @see TriggerBuilder
+ * @see JobBuilder
+ */
+public class DateBuilder {
+
+ public enum IntervalUnit { MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR }
+
+ public static final int SUNDAY = 1;
+
+ public static final int MONDAY = 2;
+
+ public static final int TUESDAY = 3;
+
+ public static final int WEDNESDAY = 4;
+
+ public static final int THURSDAY = 5;
+
+ public static final int FRIDAY = 6;
+
+ public static final int SATURDAY = 7;
+
+ public static final int JANUARY = 1;
+
+ public static final int FEBRUARY = 2;
+
+ public static final int MARCH = 3;
+
+ public static final int APRIL = 4;
+
+ public static final int MAY = 5;
+
+ public static final int JUNE = 6;
+
+ public static final int JULY = 7;
+
+ public static final int AUGUST = 8;
+
+ public static final int SEPTEMBER = 9;
+
+ public static final int OCTOBER = 10;
+
+ public static final int NOVEMBER = 11;
+
+ public static final int DECEMBER = 12;
+
+ public static final long MILLISECONDS_IN_MINUTE = 60l * 1000l;
+
+ public static final long MILLISECONDS_IN_HOUR = 60l * 60l * 1000l;
+
+ public static final long SECONDS_IN_MOST_DAYS = 24l * 60l * 60L;
+
+ public static final long MILLISECONDS_IN_DAY = SECONDS_IN_MOST_DAYS * 1000l;
+
+ private int month;
+ private int day;
+ private int year;
+ private int hour;
+ private int minute;
+ private int second;
+ private TimeZone tz;
+ private Locale lc;
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the system default timezone.
+ */
+ private DateBuilder() {
+ Calendar cal = Calendar.getInstance();
+
+ month = cal.get(Calendar.MONTH) + 1;
+ day = cal.get(Calendar.DAY_OF_MONTH);
+ year = cal.get(Calendar.YEAR);
+ hour = cal.get(Calendar.HOUR_OF_DAY);
+ minute = cal.get(Calendar.MINUTE);
+ second = cal.get(Calendar.SECOND);
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the given timezone.
+ */
+ private DateBuilder(TimeZone tz) {
+ Calendar cal = Calendar.getInstance(tz);
+
+ this.tz = tz;
+ month = cal.get(Calendar.MONTH) + 1;
+ day = cal.get(Calendar.DAY_OF_MONTH);
+ year = cal.get(Calendar.YEAR);
+ hour = cal.get(Calendar.HOUR_OF_DAY);
+ minute = cal.get(Calendar.MINUTE);
+ second = cal.get(Calendar.SECOND);
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the given locale.
+ */
+ private DateBuilder(Locale lc) {
+ Calendar cal = Calendar.getInstance(lc);
+
+ this.lc = lc;
+ month = cal.get(Calendar.MONTH) + 1;
+ day = cal.get(Calendar.DAY_OF_MONTH);
+ year = cal.get(Calendar.YEAR);
+ hour = cal.get(Calendar.HOUR_OF_DAY);
+ minute = cal.get(Calendar.MINUTE);
+ second = cal.get(Calendar.SECOND);
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the given timezone and locale.
+ */
+ private DateBuilder(TimeZone tz, Locale lc) {
+ Calendar cal = Calendar.getInstance(tz, lc);
+
+ this.tz = tz;
+ this.lc = lc;
+ month = cal.get(Calendar.MONTH) + 1;
+ day = cal.get(Calendar.DAY_OF_MONTH);
+ year = cal.get(Calendar.YEAR);
+ hour = cal.get(Calendar.HOUR_OF_DAY);
+ minute = cal.get(Calendar.MINUTE);
+ second = cal.get(Calendar.SECOND);
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the system default timezone.
+ */
+ public static DateBuilder newDate() {
+ return new DateBuilder();
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the given timezone.
+ */
+ public static DateBuilder newDateInTimezone(TimeZone tz) {
+ return new DateBuilder(tz);
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the given locale.
+ */
+ public static DateBuilder newDateInLocale(Locale lc) {
+ return new DateBuilder(lc);
+ }
+
+ /**
+ * Create a DateBuilder, with initial settings for the current date and time in the given timezone and locale.
+ */
+ public static DateBuilder newDateInTimeZoneAndLocale(TimeZone tz, Locale lc) {
+ return new DateBuilder(tz, lc);
+ }
+
+ /**
+ * Build the Date defined by this builder instance.
+ */
+ public Date build() {
+ Calendar cal;
+
+ if(tz != null && lc != null)
+ cal = Calendar.getInstance(tz, lc);
+ else if(tz != null)
+ cal = Calendar.getInstance(tz);
+ else if(lc != null)
+ cal = Calendar.getInstance(lc);
+ else
+ cal = Calendar.getInstance();
+
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.MONTH, month - 1);
+ cal.set(Calendar.DAY_OF_MONTH, day);
+ cal.set(Calendar.HOUR_OF_DAY, hour);
+ cal.set(Calendar.MINUTE, minute);
+ cal.set(Calendar.SECOND, second);
+ cal.set(Calendar.MILLISECOND, 0);
+
+ return cal.getTime();
+ }
+
+ /**
+ * Set the hour (0-23) for the Date that will be built by this builder.
+ */
+ public DateBuilder atHourOfDay(int atHour) {
+ validateHour(atHour);
+
+ this.hour = atHour;
+ return this;
+ }
+
+ /**
+ * Set the minute (0-59) for the Date that will be built by this builder.
+ */
+ public DateBuilder atMinute(int atMinute) {
+ validateMinute(atMinute);
+
+ this.minute = atMinute;
+ return this;
+ }
+
+ /**
+ * Set the second (0-59) for the Date that will be built by this builder, and truncate the milliseconds to 000.
+ */
+ public DateBuilder atSecond(int atSecond) {
+ validateSecond(atSecond);
+
+ this.second = atSecond;
+ return this;
+ }
+
+ public DateBuilder atHourMinuteAndSecond(int atHour, int atMinute, int atSecond) {
+ validateHour(atHour);
+ validateMinute(atMinute);
+ validateSecond(atSecond);
+
+ this.hour = atHour;
+ this.second = atSecond;
+ this.minute = atMinute;
+ return this;
+ }
+
+ /**
+ * Set the day of month (1-31) for the Date that will be built by this builder.
+ */
+ public DateBuilder onDay(int onDay) {
+ validateDayOfMonth(onDay);
+
+ this.day = onDay;
+ return this;
+ }
+
+ /**
+ * Set the month (1-12) for the Date that will be built by this builder.
+ */
+ public DateBuilder inMonth(int inMonth) {
+ validateMonth(inMonth);
+
+ this.month = inMonth;
+ return this;
+ }
+
+ public DateBuilder inMonthOnDay(int inMonth, int onDay) {
+ validateMonth(inMonth);
+ validateDayOfMonth(onDay);
+
+ this.month = inMonth;
+ this.day = onDay;
+ return this;
+ }
+
+ /**
+ * Set the year for the Date that will be built by this builder.
+ */
+ public DateBuilder inYear(int inYear) {
+ validateYear(inYear);
+
+ this.year = inYear;
+ return this;
+ }
+
+ /**
+ * Set the TimeZone for the Date that will be built by this builder (if "null", system default will be used)
+ */
+ public DateBuilder inTimeZone(TimeZone timezone) {
+ this.tz = timezone;
+ return this;
+ }
+
+ /**
+ * Set the Locale for the Date that will be built by this builder (if "null", system default will be used)
+ */
+ public DateBuilder inLocale(Locale locale) {
+ this.lc = locale;
+ return this;
+ }
+
+ public static Date futureDate(int interval, IntervalUnit unit) {
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(new Date());
+ c.setLenient(true);
+
+ c.add(translate(unit), interval);
+
+ return c.getTime();
+ }
+
+
+ private static int translate(IntervalUnit unit) {
+ switch(unit) {
+ case DAY : return Calendar.DAY_OF_YEAR;
+ case HOUR : return Calendar.HOUR_OF_DAY;
+ case MINUTE : return Calendar.MINUTE;
+ case MONTH : return Calendar.MONTH;
+ case SECOND : return Calendar.SECOND;
+ case MILLISECOND : return Calendar.MILLISECOND;
+ case WEEK : return Calendar.WEEK_OF_YEAR;
+ case YEAR : return Calendar.YEAR;
+ default : throw new IllegalArgumentException("Unknown IntervalUnit");
+ }
+ }
+
+ /**
+ *
+ * Get a Date object that represents the given time, on
+ * tomorrow's date.
+ *
+ *
+ * @param second
+ * The value (0-59) to give the seconds field of the date
+ * @param minute
+ * The value (0-59) to give the minutes field of the date
+ * @param hour
+ * The value (0-23) to give the hours field of the date
+ * @return the new date
+ */
+ public static Date tomorrowAt(int hour, int minute, int second) {
+ validateSecond(second);
+ validateMinute(minute);
+ validateHour(hour);
+
+ Date date = new Date();
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ // advance one day
+ c.add(Calendar.DAY_OF_YEAR, 1);
+
+ c.set(Calendar.HOUR_OF_DAY, hour);
+ c.set(Calendar.MINUTE, minute);
+ c.set(Calendar.SECOND, second);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Get a Date object that represents the given time, on
+ * today's date (equivalent to {@link #dateOf(int, int, int)}).
+ *
+ *
+ * @param second
+ * The value (0-59) to give the seconds field of the date
+ * @param minute
+ * The value (0-59) to give the minutes field of the date
+ * @param hour
+ * The value (0-23) to give the hours field of the date
+ * @return the new date
+ */
+ public static Date todayAt(int hour, int minute, int second) {
+ return dateOf(hour, minute, second);
+ }
+
+ /**
+ *
+ * Get a Date object that represents the given time, on
+ * today's date (equivalent to {@link #todayAt(int, int, int)}).
+ *
+ *
+ * @param second
+ * The value (0-59) to give the seconds field of the date
+ * @param minute
+ * The value (0-59) to give the minutes field of the date
+ * @param hour
+ * The value (0-23) to give the hours field of the date
+ * @return the new date
+ */
+ public static Date dateOf(int hour, int minute, int second) {
+ validateSecond(second);
+ validateMinute(minute);
+ validateHour(hour);
+
+ Date date = new Date();
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ c.set(Calendar.HOUR_OF_DAY, hour);
+ c.set(Calendar.MINUTE, minute);
+ c.set(Calendar.SECOND, second);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Get a Date object that represents the given time, on the
+ * given date.
+ *
+ *
+ * @param second
+ * The value (0-59) to give the seconds field of the date
+ * @param minute
+ * The value (0-59) to give the minutes field of the date
+ * @param hour
+ * The value (0-23) to give the hours field of the date
+ * @param dayOfMonth
+ * The value (1-31) to give the day of month field of the date
+ * @param month
+ * The value (1-12) to give the month field of the date
+ * @return the new date
+ */
+ public static Date dateOf(int hour, int minute, int second,
+ int dayOfMonth, int month) {
+ validateSecond(second);
+ validateMinute(minute);
+ validateHour(hour);
+ validateDayOfMonth(dayOfMonth);
+ validateMonth(month);
+
+ Date date = new Date();
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+
+ c.set(Calendar.MONTH, month - 1);
+ c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+ c.set(Calendar.HOUR_OF_DAY, hour);
+ c.set(Calendar.MINUTE, minute);
+ c.set(Calendar.SECOND, second);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Get a Date object that represents the given time, on the
+ * given date.
+ *
+ *
+ * @param second
+ * The value (0-59) to give the seconds field of the date
+ * @param minute
+ * The value (0-59) to give the minutes field of the date
+ * @param hour
+ * The value (0-23) to give the hours field of the date
+ * @param dayOfMonth
+ * The value (1-31) to give the day of month field of the date
+ * @param month
+ * The value (1-12) to give the month field of the date
+ * @param year
+ * The value (1970-2099) to give the year field of the date
+ * @return the new date
+ */
+ public static Date dateOf(int hour, int minute, int second,
+ int dayOfMonth, int month, int year) {
+ validateSecond(second);
+ validateMinute(minute);
+ validateHour(hour);
+ validateDayOfMonth(dayOfMonth);
+ validateMonth(month);
+ validateYear(year);
+
+ Date date = new Date();
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+
+ c.set(Calendar.YEAR, year);
+ c.set(Calendar.MONTH, month - 1);
+ c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+ c.set(Calendar.HOUR_OF_DAY, hour);
+ c.set(Calendar.MINUTE, minute);
+ c.set(Calendar.SECOND, second);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+
+ /**
+ *
+ * Returns a date that is rounded to the next even hour after the current time.
+ *
+ *
+ *
+ * For example a current time of 08:13:54 would result in a date
+ * with the time of 09:00:00. If the date's time is in the 23rd hour, the
+ * date's 'day' will be promoted, and the time will be set to 00:00:00.
+ *
+ *
+ * @return the new rounded date
+ */
+ public static Date evenHourDateAfterNow() {
+ return evenHourDate(null);
+ }
+ /**
+ *
+ * Returns a date that is rounded to the next even hour above the given
+ * date.
+ *
+ *
+ *
+ * For example an input date with a time of 08:13:54 would result in a date
+ * with the time of 09:00:00. If the date's time is in the 23rd hour, the
+ * date's 'day' will be promoted, and the time will be set to 00:00:00.
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @return the new rounded date
+ */
+ public static Date evenHourDate(Date date) {
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + 1);
+ c.set(Calendar.MINUTE, 0);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the previous even hour below the given
+ * date.
+ *
+ *
+ *
+ * For example an input date with a time of 08:13:54 would result in a date
+ * with the time of 08:00:00.
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @return the new rounded date
+ */
+ public static Date evenHourDateBefore(Date date) {
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+
+ c.set(Calendar.MINUTE, 0);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the next even minute after the current time.
+ *
+ *
+ *
+ * For example a current time of 08:13:54 would result in a date
+ * with the time of 08:14:00. If the date's time is in the 59th minute,
+ * then the hour (and possibly the day) will be promoted.
+ *
+ *
+ * @return the new rounded date
+ */
+ public static Date evenMinuteDateAfterNow() {
+ return evenMinuteDate(null);
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the next even minute above the given
+ * date.
+ *
+ *
+ *
+ * For example an input date with a time of 08:13:54 would result in a date
+ * with the time of 08:14:00. If the date's time is in the 59th minute,
+ * then the hour (and possibly the day) will be promoted.
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @return the new rounded date
+ */
+ public static Date evenMinuteDate(Date date) {
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 1);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the previous even minute below the
+ * given date.
+ *
+ *
+ *
+ * For example an input date with a time of 08:13:54 would result in a date
+ * with the time of 08:13:00.
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @return the new rounded date
+ */
+ public static Date evenMinuteDateBefore(Date date) {
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the next even second after the current time.
+ *
+ *
+ * @return the new rounded date
+ */
+ public static Date evenSecondDateAfterNow() {
+ return evenSecondDate(null);
+ }
+ /**
+ *
+ * Returns a date that is rounded to the next even second above the given
+ * date.
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @return the new rounded date
+ */
+ public static Date evenSecondDate(Date date) {
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ c.set(Calendar.SECOND, c.get(Calendar.SECOND) + 1);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the previous even second below the
+ * given date.
+ *
+ *
+ *
+ * For example an input date with a time of 08:13:54.341 would result in a
+ * date with the time of 08:13:54.000.
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @return the new rounded date
+ */
+ public static Date evenSecondDateBefore(Date date) {
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the next even multiple of the given
+ * minute.
+ *
+ *
+ *
+ * For example an input date with a time of 08:13:54, and an input
+ * minute-base of 5 would result in a date with the time of 08:15:00. The
+ * same input date with an input minute-base of 10 would result in a date
+ * with the time of 08:20:00. But a date with the time 08:53:31 and an
+ * input minute-base of 45 would result in 09:00:00, because the even-hour
+ * is the next 'base' for 45-minute intervals.
+ *
+ *
+ *
+ * More examples:
+ *
+ * Input Time
+ * Minute-Base
+ * Result Time
+ *
+ *
+ * 11:16:41
+ * 20
+ * 11:20:00
+ *
+ *
+ * 11:36:41
+ * 20
+ * 11:40:00
+ *
+ *
+ * 11:46:41
+ * 20
+ * 12:00:00
+ *
+ *
+ * 11:26:41
+ * 30
+ * 11:30:00
+ *
+ *
+ * 11:36:41
+ * 30
+ * 12:00:00
+ *
+ * 11:16:41
+ * 17
+ * 11:17:00
+ *
+ *
+ * 11:17:41
+ * 17
+ * 11:34:00
+ *
+ *
+ * 11:52:41
+ * 17
+ * 12:00:00
+ *
+ *
+ * 11:52:41
+ * 5
+ * 11:55:00
+ *
+ *
+ * 11:57:41
+ * 5
+ * 12:00:00
+ *
+ *
+ * 11:17:41
+ * 0
+ * 12:00:00
+ *
+ *
+ * 11:17:41
+ * 1
+ * 11:08:00
+ *
+ *
+ *
+ *
+ * @param date
+ * the Date to round, if null the current time will
+ * be used
+ * @param minuteBase
+ * the base-minute to set the time on
+ * @return the new rounded date
+ *
+ * @see #nextGivenSecondDate(Date, int)
+ */
+ public static Date nextGivenMinuteDate(Date date, int minuteBase) {
+ if (minuteBase < 0 || minuteBase > 59) {
+ throw new IllegalArgumentException(
+ "minuteBase must be >=0 and <= 59");
+ }
+
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ if (minuteBase == 0) {
+ c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + 1);
+ c.set(Calendar.MINUTE, 0);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ int minute = c.get(Calendar.MINUTE);
+
+ int arItr = minute / minuteBase;
+
+ int nextMinuteOccurance = minuteBase * (arItr + 1);
+
+ if (nextMinuteOccurance < 60) {
+ c.set(Calendar.MINUTE, nextMinuteOccurance);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ } else {
+ c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + 1);
+ c.set(Calendar.MINUTE, 0);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+ }
+
+ /**
+ *
+ * Returns a date that is rounded to the next even multiple of the given
+ * minute.
+ *
+ *
+ *
+ * The rules for calculating the second are the same as those for
+ * calculating the minute in the method
+ * getNextGivenMinuteDate(..).
+ *
+ *
+ * @param date the Date to round, if null the current time will
+ * be used
+ * @param secondBase the base-second to set the time on
+ * @return the new rounded date
+ *
+ * @see #nextGivenMinuteDate(Date, int)
+ */
+ public static Date nextGivenSecondDate(Date date, int secondBase) {
+ if (secondBase < 0 || secondBase > 59) {
+ throw new IllegalArgumentException(
+ "secondBase must be >=0 and <= 59");
+ }
+
+ if (date == null) {
+ date = new Date();
+ }
+
+ Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.setLenient(true);
+
+ if (secondBase == 0) {
+ c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 1);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+
+ int second = c.get(Calendar.SECOND);
+
+ int arItr = second / secondBase;
+
+ int nextSecondOccurance = secondBase * (arItr + 1);
+
+ if (nextSecondOccurance < 60) {
+ c.set(Calendar.SECOND, nextSecondOccurance);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ } else {
+ c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 1);
+ c.set(Calendar.SECOND, 0);
+ c.set(Calendar.MILLISECOND, 0);
+
+ return c.getTime();
+ }
+ }
+
+ /**
+ * Translate a date & time from a users time zone to the another
+ * (probably server) time zone to assist in creating a simple trigger with
+ * the right date & time.
+ *
+ * @param date the date to translate
+ * @param src the original time-zone
+ * @param dest the destination time-zone
+ * @return the translated date
+ */
+ public static Date translateTime(Date date, TimeZone src, TimeZone dest) {
+
+ Date newDate = new Date();
+
+ int offset = (dest.getOffset(date.getTime()) - src.getOffset(date.getTime()));
+
+ newDate.setTime(date.getTime() - offset);
+
+ return newDate;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ public static void validateDayOfWeek(int dayOfWeek) {
+ if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY) {
+ throw new IllegalArgumentException("Invalid day of week.");
+ }
+ }
+
+ public static void validateHour(int hour) {
+ if (hour < 0 || hour > 23) {
+ throw new IllegalArgumentException(
+ "Invalid hour (must be >= 0 and <= 23).");
+ }
+ }
+
+ public static void validateMinute(int minute) {
+ if (minute < 0 || minute > 59) {
+ throw new IllegalArgumentException(
+ "Invalid minute (must be >= 0 and <= 59).");
+ }
+ }
+
+ public static void validateSecond(int second) {
+ if (second < 0 || second > 59) {
+ throw new IllegalArgumentException(
+ "Invalid second (must be >= 0 and <= 59).");
+ }
+ }
+
+ public static void validateDayOfMonth(int day) {
+ if (day < 1 || day > 31) {
+ throw new IllegalArgumentException("Invalid day of month.");
+ }
+ }
+
+ public static void validateMonth(int month) {
+ if (month < 1 || month > 12) {
+ throw new IllegalArgumentException(
+ "Invalid month (must be >= 1 and <= 12.");
+ }
+ }
+
+ private static final int MAX_YEAR = Calendar.getInstance().get(Calendar.YEAR) + 100;
+ public static void validateYear(int year) {
+ if (year < 0 || year > MAX_YEAR) {
+ throw new IllegalArgumentException(
+ "Invalid year (must be >= 0 and <= " + MAX_YEAR);
+ }
+ }
+
+}
Index: 3rdParty_sources/quartz/org/quartz/DisallowConcurrentExecution.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/DisallowConcurrentExecution.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/DisallowConcurrentExecution.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,40 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation that marks a {@link Job} class as one that must not have multiple
+ * instances executed concurrently (where instance is based-upon a {@link JobDetail}
+ * definition - or in other words based upon a {@link JobKey}).
+ *
+ * @see PersistJobDataAfterExecution
+ *
+ * @author jhouse
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface DisallowConcurrentExecution {
+
+}
Index: 3rdParty_sources/quartz/org/quartz/ExecuteInJTATransaction.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/ExecuteInJTATransaction.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/ExecuteInJTATransaction.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,62 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.transaction.UserTransaction;
+
+/**
+ * An annotation that marks a {@link Job} class as one that will have its
+ * execution wrapped by a JTA Transaction.
+ *
+ * If this annotation is present, Quartz will begin a JTA transaction
+ * before calling the execute() method, and will commit
+ * the transaction if the method does not throw an exception and the
+ * transaction has not had setRollbackOnly() called on it
+ * (otherwise the transaction will be rolled-back by Quartz).
+ *
+ * This is essentially the same behavior as setting the configuration
+ * property org.quartz.scheduler.wrapJobExecutionInUserTransaction
+ * to true - except that it only affects the job that has
+ * the annotation, rather than all jobs (as the property does). If the
+ * property is set to true and the annotation is also set,
+ * then of course the annotation becomes redundant.
+ *
+ * @author jhouse
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ExecuteInJTATransaction {
+
+ /**
+ * The JTA transaction timeout.
+ *
+ * If set then the {@code UserTransaction} timeout will be set to this
+ * value before beginning the transaction.
+ *
+ * @see UserTransaction#setTransactionTimeout(int)
+ * @return the transaction timeout.
+ */
+ int timeout() default -1;
+}
Index: 3rdParty_sources/quartz/org/quartz/InterruptableJob.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/InterruptableJob.java (.../InterruptableJob.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/InterruptableJob.java (.../InterruptableJob.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,19 +16,17 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* The interface to be implemented by {@link Job}s that provide a
- * mechanism for having their execution interrupted. It is NOT a requirment
+ * mechanism for having their execution interrupted. It is NOT a requirement
* for jobs to implement this interface - in fact, for most people, none of
* their jobs will.
- *
*
+ * Interrupting a Job is very analogous in concept and
+ * challenge to normal interruption of a Thread in Java.
+ *
*
* The means of actually interrupting the Job must be implemented within the
* Job itself (the interrupt() method of this
@@ -51,18 +49,22 @@
* If the Job performs some form of blocking I/O or similar functions, you may
* want to consider having the Job.execute(..) method store a
* reference to the calling Thread as a member variable. Then the
- * impplementation of this interfaces interrupt() method can call
+ * Implementation of this interfaces interrupt() method can call
* interrupt() on that Thread. Before attempting this, make
* sure that you fully understand what java.lang.Thread.interrupt()
* does and doesn't do. Also make sure that you clear the Job's member
- * reference to the Thread when the execute(..) method exits (preferrably in a
+ * reference to the Thread when the execute(..) method exits (preferably in a
* finally block.
*
*
+ *
+ * See Example 7 (org.quartz.examples.example7.DumbInterruptableJob) for a simple
+ * implementation demonstration.
+ *
* @see Job
* @see StatefulJob
- * @see Scheduler#interrupt(String, String)
- * @see org.quartz.examples.example7.DumbInterruptableJob
+ * @see Scheduler#interrupt(JobKey)
+ * @see Scheduler#interrupt(String)
*
* @author James House
*/
@@ -82,12 +84,9 @@
* interrupts the Job.
*
*
- * @return void (nothing) if job interrupt is successful.
* @throws UnableToInterruptJobException
* if there is an exception while interrupting the job.
*/
- public void interrupt()
- throws UnableToInterruptJobException;
-
-
+ void interrupt()
+ throws UnableToInterruptJobException;
}
Index: 3rdParty_sources/quartz/org/quartz/Job.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/Job.java (.../Job.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/Job.java (.../Job.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,9 +16,6 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
@@ -38,7 +35,10 @@
*
*
* @see JobDetail
- * @see StatefulJob
+ * @see JobBuilder
+ * @see ExecuteInJTATransaction
+ * @see DisallowConcurrentExecution
+ * @see PersistJobDataAfterExecution
* @see Trigger
* @see Scheduler
*
@@ -70,11 +70,10 @@
* execution.
*
*
- * @return void (nothing) if job is successful.
* @throws JobExecutionException
* if there is an exception while executing the job.
*/
- public void execute(JobExecutionContext context)
- throws JobExecutionException;
+ void execute(JobExecutionContext context)
+ throws JobExecutionException;
}
Index: 3rdParty_sources/quartz/org/quartz/JobBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/JobBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/JobBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,351 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import org.quartz.impl.JobDetailImpl;
+import org.quartz.utils.Key;
+
+/**
+ * JobBuilder is used to instantiate {@link JobDetail}s.
+ *
+ * The builder will always try to keep itself in a valid state, with
+ * reasonable defaults set for calling build() at any point. For instance
+ * if you do not invoke withIdentity(..) a job name will be generated
+ * for you.
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(simpleSchedule()
+ * .withIntervalInHours(1)
+ * .repeatForever())
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ * @see TriggerBuilder
+ * @see DateBuilder
+ * @see JobDetail
+ */
+public class JobBuilder {
+
+ private JobKey key;
+ private String description;
+ private Class extends Job> jobClass;
+ private boolean durability;
+ private boolean shouldRecover;
+
+ private JobDataMap jobDataMap = new JobDataMap();
+
+ protected JobBuilder() {
+ }
+
+ /**
+ * Create a JobBuilder with which to define a JobDetail.
+ *
+ * @return a new JobBuilder
+ */
+ public static JobBuilder newJob() {
+ return new JobBuilder();
+ }
+
+ /**
+ * Create a JobBuilder with which to define a JobDetail,
+ * and set the class name of the Job to be executed.
+ *
+ * @return a new JobBuilder
+ */
+ public static JobBuilder newJob(Class extends Job> jobClass) {
+ JobBuilder b = new JobBuilder();
+ b.ofType(jobClass);
+ return b;
+ }
+
+ /**
+ * Produce the JobDetail instance defined by this
+ * JobBuilder.
+ *
+ * @return the defined JobDetail.
+ */
+ public JobDetail build() {
+
+ JobDetailImpl job = new JobDetailImpl();
+
+ job.setJobClass(jobClass);
+ job.setDescription(description);
+ if(key == null)
+ key = new JobKey(Key.createUniqueName(null), null);
+ job.setKey(key);
+ job.setDurability(durability);
+ job.setRequestsRecovery(shouldRecover);
+
+
+ if(!jobDataMap.isEmpty())
+ job.setJobDataMap(jobDataMap);
+
+ return job;
+ }
+
+ /**
+ * Use a JobKey with the given name and default group to
+ * identify the JobDetail.
+ *
+ * If none of the 'withIdentity' methods are set on the JobBuilder,
+ * then a random, unique JobKey will be generated.
+ *
+ * @param name the name element for the Job's JobKey
+ * @return the updated JobBuilder
+ * @see JobKey
+ * @see JobDetail#getKey()
+ */
+ public JobBuilder withIdentity(String name) {
+ key = new JobKey(name, null);
+ return this;
+ }
+
+ /**
+ * Use a JobKey with the given name and group to
+ * identify the JobDetail.
+ *
+ * If none of the 'withIdentity' methods are set on the JobBuilder,
+ * then a random, unique JobKey will be generated.
+ *
+ * @param name the name element for the Job's JobKey
+ * @param group the group element for the Job's JobKey
+ * @return the updated JobBuilder
+ * @see JobKey
+ * @see JobDetail#getKey()
+ */
+ public JobBuilder withIdentity(String name, String group) {
+ key = new JobKey(name, group);
+ return this;
+ }
+
+ /**
+ * Use a JobKey to identify the JobDetail.
+ *
+ * If none of the 'withIdentity' methods are set on the JobBuilder,
+ * then a random, unique JobKey will be generated.
+ *
+ * @param jobKey the Job's JobKey
+ * @return the updated JobBuilder
+ * @see JobKey
+ * @see JobDetail#getKey()
+ */
+ public JobBuilder withIdentity(JobKey jobKey) {
+ this.key = jobKey;
+ return this;
+ }
+
+ /**
+ * Set the given (human-meaningful) description of the Job.
+ *
+ * @param jobDescription the description for the Job
+ * @return the updated JobBuilder
+ * @see JobDetail#getDescription()
+ */
+ public JobBuilder withDescription(String jobDescription) {
+ this.description = jobDescription;
+ return this;
+ }
+
+ /**
+ * Set the class which will be instantiated and executed when a
+ * Trigger fires that is associated with this JobDetail.
+ *
+ * @param jobClazz a class implementing the Job interface.
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobClass()
+ */
+ public JobBuilder ofType(Class extends Job> jobClazz) {
+ this.jobClass = jobClazz;
+ return this;
+ }
+
+ /**
+ * Instructs the Scheduler whether or not the Job
+ * should be re-executed if a 'recovery' or 'fail-over' situation is
+ * encountered.
+ *
+ *
+ * If not explicitly set, the default value is false.
+ *
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#requestsRecovery()
+ */
+ public JobBuilder requestRecovery() {
+ this.shouldRecover = true;
+ return this;
+ }
+
+ /**
+ * Instructs the Scheduler whether or not the Job
+ * should be re-executed if a 'recovery' or 'fail-over' situation is
+ * encountered.
+ *
+ *
+ * If not explicitly set, the default value is false.
+ *
+ *
+ * @param jobShouldRecover the desired setting
+ * @return the updated JobBuilder
+ */
+ public JobBuilder requestRecovery(boolean jobShouldRecover) {
+ this.shouldRecover = jobShouldRecover;
+ return this;
+ }
+
+ /**
+ * Whether or not the Job should remain stored after it is
+ * orphaned (no {@link Trigger}s point to it).
+ *
+ *
+ * If not explicitly set, the default value is false
+ * - this method sets the value to true.
+ *
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#isDurable()
+ */
+ public JobBuilder storeDurably() {
+ this.durability = true;
+ return this;
+ }
+
+ /**
+ * Whether or not the Job should remain stored after it is
+ * orphaned (no {@link Trigger}s point to it).
+ *
+ *
+ * If not explicitly set, the default value is false.
+ *
+ *
+ * @param jobDurability the value to set for the durability property.
+ * @return the updated JobBuilder
+ * @see JobDetail#isDurable()
+ */
+ public JobBuilder storeDurably(boolean jobDurability) {
+ this.durability = jobDurability;
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the JobDetail's {@link JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(String dataKey, String value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the JobDetail's {@link JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(String dataKey, Integer value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the JobDetail's {@link JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(String dataKey, Long value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the JobDetail's {@link JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(String dataKey, Float value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the JobDetail's {@link JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(String dataKey, Double value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the JobDetail's {@link JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(String dataKey, Boolean value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add all the data from the given {@link JobDataMap} to the
+ * {@code JobDetail}'s {@code JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder usingJobData(JobDataMap newJobDataMap) {
+ jobDataMap.putAll(newJobDataMap);
+ return this;
+ }
+
+ /**
+ * Replace the {@code JobDetail}'s {@link JobDataMap} with the
+ * given {@code JobDataMap}.
+ *
+ * @return the updated JobBuilder
+ * @see JobDetail#getJobDataMap()
+ */
+ public JobBuilder setJobData(JobDataMap newJobDataMap) {
+ jobDataMap = newJobDataMap;
+ return this;
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/JobDataMap.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/JobDataMap.java (.../JobDataMap.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/JobDataMap.java (.../JobDataMap.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,26 +16,20 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
import java.io.Serializable;
-import java.util.Iterator;
import java.util.Map;
-import org.quartz.utils.DirtyFlagMap;
+import org.quartz.utils.StringKeyDirtyFlagMap;
/**
- *
* Holds state information for Job instances.
- *
*
*
* JobDataMap instances are stored once when the Job
* is added to a scheduler. They are also re-persisted after every execution of
- * StatefulJob instances.
+ * jobs annotated with @PersistJobDataAfterExecution.
*
*
*
@@ -54,13 +48,13 @@
*
*
* @see Job
- * @see StatefulJob
+ * @see PersistJobDataAfterExecution
* @see Trigger
* @see JobExecutionContext
*
* @author James House
*/
-public class JobDataMap extends DirtyFlagMap implements Serializable {
+public class JobDataMap extends StringKeyDirtyFlagMap implements Serializable {
private static final long serialVersionUID = -6939901990106713909L;
@@ -72,16 +66,6 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
- private boolean allowsTransientData = false;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
/**
*
* Create an empty JobDataMap.
@@ -96,10 +80,11 @@
* Create a JobDataMap with the given data.
*
*/
- public JobDataMap(Map map) {
+ public JobDataMap(Map, ?> map) {
this();
-
- putAll(map);
+ @SuppressWarnings("unchecked") // casting to keep API compatible and avoid compiler errors/warnings.
+ Map mapTyped = (Map)map;
+ putAll(mapTyped);
}
/*
@@ -112,163 +97,12 @@
/**
*
- * Tell the JobDataMap that it should allow non- Serializable
- * data.
- *
- *
- *
- * If the JobDataMap does contain non- Serializable
- * objects, and it belongs to a non-volatile Job that is
- * stored in a JobStore that supports persistence, then
- * those elements will be nulled-out during persistence.
- *
- */
- public void setAllowsTransientData(boolean allowsTransientData) {
-
- if (containsTransientData() && !allowsTransientData)
- throw new IllegalStateException(
- "Cannot set property 'allowsTransientData' to 'false' "
- + "when data map contains non-serializable objects.");
-
- this.allowsTransientData = allowsTransientData;
- }
-
- public boolean getAllowsTransientData() {
- return allowsTransientData;
- }
-
- public boolean containsTransientData() {
-
- if (!getAllowsTransientData()) // short circuit...
- return false;
-
- String[] keys = getKeys();
-
- for (int i = 0; i < keys.length; i++) {
- Object o = super.get(keys[i]);
- if (!(o instanceof Serializable)) return true;
- }
-
- return false;
- }
-
- /**
- *
- * Nulls-out any data values that are non-Serializable.
- *
- */
- public void removeTransientData() {
-
- if (!getAllowsTransientData()) // short circuit...
- return;
-
- String[] keys = getKeys();
-
- for (int i = 0; i < keys.length; i++) {
- Object o = super.get(keys[i]);
- if (!(o instanceof Serializable)) remove(keys[i]);
- }
-
- }
-
- /**
- *
- * Adds the name-value pairs in the given Map to the JobDataMap.
- *
- *
- *
- * All keys must be Strings, and all values must be Serializable.
- *
- */
- public void putAll(Map map) {
- Iterator itr = map.keySet().iterator();
- while (itr.hasNext()) {
- Object key = itr.next();
- Object val = map.get(key);
-
- put(key, val);
- // will throw IllegalArgumentException if value not serilizable
- }
- }
-
- /**
- *
- * Adds the given int value to the Job's
- * data map.
- *
- */
- public void put(String key, int value) {
- super.put(key, new Integer(value));
- }
-
- /**
- *
- * Adds the given long value to the Job's
- * data map.
- *
- */
- public void put(String key, long value) {
- super.put(key, new Long(value));
- }
-
- /**
- *
- * Adds the given float value to the Job's
- * data map.
- *
- */
- public void put(String key, float value) {
- super.put(key, new Float(value));
- }
-
- /**
- *
- * Adds the given double value to the Job's
- * data map.
- *
- */
- public void put(String key, double value) {
- super.put(key, new Double(value));
- }
-
- /**
- *
- * Adds the given boolean value to the Job's
- * data map.
- *
- */
- public void put(String key, boolean value) {
- super.put(key, new Boolean(value));
- }
-
- /**
- *
- * Adds the given char value to the Job's
- * data map.
- *
- */
- public void put(String key, char value) {
- super.put(key, new Character(value));
- }
-
- /**
- *
- * Adds the given String value to the Job's
- * data map.
- *
- */
- public void put(String key, String value) {
- super.put(key, value);
- }
-
- /**
- *
* Adds the given boolean value as a string version to the
* Job's data map.
*
*/
public void putAsString(String key, boolean value) {
- String strValue = new Boolean(value).toString();
+ String strValue = Boolean.valueOf(value).toString();
super.put(key, strValue);
}
@@ -292,7 +126,7 @@
*
*/
public void putAsString(String key, char value) {
- String strValue = new Character(value).toString();
+ String strValue = Character.valueOf(value).toString();
super.put(key, strValue);
}
@@ -316,7 +150,7 @@
*
*/
public void putAsString(String key, double value) {
- String strValue = new Double(value).toString();
+ String strValue = Double.toString(value);
super.put(key, strValue);
}
@@ -340,7 +174,7 @@
*
*/
public void putAsString(String key, float value) {
- String strValue = new Float(value).toString();
+ String strValue = Float.toString(value);
super.put(key, strValue);
}
@@ -364,7 +198,7 @@
*
*/
public void putAsString(String key, int value) {
- String strValue = new Integer(value).toString();
+ String strValue = Integer.valueOf(value).toString();
super.put(key, strValue);
}
@@ -388,7 +222,7 @@
*
*/
public void putAsString(String key, long value) {
- String strValue = new Long(value).toString();
+ String strValue = Long.valueOf(value).toString();
super.put(key, strValue);
}
@@ -407,156 +241,16 @@
/**
*
- * Adds the given Serializable object value to the JobDataMap.
- *
- */
- public Object put(Object key, Object value) {
- if (!(key instanceof String))
- throw new IllegalArgumentException(
- "Keys in map must be Strings.");
-
- return super.put(key, value);
- }
-
- /**
- *
* Retrieve the identified int value from the JobDataMap.
*
*
* @throws ClassCastException
- * if the identified object is not an Integer.
- */
- public int getInt(String key) {
- Object obj = get(key);
-
- try {
- return ((Integer) obj).intValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not an Integer.");
- }
- }
-
- /**
- *
- * Retrieve the identified long value from the JobDataMap.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Long.
- */
- public long getLong(String key) {
- Object obj = get(key);
-
- try {
- return ((Long) obj).longValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Long.");
- }
- }
-
- /**
- *
- * Retrieve the identified float value from the JobDataMap.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Float.
- */
- public float getFloat(String key) {
- Object obj = get(key);
-
- try {
- return ((Float) obj).floatValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Float.");
- }
- }
-
- /**
- *
- * Retrieve the identified double value from the JobDataMap.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Double.
- */
- public double getDouble(String key) {
- Object obj = get(key);
-
- try {
- return ((Double) obj).doubleValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Double.");
- }
- }
-
- /**
- *
- * Retrieve the identified boolean value from the JobDataMap.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Boolean.
- */
- public boolean getBoolean(String key) {
- Object obj = get(key);
-
- try {
- return ((Boolean) obj).booleanValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Boolean.");
- }
- }
-
- /**
- *
- * Retrieve the identified char value from the JobDataMap.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Character.
- */
- public char getChar(String key) {
- Object obj = get(key);
-
- try {
- return ((Character) obj).charValue();
- } catch (Exception e) {
- throw new ClassCastException(
- "Identified object is not a Character.");
- }
- }
-
- /**
- *
- * Retrieve the identified String value from the JobDataMap.
- *
- *
- * @throws ClassCastException
* if the identified object is not a String.
*/
- public String getString(String key) {
- Object obj = get(key);
-
- try {
- return (String) obj;
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a String.");
- }
- }
-
- /**
- *
- * Retrieve the identified int value from the JobDataMap.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a String.
- */
public int getIntFromString(String key) {
Object obj = get(key);
- return new Integer((String) obj).intValue();
+ return new Integer((String) obj);
}
/**
@@ -565,15 +259,16 @@
*
*
* @throws ClassCastException
- * if the identified object is not a String or Integeger.
+ * if the identified object is not a String or Integer.
*/
- public long getIntValue(String key) {
+ public int getIntValue(String key) {
Object obj = get(key);
- if(obj instanceof String)
+ if(obj instanceof String) {
return getIntFromString(key);
- else
+ } else {
return getInt(key);
+ }
}
/**
@@ -601,7 +296,7 @@
public boolean getBooleanValueFromString(String key) {
Object obj = get(key);
- return new Boolean((String) obj).booleanValue();
+ return Boolean.valueOf((String) obj);
}
/**
@@ -616,10 +311,11 @@
public boolean getBooleanValue(String key) {
Object obj = get(key);
- if(obj instanceof String)
+ if(obj instanceof String) {
return getBooleanValueFromString(key);
- else
+ } else {
return getBoolean(key);
+ }
}
/**
@@ -633,7 +329,7 @@
public Boolean getBooleanFromString(String key) {
Object obj = get(key);
- return new Boolean((String) obj);
+ return Boolean.valueOf((String) obj);
}
/**
@@ -661,7 +357,7 @@
public Character getCharacterFromString(String key) {
Object obj = get(key);
- return new Character(((String) obj).charAt(0));
+ return ((String) obj).charAt(0);
}
/**
@@ -675,7 +371,7 @@
public double getDoubleValueFromString(String key) {
Object obj = get(key);
- return new Double((String) obj).doubleValue();
+ return Double.valueOf((String) obj);
}
/**
@@ -689,10 +385,11 @@
public double getDoubleValue(String key) {
Object obj = get(key);
- if(obj instanceof String)
+ if(obj instanceof String) {
return getDoubleValueFromString(key);
- else
+ } else {
return getDouble(key);
+ }
}
/**
@@ -720,7 +417,7 @@
public float getFloatValueFromString(String key) {
Object obj = get(key);
- return new Float((String) obj).floatValue();
+ return new Float((String) obj);
}
/**
@@ -734,10 +431,11 @@
public float getFloatValue(String key) {
Object obj = get(key);
- if(obj instanceof String)
+ if(obj instanceof String) {
return getFloatValueFromString(key);
- else
+ } else {
return getFloat(key);
+ }
}
/**
@@ -765,7 +463,7 @@
public long getLongValueFromString(String key) {
Object obj = get(key);
- return new Long((String) obj).longValue();
+ return new Long((String) obj);
}
/**
@@ -779,10 +477,11 @@
public long getLongValue(String key) {
Object obj = get(key);
- if(obj instanceof String)
+ if(obj instanceof String) {
return getLongValueFromString(key);
- else
+ } else {
return getLong(key);
+ }
}
/**
@@ -798,9 +497,4 @@
return new Long((String) obj);
}
-
- public String[] getKeys() {
- return (String[]) keySet().toArray(new String[size()]);
- }
-
}
Index: 3rdParty_sources/quartz/org/quartz/JobDetail.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/JobDetail.java (.../JobDetail.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/JobDetail.java (.../JobDetail.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,5 @@
-
-/*
- * Copyright 2004-2005 OpenSymphony
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*
* 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
@@ -16,364 +15,67 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
-import java.util.ArrayList;
+import java.io.Serializable;
/**
- *
- * Conveys the detail properties of a given Job instance.
- *
+ * Conveys the detail properties of a given Job instance. JobDetails are
+ * to be created/defined with {@link JobBuilder}.
*
*
* Quartz does not store an actual instance of a Job class, but
* instead allows you to define an instance of one, through the use of a JobDetail.
*
*
*
- * Job s have a name and group associated with them, which
+ * Jobs have a name and group associated with them, which
* should uniquely identify them within a single {@link Scheduler}.
*
*
*
- * Trigger s are the 'mechanism' by which Job s
- * are scheduled. Many Trigger s can point to the same Job,
+ * Triggers are the 'mechanism' by which Jobs
+ * are scheduled. Many Triggers can point to the same Job,
* but a single Trigger can only point to one Job.
*
*
+ * @see JobBuilder
* @see Job
- * @see StatefulJob
* @see JobDataMap
* @see Trigger
*
* @author James House
- * @author Sharada Jambula
*/
-public class JobDetail implements Cloneable, java.io.Serializable {
+public interface JobDetail extends Serializable, Cloneable {
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
+ public JobKey getKey();
- private String name;
-
- private String group = Scheduler.DEFAULT_GROUP;
-
- private String description;
-
- private Class jobClass;
-
- private JobDataMap jobDataMap;
-
- private boolean volatility = false;
-
- private boolean durability = false;
-
- private boolean shouldRecover = false;
-
- private ArrayList jobListeners = new ArrayList(2);
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
/**
*
- * Create a JobDetail with no specified name or group, and
- * the default settings of all the other properties.
- *
- *
- *
- * Note that the {@link #setName(String)},{@link #setGroup(String)}and
- * {@link #setJobClass(Class)}methods must be called before the job can be
- * placed into a {@link Scheduler}
- *
- */
- public JobDetail() {
- // do nothing...
- }
-
- /**
- *
- * Create a JobDetail with the given name, and group, and
- * the default settings of all the other properties.
- *
- *
- * @param group if null, Scheduler.DEFAULT_GROUP will be used.
- *
- * @exception IllegalArgumentException
- * if nameis null or empty, or the group is an empty string.
- */
- public JobDetail(String name, String group, Class jobClass) {
- setName(name);
- setGroup(group);
- setJobClass(jobClass);
- }
-
- /**
- *
- * Create a JobDetail with the given name, and group, and
- * the given settings of all the other properties.
- *
- *
- * @param group if null, Scheduler.DEFAULT_GROUP will be used.
- *
- * @exception IllegalArgumentException
- * if nameis null or empty, or the group is an empty string.
- */
- public JobDetail(String name, String group, Class jobClass,
- boolean volatility, boolean durability, boolean recover) {
- setName(name);
- setGroup(group);
- setJobClass(jobClass);
- setVolatility(volatility);
- setDurability(durability);
- setRequestsRecovery(recover);
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- *
- * Get the name of this Job.
- *
- */
- public String getName() {
- return name;
- }
-
- /**
- *
- * Set the name of this Job.
- *
- *
- * @exception IllegalArgumentException
- * if name is null or empty.
- */
- public void setName(String name) {
- if (name == null || name.trim().length() == 0)
- throw new IllegalArgumentException("Job name cannot be empty.");
-
- this.name = name;
- }
-
- /**
- *
- * Get the group of this Job.
- *
- */
- public String getGroup() {
- return group;
- }
-
- /**
- *
- * Set the group of this Job.
- *
- *
- * @param group if null, Scheduler.DEFAULT_GROUP will be used.
- *
- * @exception IllegalArgumentException
- * if the group is an empty string.
- */
- public void setGroup(String group) {
- if (group != null && group.trim().length() == 0)
- throw new IllegalArgumentException(
- "Group name cannot be empty.");
-
- if(group == null)
- group = Scheduler.DEFAULT_GROUP;
-
- this.group = group;
- }
-
- /**
- *
- * Returns the 'full name' of the Trigger in the format
- * "group.name".
- *
- */
- public String getFullName() {
- return group + "." + name;
- }
-
- /**
- *
* Return the description given to the Job instance by its
* creator (if any).
*
*
* @return null if no description was set.
*/
- public String getDescription() {
- return description;
- }
+ public String getDescription();
/**
*
- * Set a description for the Job instance - may be useful
- * for remembering/displaying the purpose of the job, though the
- * description has no meaning to Quartz.
- *
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- *
* Get the instance of Job that will be executed.
*
*/
- public Class getJobClass() {
- return jobClass;
- }
+ public Class extends Job> getJobClass();
/**
*
- * Set the instance of Job that will be executed.
- *
- *
- * @exception IllegalArgumentException
- * if jobClass is null or the class is not a Job.
- */
- public void setJobClass(Class jobClass) {
- if (jobClass == null)
- throw new IllegalArgumentException("Job class cannot be null.");
-
- if (!Job.class.isAssignableFrom(jobClass))
- throw new IllegalArgumentException(
- "Job class must implement the Job interface.");
-
- this.jobClass = jobClass;
- }
-
- /**
- *
* Get the JobDataMap that is associated with the Job.
*
*/
- public JobDataMap getJobDataMap() {
- if (jobDataMap == null) jobDataMap = new JobDataMap();
- return jobDataMap;
- }
+ public JobDataMap getJobDataMap();
/**
*
- * Set the JobDataMap to be associated with the Job.
- *
- */
- public void setJobDataMap(JobDataMap jobDataMap) {
- this.jobDataMap = jobDataMap;
- }
-
- /**
- *
- * 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("Job's name cannot be null",
- SchedulerException.ERR_CLIENT_ERROR);
-
- if (group == null)
- throw new SchedulerException("Job's group cannot be null",
- SchedulerException.ERR_CLIENT_ERROR);
-
- if (jobClass == null)
- throw new SchedulerException("Job's class cannot be null",
- SchedulerException.ERR_CLIENT_ERROR);
- }
-
- /**
- *
- * Set whether or not the Job 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.
- *
- */
- public void setVolatility(boolean volatility) {
- this.volatility = volatility;
- }
-
- /**
- *
- * Set whether or not the Job should remain stored after it
- * is orphaned (no {@link Trigger}s point to it).
- *
- *
- *
- * If not explicitly set, the default value is false.
- *
- */
- public void setDurability(boolean durability) {
- this.durability = durability;
- }
-
- /**
- *
- * Set whether or not the the Scheduler should re-execute
- * the Job if a 'recovery' or 'fail-over' situation is
- * encountered.
- *
- *
- *
- * If not explicitly set, the default value is false.
- *
- *
- * @see JobExecutionContext#isRecovering()
- * @see JobExecutionContext#isFailedOver()
- */
- public void setRequestsRecovery(boolean shouldRecover) {
- this.shouldRecover = shouldRecover;
- }
-
- /**
- *
- * Whether or not the Job should not 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 Job should be garbage
- * collected along with the {@link Scheduler}.
- */
- public boolean isVolatile() {
- return volatility;
- }
-
- /**
- *
* Whether or not the Job should remain stored after it is
* orphaned (no {@link Trigger}s point to it).
*
@@ -385,21 +87,19 @@
* @return true if the Job should remain persisted after
* being orphaned.
*/
- public boolean isDurable() {
- return durability;
- }
+ public boolean isDurable();
/**
- *
- * Whether or not the Job implements the interface {@link StatefulJob}.
- *
+ * @see PersistJobDataAfterExecution
+ * @return whether the associated Job class carries the {@link PersistJobDataAfterExecution} annotation.
*/
- public boolean isStateful() {
- if (jobClass == null)
- return false;
+ public boolean isPersistJobDataAfterExecution();
- return (StatefulJob.class.isAssignableFrom(jobClass));
- }
+ /**
+ * @see DisallowConcurrentExecution
+ * @return whether the associated Job class carries the {@link DisallowConcurrentExecution} annotation.
+ */
+ public boolean isConcurrentExectionDisallowed();
/**
*
@@ -413,70 +113,15 @@
*
*
* @see JobExecutionContext#isRecovering()
- * @see JobExecutionContext#isFailedOver()
*/
- public boolean requestsRecovery() {
- return shouldRecover;
- }
+ public boolean requestsRecovery();
+ public Object clone();
+
/**
- *
- * Add the specified name of a {@link JobListener} to the
- * end of the Job's list of listeners.
- *
+ * Get a {@link JobBuilder} that is configured to produce a
+ * JobDetail identical to this one.
*/
- public void addJobListener(String name) {
- jobListeners.add(name);
- }
+ public JobBuilder getJobBuilder();
- /**
- *
- * Remove the specified name of a {@link JobListener} from
- * the Job's list of listeners.
- *
- *
- * @return true if the given name was found in the list, and removed
- */
- public boolean removeJobListener(String name) {
- return jobListeners.remove(name);
- }
-
- /**
- *
- * Returns an array of String s containing the names of all
- * {@link JobListener} s assigned to the Job,
- * in the order in which they should be notified.
- *
- */
- public String[] getJobListenerNames() {
- return (String[]) jobListeners.toArray(new String[jobListeners.size()]);
- }
-
- /**
- *
- * Return a simple string representation of this object.
- *
- */
- public String toString() {
- return "JobDetail '" + getFullName() + "': jobClass: '"
- + ((getJobClass() == null) ? null : getJobClass().getName())
- + " isStateful: " + isStateful() + " isVolatile: "
- + isVolatile() + " isDurable: " + isDurable()
- + " requestsRecovers: " + requestsRecovery();
- }
-
- public Object clone() {
- JobDetail copy;
- try {
- copy = (JobDetail) super.clone();
- copy.jobListeners = (ArrayList) jobListeners.clone();
- if (jobDataMap != null)
- copy.jobDataMap = (JobDataMap) jobDataMap.clone();
- } catch (CloneNotSupportedException ex) {
- throw new IncompatibleClassChangeError("Not Cloneable.");
- }
-
- return copy;
- }
-
-}
+}
\ No newline at end of file
Index: 3rdParty_sources/quartz/org/quartz/JobExecutionContext.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/JobExecutionContext.java (.../JobExecutionContext.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/JobExecutionContext.java (.../JobExecutionContext.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,5 @@
-
-/*
- * Copyright 2004-2005 OpenSymphony
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*
* 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
@@ -16,23 +15,15 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
import java.util.Date;
-import java.util.HashMap;
-import org.quartz.spi.TriggerFiredBundle;
-
/**
- *
* A context bundle containing handles to various environment information, that
* is given to a {@link org.quartz.JobDetail} instance as it is
* executed, and to a {@link Trigger} instance after the
* execution completes.
- *
*
*
* The JobDataMap found on this object (via the
@@ -43,13 +34,14 @@
* It is thus considered a 'best practice' that the execute code of a Job
* retrieve data from the JobDataMap found on this object NOTE: Do not
* expect value 'set' into this JobDataMap to somehow be set back onto a
- * StatefulJob's own JobDataMap.
+ * job's own JobDataMap - even if it has the
+ * @PersistJobDataAfterExecution annotation.
*
*
*
* JobExecutionContext s are also returned from the
* Scheduler.getCurrentlyExecutingJobs()
- * method. These are the same instances as those past into the jobs that are
+ * method. These are the same instances as those passed into the jobs that are
* currently executing within the scheduler. The exception to this is when your
* application is using Quartz remotely (i.e. via RMI) - in which case you get
* a clone of the JobExecutionContexts, and their references to
@@ -58,145 +50,66 @@
* to the job instance that is running).
*
*
- * @see #getJobDetail()
* @see #getScheduler()
* @see #getMergedJobDataMap()
+ * @see #getJobDetail()
*
* @see Job
* @see Trigger
* @see JobDataMap
*
* @author James House
*/
-public class JobExecutionContext implements java.io.Serializable {
+public interface JobExecutionContext {
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- private transient Scheduler scheduler;
-
- private Trigger trigger;
-
- private JobDetail jobDetail;
-
- private JobDataMap jobDataMap;
-
- private transient Job job;
-
- private Calendar calendar;
-
- private boolean recovering = false;
-
- private int numRefires = 0;
-
- private Date fireTime;
-
- private Date scheduledFireTime;
-
- private Date prevFireTime;
-
- private Date nextFireTime;
-
- private long jobRunTime = -1;
-
- private Object result;
-
- private HashMap data = new HashMap();
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
/**
*
- * Create a JobExcecutionContext with the given context data.
- *
- */
- public JobExecutionContext(Scheduler scheduler,
- TriggerFiredBundle firedBundle, Job job) {
- this.scheduler = scheduler;
- this.trigger = firedBundle.getTrigger();
- this.calendar = firedBundle.getCalendar();
- this.jobDetail = firedBundle.getJobDetail();
- this.job = job;
- this.recovering = firedBundle.isRecovering();
- this.fireTime = firedBundle.getFireTime();
- this.scheduledFireTime = firedBundle.getScheduledFireTime();
- this.prevFireTime = firedBundle.getPrevFireTime();
- this.nextFireTime = firedBundle.getNextFireTime();
-
- this.jobDataMap = new JobDataMap();
- this.jobDataMap.putAll(jobDetail.getJobDataMap());
- this.jobDataMap.putAll(trigger.getJobDataMap());
-
- this.jobDataMap.setMutable(false);
- this.trigger.getJobDataMap().setMutable(false);
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- *
* Get a handle to the Scheduler instance that fired the
* Job.
*
*/
- public Scheduler getScheduler() {
- return scheduler;
- }
+ public Scheduler getScheduler();
/**
*
* Get a handle to the Trigger instance that fired the
* Job.
*
*/
- public Trigger getTrigger() {
- return trigger;
- }
+ public Trigger getTrigger();
/**
*
* Get a handle to the Calendar referenced by the Trigger
* instance that fired the Job.
*
*/
- public Calendar getCalendar() {
- return calendar;
- }
+ public Calendar getCalendar();
/**
*
* If the Job is being re-executed because of a 'recovery'
* situation, this method will return true.
*
*/
- public boolean isRecovering() {
- return recovering;
- }
+ public boolean isRecovering();
- public void incrementRefireCount() {
- numRefires++;
- }
+ /**
+ * Return the {@code TriggerKey} of the originally scheduled and now recovering job.
+ *
+ * When recovering a previously failed job execution this method returns the identity
+ * of the originally firing trigger. This recovering job will have been scheduled for
+ * the same firing time as the original job, and so is available via the
+ * {@link #getScheduledFireTime()} method. The original firing time of the job can be
+ * accessed via the {@link Scheduler#FAILED_JOB_ORIGINAL_TRIGGER_FIRETIME_IN_MILLISECONDS}
+ * element of this job's {@code JobDataMap}.
+ *
+ * @return the recovering trigger details
+ * @throws IllegalStateException if this is not a recovering job.
+ */
+ public TriggerKey getRecoveringTriggerKey() throws IllegalStateException;
- public int getRefireCount() {
- return numRefires;
- }
+ public int getRefireCount();
/**
*
@@ -209,12 +122,12 @@
* JobDetail and the one found on the Trigger, with
* the value in the latter overriding any same-named values in the former.
* It is thus considered a 'best practice' that the execute code of a Job
- * retrieve data from the JobDataMap found on this object
+ * retrieve data from the JobDataMap found on this object.
*
*
- * NOTE: Do not
- * expect value 'set' into this JobDataMap to somehow be set back onto a
- * StatefulJob's own JobDataMap.
+ *
NOTE: Do not expect value 'set' into this JobDataMap to somehow be set
+ * or persisted back onto a job's own JobDataMap - even if it has the
+ * @PersistJobDataAfterExecution annotation.
*
*
*
@@ -223,18 +136,14 @@
*
*
*/
- public JobDataMap getMergedJobDataMap() {
- return jobDataMap;
- }
+ public JobDataMap getMergedJobDataMap();
/**
*
* Get the JobDetail associated with the Job.
*
*/
- public JobDetail getJobDetail() {
- return jobDetail;
- }
+ public JobDetail getJobDetail();
/**
*
@@ -247,9 +156,7 @@
* interfaces.
*
*/
- public Job getJobInstance() {
- return job;
- }
+ public Job getJobInstance();
/**
* The actual time the trigger fired. For instance the scheduled time may
@@ -259,9 +166,7 @@
* @return Returns the fireTime.
* @see #getScheduledFireTime()
*/
- public Date getFireTime() {
- return fireTime;
- }
+ public Date getFireTime();
/**
* The scheduled time the trigger fired for. For instance the scheduled
@@ -271,29 +176,23 @@
* @return Returns the scheduledFireTime.
* @see #getFireTime()
*/
- public Date getScheduledFireTime() {
- return scheduledFireTime;
- }
+ public Date getScheduledFireTime();
- public Date getPreviousFireTime() {
- return prevFireTime;
- }
+ public Date getPreviousFireTime();
- public Date getNextFireTime() {
- return nextFireTime;
- }
+ public Date getNextFireTime();
- public String toString() {
- return "JobExecutionContext:" + " trigger: '"
- + getTrigger().getFullName() + " job: "
- + getJobDetail().getFullName() + " fireTime: '" + getFireTime()
- + " scheduledFireTime: " + getScheduledFireTime()
- + " previousFireTime: '" + getPreviousFireTime()
- + " nextFireTime: " + getNextFireTime() + " isRecovering: "
- + isRecovering() + " refireCount: " + getRefireCount();
- }
-
/**
+ * Get the unique Id that identifies this particular firing instance of the
+ * trigger that triggered this job execution. It is unique to this
+ * JobExecutionContext instance as well.
+ *
+ * @return the unique fire instance id
+ * @see Scheduler#interrupt(String)
+ */
+ public String getFireInstanceId();
+
+ /**
* Returns the result (if any) that the Job set before its
* execution completed (the type of object set as the result is entirely up
* to the particular job).
@@ -307,10 +206,8 @@
*
* @return Returns the result.
*/
- public Object getResult() {
- return result;
- }
-
+ public Object getResult();
+
/**
* Set the result (if any) of the Job's execution (the type of
* object set as the result is entirely up to the particular job).
@@ -321,13 +218,9 @@
* {@link TriggerListener}s that are watching the job's
* execution.
*
- *
- * @return Returns the result.
*/
- public void setResult(Object result) {
- this.result = result;
- }
-
+ public void setResult(Object result);
+
/**
* The amount of time the job ran for (in milliseconds). The returned
* value will be -1 until the job has actually completed (or thrown an
@@ -336,16 +229,7 @@
*
* @return Returns the jobRunTime.
*/
- public long getJobRunTime() {
- return jobRunTime;
- }
-
- /**
- * @param jobRunTime The jobRunTime to set.
- */
- public void setJobRunTime(long jobRunTime) {
- this.jobRunTime = jobRunTime;
- }
+ public long getJobRunTime();
/**
* Put the specified value into the context's data map with the given key.
@@ -355,19 +239,16 @@
* completes, and all TriggerListeners and JobListeners have been
* notified.
*
- * @param key
- * @param value
+ * @param key the key for the associated value
+ * @param value the value to store
*/
- public void put(Object key, Object value) {
- data.put(key, value);
- }
-
+ public void put(Object key, Object value);
+
/**
* Get the value with the given key from the context's data map.
*
- * @param key
+ * @param key the key for the desired value
*/
- public Object get(Object key) {
- return data.get(key);
- }
-}
+ public Object get(Object key);
+
+}
\ No newline at end of file
Index: 3rdParty_sources/quartz/org/quartz/JobExecutionException.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/JobExecutionException.java (.../JobExecutionException.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/JobExecutionException.java (.../JobExecutionException.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,19 +16,14 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* An exception that can be thrown by a {@link org.quartz.Job}
* to indicate to the Quartz {@link Scheduler} that an error
- * occured while executing, and whether or not the Job requests
+ * occurred while executing, and whether or not the Job requests
* to be re-fired immediately (using the same {@link JobExecutionContext},
* or whether it wants to be unscheduled.
- *
*
*
* Note that if the flag for 'refire immediately' is set, the flags for
@@ -43,6 +38,8 @@
*/
public class JobExecutionException extends SchedulerException {
+ private static final long serialVersionUID = 1326342535829043325L;
+
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -79,7 +76,7 @@
* Create a JobExcecutionException, with the given cause.
*
*/
- public JobExecutionException(Exception cause) {
+ public JobExecutionException(Throwable cause) {
super(cause);
}
@@ -108,7 +105,7 @@
* the 're-fire immediately' flag set to the given value.
*
*/
- public JobExecutionException(Exception cause, boolean refireImmediately) {
+ public JobExecutionException(Throwable cause, boolean refireImmediately) {
super(cause);
refire = refireImmediately;
@@ -117,16 +114,36 @@
/**
*
* Create a JobExcecutionException with the given message, and underlying
+ * exception.
+ *
+ */
+ public JobExecutionException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ /**
+ *
+ * Create a JobExcecutionException with the given message, and underlying
* exception, and the 're-fire immediately' flag set to the given value.
*
*/
- public JobExecutionException(String msg, Exception cause,
+ public JobExecutionException(String msg, Throwable cause,
boolean refireImmediately) {
super(msg, cause);
refire = refireImmediately;
}
+
+ /**
+ * Create a JobExcecutionException with the given message and the 're-fire
+ * immediately' flag set to the given value.
+ */
+ public JobExecutionException(String msg, boolean refireImmediately) {
+ super(msg);
+ refire = refireImmediately;
+ }
+
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -135,6 +152,10 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
+ public void setRefireImmediately(boolean refire) {
+ this.refire = refire;
+ }
+
public boolean refireImmediately() {
return refire;
}
Index: 3rdParty_sources/quartz/org/quartz/JobKey.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/JobKey.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/JobKey.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,77 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import org.quartz.utils.Key;
+
+/**
+ * Uniquely identifies a {@link JobDetail}.
+ *
+ * Keys are composed of both a name and group, and the name must be unique
+ * within the group. If only a group is specified then the default group
+ * name will be used.
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(simpleSchedule()
+ * .withIntervalInHours(1)
+ * .repeatForever())
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ *
+ * @see Job
+ * @see Key#DEFAULT_GROUP
+ */
+public final class JobKey extends Key {
+
+ private static final long serialVersionUID = -6073883950062574010L;
+
+ public JobKey(String name) {
+ super(name, null);
+ }
+
+ public JobKey(String name, String group) {
+ super(name, group);
+ }
+
+ public static JobKey jobKey(String name) {
+ return new JobKey(name, null);
+ }
+
+ public static JobKey jobKey(String name, String group) {
+ return new JobKey(name, group);
+ }
+
+}
Index: 3rdParty_sources/quartz/org/quartz/JobListener.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/JobListener.java (.../JobListener.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/JobListener.java (.../JobListener.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,20 +16,16 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* The interface to be implemented by classes that want to be informed when a
* {@link org.quartz.JobDetail} executes. In general,
* applications that use a Scheduler will not have use for this
* mechanism.
- *
*
- * @see Scheduler
+ * @see ListenerManager#addJobListener(JobListener, Matcher)
+ * @see Matcher
* @see Job
* @see JobExecutionContext
* @see JobExecutionException
@@ -52,13 +48,13 @@
* Get the name of the JobListener.
*
*/
- public String getName();
+ String getName();
/**
*
* Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
* is about to be executed (an associated {@link Trigger}
- * has occured).
+ * has occurred).
*
*
*
@@ -68,19 +64,19 @@
*
* @see #jobExecutionVetoed(JobExecutionContext)
*/
- public void jobToBeExecuted(JobExecutionContext context);
+ void jobToBeExecuted(JobExecutionContext context);
/**
*
* Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
* was about to be executed (an associated {@link Trigger}
- * has occured), but a {@link TriggerListener} vetoed it's
+ * has occurred), but a {@link TriggerListener} vetoed it's
* execution.
*
*
* @see #jobToBeExecuted(JobExecutionContext)
*/
- public void jobExecutionVetoed(JobExecutionContext context);
+ void jobExecutionVetoed(JobExecutionContext context);
/**
@@ -90,7 +86,7 @@
* triggered(xx) method has been called.
*
*/
- public void jobWasExecuted(JobExecutionContext context,
+ void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException);
}
Index: 3rdParty_sources/quartz/org/quartz/JobPersistenceException.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/JobPersistenceException.java (.../JobPersistenceException.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/JobPersistenceException.java (.../JobPersistenceException.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,20 +16,17 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* An exception that is thrown to indicate that there has been a failure in the
* scheduler's underlying persistence mechanism.
- *
*
* @author James House
*/
public class JobPersistenceException extends SchedulerException {
+
+ private static final long serialVersionUID = -8924958757341995694L;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -46,38 +43,17 @@
*/
public JobPersistenceException(String msg) {
super(msg);
- setErrorCode(ERR_PERSISTENCE);
}
- /**
- *
- * Create a JobPersistenceException with the given message
- * and error code.
- *
- */
- public JobPersistenceException(String msg, int errCode) {
- super(msg, errCode);
- }
/**
*
* Create a JobPersistenceException with the given message
* and cause.
*
*/
- public JobPersistenceException(String msg, Exception cause) {
+ public JobPersistenceException(String msg, Throwable cause) {
super(msg, cause);
- setErrorCode(ERR_PERSISTENCE);
}
- /**
- *
- * Create a JobPersistenceException with the given message,
- * cause and error code.
- *
- */
- public JobPersistenceException(String msg, Exception cause, int errorCode) {
- super(msg, cause, errorCode);
- }
-
}
Index: 3rdParty_sources/quartz/org/quartz/ListenerManager.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/ListenerManager.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/ListenerManager.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,277 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.util.List;
+
+/**
+ * Client programs may be interested in the 'listener' interfaces that are
+ * available from Quartz. The {@link JobListener} interface
+ * provides notifications of Job executions. The
+ * {@link TriggerListener} interface provides notifications of
+ * Trigger firings. The {@link SchedulerListener}
+ * interface provides notifications of Scheduler events and
+ * errors. Listeners can be associated with local schedulers through the
+ * {@link ListenerManager} interface.
+ *
+ * Listener registration order is preserved, and hence notification of listeners
+ * will be in the order in which they were registered.
+ *
+ * @author jhouse
+ * @since 2.0 - previously listeners were managed directly on the Scheduler interface.
+ */
+public interface ListenerManager {
+
+ /**
+ * Add the given {@link JobListener} to the Scheduler,
+ * and register it to receive events for all Jobs.
+ *
+ * Because no matchers are provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addJobListener(JobListener jobListener);
+
+ /**
+ * Add the given {@link JobListener} to the Scheduler,
+ * and register it to receive events for Jobs that are matched by the
+ * given Matcher.
+ *
+ * If no matchers are provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addJobListener(JobListener jobListener, Matcher matcher);
+
+ /**
+ * Add the given {@link JobListener} to the Scheduler,
+ * and register it to receive events for Jobs that are matched by ANY of the
+ * given Matchers.
+ *
+ * If no matchers are provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addJobListener(JobListener jobListener, Matcher ... matchers);
+
+ /**
+ * Add the given {@link JobListener} to the Scheduler,
+ * and register it to receive events for Jobs that are matched by ANY of the
+ * given Matchers.
+ *
+ * If no matchers are provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addJobListener(JobListener jobListener, List> matchers);
+
+ /**
+ * Add the given Matcher to the set of matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @param matcher the additional matcher to apply for selecting events
+ * @return true if the identified listener was found and updated
+ */
+ public boolean addJobListenerMatcher(String listenerName, Matcher matcher);
+
+ /**
+ * Remove the given Matcher to the set of matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @param matcher the additional matcher to apply for selecting events
+ * @return true if the given matcher was found and removed from the listener's list of matchers
+ */
+ public boolean removeJobListenerMatcher(String listenerName, Matcher matcher);
+
+ /**
+ * Set the set of Matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ * Removes any existing matchers for the identified listener!
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @param matchers the matchers to apply for selecting events
+ * @return true if the given matcher was found and removed from the listener's list of matchers
+ */
+ public boolean setJobListenerMatchers(String listenerName, List> matchers);
+
+ /**
+ * Get the set of Matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @return the matchers registered for selecting events for the identified listener
+ */
+ public List> getJobListenerMatchers(String listenerName);
+
+ /**
+ * Remove the identified {@link JobListener} from the Scheduler.
+ *
+ * @return true if the identified listener was found in the list, and
+ * removed.
+ */
+ public boolean removeJobListener(String name);
+
+ /**
+ * Get a List containing all of the {@link JobListener}s in
+ * the Scheduler, in the order in which they were registered.
+ */
+ public List getJobListeners();
+
+ /**
+ * Get the {@link JobListener} that has the given name.
+ */
+ public JobListener getJobListener(String name);
+
+ /**
+ * Add the given {@link TriggerListener} to the Scheduler,
+ * and register it to receive events for all Triggers.
+ *
+ * Because no matcher is provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addTriggerListener(TriggerListener triggerListener);
+
+ /**
+ * Add the given {@link TriggerListener} to the Scheduler,
+ * and register it to receive events for Triggers that are matched by the
+ * given Matcher.
+ *
+ * If no matcher is provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addTriggerListener(TriggerListener triggerListener, Matcher matcher);
+
+ /**
+ * Add the given {@link TriggerListener} to the Scheduler,
+ * and register it to receive events for Triggers that are matched by ANY of the
+ * given Matchers.
+ *
+ * If no matcher is provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addTriggerListener(TriggerListener triggerListener, Matcher ... matchers);
+
+ /**
+ * Add the given {@link TriggerListener} to the Scheduler,
+ * and register it to receive events for Triggers that are matched by ANY of the
+ * given Matchers.
+ *
+ * If no matcher is provided, the EverythingMatcher will be used.
+ *
+ * @see Matcher
+ * @see org.quartz.impl.matchers.EverythingMatcher
+ */
+ public void addTriggerListener(TriggerListener triggerListener, List> matchers);
+
+ /**
+ * Add the given Matcher to the set of matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @param matcher the additional matcher to apply for selecting events
+ * @return true if the identified listener was found and updated
+ */
+ public boolean addTriggerListenerMatcher(String listenerName, Matcher matcher);
+
+ /**
+ * Remove the given Matcher to the set of matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @param matcher the additional matcher to apply for selecting events
+ * @return true if the given matcher was found and removed from the listener's list of matchers
+ */
+ public boolean removeTriggerListenerMatcher(String listenerName, Matcher matcher);
+
+ /**
+ * Set the set of Matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ * Removes any existing matchers for the identified listener!
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @param matchers the matchers to apply for selecting events
+ * @return true if the given matcher was found and removed from the listener's list of matchers
+ */
+ public boolean setTriggerListenerMatchers(String listenerName, List> matchers);
+
+ /**
+ * Get the set of Matchers for which the listener
+ * will receive events if ANY of the matchers match.
+ *
+ *
+ * @param listenerName the name of the listener to add the matcher to
+ * @return the matchers registered for selecting events for the identified listener
+ */
+ public List> getTriggerListenerMatchers( String listenerName);
+
+ /**
+ * Remove the identified {@link TriggerListener} from the Scheduler.
+ *
+ * @return true if the identified listener was found in the list, and
+ * removed.
+ */
+ public boolean removeTriggerListener(String name);
+
+ /**
+ * Get a List containing all of the {@link TriggerListener}s
+ * in the Scheduler, in the order in which they were registered.
+ */
+ public List getTriggerListeners();
+
+ /**
+ * Get the {@link TriggerListener} that has the given name.
+ */
+ public TriggerListener getTriggerListener(String name);
+
+ /**
+ * Register the given {@link SchedulerListener} with the
+ * Scheduler.
+ */
+ public void addSchedulerListener(SchedulerListener schedulerListener);
+
+ /**
+ * Remove the given {@link SchedulerListener} from the
+ * Scheduler.
+ *
+ * @return true if the identified listener was found in the list, and
+ * removed.
+ */
+ public boolean removeSchedulerListener(SchedulerListener schedulerListener);
+
+ /**
+ * Get a List containing all of the {@link SchedulerListener}s
+ * registered with the Scheduler, in the order in which they were registered.
+ */
+ public List getSchedulerListeners();
+
+}
\ No newline at end of file
Index: 3rdParty_sources/quartz/org/quartz/Matcher.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/Matcher.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/Matcher.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,38 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.io.Serializable;
+
+import org.quartz.utils.Key;
+
+/**
+ * Matchers can be used in various {@link Scheduler} API methods to
+ * select the entities that should be operated upon.
+ *
+ * @author jhouse
+ * @since 2.0
+ */
+public interface Matcher> extends Serializable {
+
+ boolean isMatch(T key);
+
+ public int hashCode();
+
+ public boolean equals(Object obj);
+}
Fisheye: Tag c208628989d52041b3765784f4c8cbfd6c80d47b refers to a dead (removed) revision in file `3rdParty_sources/quartz/org/quartz/NthIncludedDayTrigger.java'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/quartz/org/quartz/ObjectAlreadyExistsException.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/ObjectAlreadyExistsException.java (.../ObjectAlreadyExistsException.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/ObjectAlreadyExistsException.java (.../ObjectAlreadyExistsException.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,22 +16,19 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* An exception that is thrown to indicate that an attempt to store a new
* object (i.e. {@link org.quartz.JobDetail},{@link Trigger}
* or {@link Calendar}) in a {@link Scheduler}
* failed, because one with the same name & group already exists.
- *
*
* @author James House
*/
public class ObjectAlreadyExistsException extends JobPersistenceException {
+
+ private static final long serialVersionUID = -558301282071659896L;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -63,8 +60,7 @@
*
*/
public ObjectAlreadyExistsException(JobDetail offendingJob) {
- super("Unable to store Job with name: '" + offendingJob.getName()
- + "' and group: '" + offendingJob.getGroup()
+ super("Unable to store Job : '" + offendingJob.getKey()
+ "', because one already exists with this identification.");
}
@@ -81,8 +77,8 @@
*/
public ObjectAlreadyExistsException(Trigger offendingTrigger) {
super("Unable to store Trigger with name: '"
- + offendingTrigger.getName() + "' and group: '"
- + offendingTrigger.getGroup()
+ + offendingTrigger.getKey().getName() + "' and group: '"
+ + offendingTrigger.getKey().getGroup()
+ "', because one already exists with this identification.");
}
Index: 3rdParty_sources/quartz/org/quartz/PersistJobDataAfterExecution.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/PersistJobDataAfterExecution.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/PersistJobDataAfterExecution.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,44 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation that marks a {@link Job} class as one that makes updates to its
+ * {@link JobDataMap} during execution, and wishes the scheduler to re-store the
+ * JobDataMap when execution completes.
+ *
+ * Jobs that are marked with this annotation should also seriously consider
+ * using the {@link DisallowConcurrentExecution} annotation, to avoid data
+ * storage race conditions with concurrently executing job instances.
+ *
+ * @see DisallowConcurrentExecution
+ *
+ * @author jhouse
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface PersistJobDataAfterExecution {
+
+}
Index: 3rdParty_sources/quartz/org/quartz/ScheduleBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/ScheduleBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/ScheduleBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,26 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import org.quartz.spi.MutableTrigger;
+
+public abstract class ScheduleBuilder {
+
+ protected abstract MutableTrigger build();
+
+}
Index: 3rdParty_sources/quartz/org/quartz/Scheduler.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/Scheduler.java (.../Scheduler.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/Scheduler.java (.../Scheduler.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,26 +16,25 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import org.quartz.Trigger.TriggerState;
+import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.spi.JobFactory;
+import org.quartz.utils.Key;
/**
- *
* This is the main interface of a Quartz Scheduler.
- *
*
*
- * A Scheduler maintains a registery of {@link org.quartz.JobDetail}
- * s and {@link Trigger}s. Once registered, the Scheduler
- * is responible for executing Job s when their associated
+ * A Scheduler maintains a registry of {@link org.quartz.JobDetail}s
+ * and {@link Trigger}s. Once registered, the Scheduler
+ * is responsible for executing Job s when their associated
* Trigger s fire (when their scheduled time arrives).
*
*
@@ -87,7 +86,8 @@
* provides notifications of Job executions. The {@link TriggerListener}
* interface provides notifications of Trigger firings. The
* {@link SchedulerListener} interface provides notifications of
- * Scheduler events and errors.
+ * Scheduler events and errors. Listeners can be associated with
+ * local schedulers through the {@link ListenerManager} interface.
*
*
*
@@ -97,7 +97,9 @@
*
* @see Job
* @see JobDetail
+ * @see JobBuilder
* @see Trigger
+ * @see TriggerBuilder
* @see JobListener
* @see TriggerListener
* @see SchedulerListener
@@ -116,40 +118,78 @@
*/
/**
- *
- * A (possibly) usefull constant that can be used for specifying the group
+ * A (possibly) useful constant that can be used for specifying the group
* that Job and Trigger instances belong to.
- *
*/
- public static final String DEFAULT_GROUP = "DEFAULT";
+ String DEFAULT_GROUP = Key.DEFAULT_GROUP;
/**
- *
* A constant Trigger group name used internally by the
* scheduler - clients should not use the value of this constant
- * ("MANUAL_TRIGGER") for thename of a Trigger's group.
- *
+ * ("RECOVERING_JOBS") for the name of a Trigger's group.
+ *
+ * @see org.quartz.JobDetail#requestsRecovery()
*/
- public static final String DEFAULT_MANUAL_TRIGGERS = "MANUAL_TRIGGER";
+ String DEFAULT_RECOVERY_GROUP = "RECOVERING_JOBS";
/**
- *
* A constant Trigger group name used internally by the
* scheduler - clients should not use the value of this constant
- * ("RECOVERING_JOBS") for thename of a Trigger's group.
- *
+ * ("FAILED_OVER_JOBS") for the name of a Trigger's group.
+ *
+ * @see org.quartz.JobDetail#requestsRecovery()
*/
- public static final String DEFAULT_RECOVERY_GROUP = "RECOVERING_JOBS";
+ String DEFAULT_FAIL_OVER_GROUP = "FAILED_OVER_JOBS";
+
/**
- *
- * A constant Trigger group name used internally by the
- * scheduler - clients should not use the value of this constant
- * ("FAILED_OVER_JOBS") for thename of a Trigger's group.
- *
+ * A constant JobDataMap key that can be used to retrieve the
+ * name of the original Trigger from a recovery trigger's
+ * data map in the case of a job recovering after a failed scheduler
+ * instance.
+ *
+ * @see org.quartz.JobDetail#requestsRecovery()
*/
- public static final String DEFAULT_FAIL_OVER_GROUP = "FAILED_OVER_JOBS";
+ String FAILED_JOB_ORIGINAL_TRIGGER_NAME = "QRTZ_FAILED_JOB_ORIG_TRIGGER_NAME";
+ /**
+ * A constant JobDataMap key that can be used to retrieve the
+ * group of the original Trigger from a recovery trigger's
+ * data map in the case of a job recovering after a failed scheduler
+ * instance.
+ *
+ * @see org.quartz.JobDetail#requestsRecovery()
+ */
+ String FAILED_JOB_ORIGINAL_TRIGGER_GROUP = "QRTZ_FAILED_JOB_ORIG_TRIGGER_GROUP";
+
+ /**
+ * A constant JobDataMap key that can be used to retrieve the
+ * fire time of the original Trigger from a recovery
+ * trigger's data map in the case of a job recovering after a failed scheduler
+ * instance.
+ *
+ * Note that this is the time the original firing actually occurred,
+ * which may be different from the scheduled fire time - as a trigger doesn't
+ * always fire exactly on time.
+ *
+ * @see org.quartz.JobDetail#requestsRecovery()
+ */
+ String FAILED_JOB_ORIGINAL_TRIGGER_FIRETIME_IN_MILLISECONDS = "QRTZ_FAILED_JOB_ORIG_TRIGGER_FIRETIME_IN_MILLISECONDS_AS_STRING";
+
+ /**
+ * A constant JobDataMap key that can be used to retrieve the
+ * scheduled fire time of the original Trigger from a recovery
+ * trigger's data map in the case of a job recovering after a failed scheduler
+ * instance.
+ *
+ * Note that this is the time the original firing was scheduled for,
+ * which may be different from the actual firing time - as a trigger doesn't
+ * always fire exactly on time.
+ *
+ * @see org.quartz.JobDetail#requestsRecovery()
+ */
+ String FAILED_JOB_ORIGINAL_TRIGGER_SCHEDULED_FIRETIME_IN_MILLISECONDS = "QRTZ_FAILED_JOB_ORIG_TRIGGER_SCHEDULED_FIRETIME_IN_MILLISECONDS_AS_STRING";
+
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -159,39 +199,31 @@
*/
/**
- *
* Returns the name of the Scheduler.
- *
*/
- public String getSchedulerName() throws SchedulerException;
+ String getSchedulerName() throws SchedulerException;
/**
- *
* Returns the instance Id of the Scheduler.
- *
*/
- public String getSchedulerInstanceId() throws SchedulerException;
+ String getSchedulerInstanceId() throws SchedulerException;
/**
- *
* Returns the SchedulerContext of the Scheduler.
- *
*/
- public SchedulerContext getContext() throws SchedulerException;
+ SchedulerContext getContext() throws SchedulerException;
///////////////////////////////////////////////////////////////////////////
///
- /// Schedululer State Management Methods
+ /// Scheduler State Management Methods
///
///////////////////////////////////////////////////////////////////////////
-
+
/**
- *
* Starts the Scheduler's threads that fire {@link Trigger}s.
* When a scheduler is first created it is in "stand-by" mode, and will not
* fire triggers. The scheduler can also be put into stand-by mode by
* calling the standby() method.
- *
*
*
* The misfire/recovery process will be started, if it is the initial call
@@ -201,17 +233,48 @@
* @throws SchedulerException
* if shutdown() has been called, or there is an
* error within the Scheduler.
- *
- * @see #standby
- * @see #shutdown
+ *
+ * @see #startDelayed(int)
+ * @see #standby()
+ * @see #shutdown()
*/
- public void start() throws SchedulerException;
+ void start() throws SchedulerException;
/**
+ * Calls {#start()} after the indicated number of seconds.
+ * (This call does not block). This can be useful within applications that
+ * have initializers that create the scheduler immediately, before the
+ * resources needed by the executing jobs have been fully initialized.
+ *
+ * @throws SchedulerException
+ * if shutdown() has been called, or there is an
+ * error within the Scheduler.
+ *
+ * @see #start()
+ * @see #standby()
+ * @see #shutdown()
+ */
+ void startDelayed(int seconds) throws SchedulerException;
+
+ /**
+ * Whether the scheduler has been started.
+ *
*
- * Temporarily halts the Scheduler's firing of {@link Trigger}s.
+ * Note: This only reflects whether {@link #start()} has ever
+ * been called on this Scheduler, so it will return true even
+ * if the Scheduler is currently in standby mode or has been
+ * since shutdown.
*
*
+ * @see #start()
+ * @see #isShutdown()
+ * @see #isInStandbyMode()
+ */
+ boolean isStarted() throws SchedulerException;
+
+ /**
+ * Temporarily halts the Scheduler's firing of {@link Trigger}s.
+ *
*
* When start() is called (to bring the scheduler out of
* stand-by mode), trigger misfire instructions will NOT be applied
@@ -227,50 +290,32 @@
* @see #start()
* @see #pauseAll()
*/
- public void standby() throws SchedulerException;
+ void standby() throws SchedulerException;
/**
- * @deprecated replaced by better-named standby() method.
- * @see #standby()
- */
- public void pause() throws SchedulerException;
-
- /**
- *
* Reports whether the Scheduler is in stand-by mode.
- *
*
* @see #standby()
* @see #start()
*/
- public boolean isInStandbyMode() throws SchedulerException;
+ boolean isInStandbyMode() throws SchedulerException;
/**
- * @deprecated
- * @see #isInStandbyMode()
- */
- public boolean isPaused() throws SchedulerException;
-
- /**
- *
* Halts the Scheduler's firing of {@link Trigger}s,
* and cleans up all resources associated with the Scheduler. Equivalent to
* shutdown(false).
- *
*
*
* The scheduler cannot be re-started.
*
*
* @see #shutdown(boolean)
*/
- public void shutdown() throws SchedulerException;
+ void shutdown() throws SchedulerException;
/**
- *
* Halts the Scheduler's firing of {@link Trigger}s,
* and cleans up all resources associated with the Scheduler.
- *
*
*
* The scheduler cannot be re-started.
@@ -282,33 +327,33 @@
*
* @see #shutdown
*/
- public void shutdown(boolean waitForJobsToComplete)
- throws SchedulerException;
+ void shutdown(boolean waitForJobsToComplete)
+ throws SchedulerException;
/**
- *
* Reports whether the Scheduler has been shutdown.
- *
*/
- public boolean isShutdown() throws SchedulerException;
+ boolean isShutdown() throws SchedulerException;
/**
- *
- * Get a SchedulerMetaData object describiing the settings
+ * Get a SchedulerMetaData object describing the settings
* and capabilities of the scheduler instance.
- *
*
*
* Note that the data returned is an 'instantaneous' snap-shot, and that as
* soon as it's returned, the meta data values may be different.
*
*/
- public SchedulerMetaData getMetaData() throws SchedulerException;
+ SchedulerMetaData getMetaData() throws SchedulerException;
/**
- *
* Return a list of JobExecutionContext objects that
- * represent all currently executing Jobs.
+ * represent all currently executing Jobs in this Scheduler instance.
+ *
+ *
+ * This method is not cluster aware. That is, it will only return Jobs
+ * currently executing in this Scheduler instance, not across the entire
+ * cluster.
*
*
*
@@ -320,37 +365,46 @@
*
* @see JobExecutionContext
*/
- public List getCurrentlyExecutingJobs() throws SchedulerException;
+ List getCurrentlyExecutingJobs() throws SchedulerException;
/**
- *
* Set the JobFactory that will be responsible for producing
* instances of Job classes.
- *
*
*
* JobFactories may be of use to those wishing to have their application
* produce Job instances via some special mechanism, such as to
- * give the opertunity for dependency injection.
+ * give the opportunity for dependency injection.
*
*
- * @see org.quart.spi.JobFactory
- * @throws SchedulerException
+ * @see org.quartz.spi.JobFactory
*/
- public void setJobFactory(JobFactory factory) throws SchedulerException;
+ void setJobFactory(JobFactory factory) throws SchedulerException;
+
+ /**
+ * Get a reference to the scheduler's ListenerManager,
+ * through which listeners may be registered.
+ *
+ * @return the scheduler's ListenerManager
+ * @throws SchedulerException if the scheduler is not local
+ * @see ListenerManager
+ * @see JobListener
+ * @see TriggerListener
+ * @see SchedulerListener
+ */
+ ListenerManager getListenerManager() throws SchedulerException;
+
///////////////////////////////////////////////////////////////////////////
///
/// Scheduling-related Methods
///
///////////////////////////////////////////////////////////////////////////
/**
- *
* Add the given {@link org.quartz.JobDetail} to the
* Scheduler, and associate the given {@link Trigger} with
* it.
- *
*
*
* If the given Trigger does not reference any Job, then it
@@ -361,272 +415,327 @@
* if the Job or Trigger cannot be added to the Scheduler, or
* there is an internal Scheduler error.
*/
- public Date scheduleJob(JobDetail jobDetail, Trigger trigger)
- throws SchedulerException;
+ Date scheduleJob(JobDetail jobDetail, Trigger trigger)
+ throws SchedulerException;
/**
- *
* Schedule the given {@link org.quartz.Trigger} with the
* Job identified by the Trigger's settings.
- *
*
* @throws SchedulerException
* if the indicated Job does not exist, or the Trigger cannot be
* added to the Scheduler, or there is an internal Scheduler
* error.
*/
- public Date scheduleJob(Trigger trigger) throws SchedulerException;
+ Date scheduleJob(Trigger trigger) throws SchedulerException;
/**
- *
+ * Schedule all of the given jobs with the related set of triggers.
+ *
+ *
If any of the given jobs or triggers already exist (or more
+ * specifically, if the keys are not unique) and the replace
+ * parameter is not set to true then an exception will be thrown.
+ *
+ * @throws ObjectAlreadyExistsException if the job/trigger keys
+ * are not unique and the replace flag is not set to true.
+ */
+ void scheduleJobs(Map> triggersAndJobs, boolean replace) throws SchedulerException;
+
+ /**
+ * Schedule the given job with the related set of triggers.
+ *
+ * If any of the given job or triggers already exist (or more
+ * specifically, if the keys are not unique) and the replace
+ * parameter is not set to true then an exception will be thrown.
+ *
+ * @throws ObjectAlreadyExistsException if the job/trigger keys
+ * are not unique and the replace flag is not set to true.
+ */
+ void scheduleJob(JobDetail jobDetail, Set extends Trigger> triggersForJob, boolean replace) throws SchedulerException;
+
+ /**
* Remove the indicated {@link Trigger} from the scheduler.
- *
+ *
+ * If the related job does not have any other triggers, and the job is
+ * not durable, then the job will also be deleted.
*/
- public boolean unscheduleJob(String triggerName, String groupName)
- throws SchedulerException;
+ boolean unscheduleJob(TriggerKey triggerKey)
+ throws SchedulerException;
/**
- *
+ * Remove all of the indicated {@link Trigger}s from the scheduler.
+ *
+ *
If the related job does not have any other triggers, and the job is
+ * not durable, then the job will also be deleted.
+ *
+ * Note that while this bulk operation is likely more efficient than
+ * invoking unscheduleJob(TriggerKey triggerKey) several
+ * times, it may have the adverse affect of holding data locks for a
+ * single long duration of time (rather than lots of small durations
+ * of time).
+ */
+ boolean unscheduleJobs(List triggerKeys)
+ throws SchedulerException;
+
+ /**
* Remove (delete) the {@link org.quartz.Trigger} with the
- * given name, and store the new given one - which must be associated
+ * given key, and store the new given one - which must be associated
* with the same job (the new trigger must have the job name & group specified)
* - however, the new trigger need not have the same name as the old trigger.
- *
*
- * @param triggerName
- * The name of the Trigger to be replaced.
- * @param groupName
- * The group name of the Trigger to be replaced.
+ * @param triggerKey identity of the trigger to replace
* @param newTrigger
* The new Trigger to be stored.
+ *
* @return null if a Trigger with the given
- * name & group was not found and removed from the store, otherwise
- * the first fire time of the newly scheduled trigger.
+ * name & group was not found and removed from the store (and the
+ * new trigger is therefore not stored), otherwise
+ * the first fire time of the newly scheduled trigger is returned.
*/
- public Date rescheduleJob(String triggerName,
- String groupName, Trigger newTrigger) throws SchedulerException;
-
+ Date rescheduleJob(TriggerKey triggerKey, Trigger newTrigger)
+ throws SchedulerException;
/**
- *
* Add the given Job to the Scheduler - with no associated
* Trigger. The Job will be 'dormant' until
* it is scheduled with a Trigger, or Scheduler.triggerJob()
* is called for it.
- *
*
*
* The Job must by definition be 'durable', if it is not,
* SchedulerException will be thrown.
*
- *
+ *
+ * @see #addJob(JobDetail, boolean, boolean)
+ *
* @throws SchedulerException
* if there is an internal Scheduler error, or if the Job is not
* durable, or a Job with the same name already exists, and
* replace is false.
*/
- public void addJob(JobDetail jobDetail, boolean replace)
- throws SchedulerException;
+ void addJob(JobDetail jobDetail, boolean replace)
+ throws SchedulerException;
/**
+ * Add the given Job to the Scheduler - with no associated
+ * Trigger. The Job will be 'dormant' until
+ * it is scheduled with a Trigger, or Scheduler.triggerJob()
+ * is called for it.
+ *
*
+ * With the storeNonDurableWhileAwaitingScheduling parameter
+ * set to true, a non-durable job can be stored. Once it is
+ * scheduled, it will resume normal non-durable behavior (i.e. be deleted
+ * once there are no remaining associated triggers).
+ *
+ *
+ * @throws SchedulerException
+ * if there is an internal Scheduler error, or if the Job is not
+ * durable, or a Job with the same name already exists, and
+ * replace is false.
+ */
+ void addJob(JobDetail jobDetail, boolean replace, boolean storeNonDurableWhileAwaitingScheduling)
+ throws SchedulerException;
+
+ /**
* Delete the identified Job from the Scheduler - and any
* associated Triggers.
- *
*
* @return true if the Job was found and deleted.
* @throws SchedulerException
* if there is an internal Scheduler error.
*/
- public boolean deleteJob(String jobName, String groupName)
- throws SchedulerException;
+ boolean deleteJob(JobKey jobKey)
+ throws SchedulerException;
/**
- *
- * Trigger the identified {@link org.quartz.JobDetail}
- * (execute it now) - the generated trigger will be non-volatile.
- *
+ * Delete the identified Jobs from the Scheduler - and any
+ * associated Triggers.
+ *
+ * Note that while this bulk operation is likely more efficient than
+ * invoking deleteJob(JobKey jobKey) several
+ * times, it may have the adverse affect of holding data locks for a
+ * single long duration of time (rather than lots of small durations
+ * of time).
+ *
+ * @return true if all of the Jobs were found and deleted, false if
+ * one or more were not deleted.
+ * @throws SchedulerException
+ * if there is an internal Scheduler error.
*/
- public void triggerJob(String jobName, String groupName)
- throws SchedulerException;
-
+ boolean deleteJobs(List jobKeys)
+ throws SchedulerException;
+
/**
- *
* Trigger the identified {@link org.quartz.JobDetail}
- * (execute it now) - the generated trigger will be volatile.
- *
+ * (execute it now).
*/
- public void triggerJobWithVolatileTrigger(String jobName, String groupName)
- throws SchedulerException;
+ void triggerJob(JobKey jobKey)
+ throws SchedulerException;
/**
- *
* Trigger the identified {@link org.quartz.JobDetail}
- * (execute it now) - the generated trigger will be non-volatile.
- *
+ * (execute it now).
*
- * @param jobName the name of the Job to trigger
- * @param groupName the group name of the Job to trigger
* @param data the (possibly null) JobDataMap to be
* associated with the trigger that fires the job immediately.
*/
- public void triggerJob(String jobName, String groupName, JobDataMap data)
- throws SchedulerException;
+ void triggerJob(JobKey jobKey, JobDataMap data)
+ throws SchedulerException;
/**
- *
- * Trigger the identified {@link org.quartz.JobDetail}
- * (execute it now) - the generated trigger will be volatile.
- *
- *
- * @param jobName the name of the Job to trigger
- * @param groupName the group name of the Job to trigger
- * @param data the (possibly null) JobDataMap to be
- * associated with the trigger that fires the job immediately.
- */
- public void triggerJobWithVolatileTrigger(String jobName, String groupName, JobDataMap data)
- throws SchedulerException;
-
- /**
- *
* Pause the {@link org.quartz.JobDetail} with the given
- * name - by pausing all of its current Triggers.
- *
+ * key - by pausing all of its current Triggers.
*
- * @see #resumeJob(String, String)
+ * @see #resumeJob(JobKey)
*/
- public void pauseJob(String jobName, String groupName)
- throws SchedulerException;
+ void pauseJob(JobKey jobKey)
+ throws SchedulerException;
/**
- *
* Pause all of the {@link org.quartz.JobDetail}s in the
- * given group - by pausing all of their Triggers.
- *
- *
+ * matching groups - by pausing all of their Triggers.
+ *
*
- * The Scheduler will "remember" that the group is paused, and impose the
- * pause on any new jobs that are added to the group while the group is
- * paused.
+ * The Scheduler will "remember" the groups paused, and impose the
+ * pause on any new jobs that are added to any of those groups
+ * until it is resumed.
*
*
- * @see #resumeJobGroup(String)
+ * NOTE: There is a limitation that only exactly matched groups
+ * can be remembered as paused. For example, if there are pre-existing
+ * job in groups "aaa" and "bbb" and a matcher is given to pause
+ * groups that start with "a" then the group "aaa" will be remembered
+ * as paused and any subsequently added jobs in group "aaa" will be paused,
+ * however if a job is added to group "axx" it will not be paused,
+ * as "axx" wasn't known at the time the "group starts with a" matcher
+ * was applied. HOWEVER, if there are pre-existing groups "aaa" and
+ * "bbb" and a matcher is given to pause the group "axx" (with a
+ * group equals matcher) then no jobs will be paused, but it will be
+ * remembered that group "axx" is paused and later when a job is added
+ * in that group, it will become paused.
+ *
+ * @param matcher The matcher to evaluate against know groups
+ * @throws SchedulerException On error
+ * @see #resumeJobs(org.quartz.impl.matchers.GroupMatcher)
*/
- public void pauseJobGroup(String groupName) throws SchedulerException;
+ void pauseJobs(GroupMatcher matcher) throws SchedulerException;
/**
- *
- * Pause the {@link Trigger} with the given name.
- *
+ * Pause the {@link Trigger} with the given key.
*
- * @see #resumeTrigger(String, String)
+ * @see #resumeTrigger(TriggerKey)
*/
- public void pauseTrigger(String triggerName, String groupName)
- throws SchedulerException;
+ void pauseTrigger(TriggerKey triggerKey)
+ throws SchedulerException;
/**
- *
- * Pause all of the {@link Trigger}s in the given group.
- *
+ * Pause all of the {@link Trigger}s in the groups matching.
*
*
- * The Scheduler will "remember" that the group is paused, and impose the
- * pause on any new triggers that are added to the group while the group is
- * paused.
+ * The Scheduler will "remember" all the groups paused, and impose the
+ * pause on any new triggers that are added to any of those groups
+ * until it is resumed.
*
*
- * @see #resumeTriggerGroup(String)
+ * NOTE: There is a limitation that only exactly matched groups
+ * can be remembered as paused. For example, if there are pre-existing
+ * triggers in groups "aaa" and "bbb" and a matcher is given to pause
+ * groups that start with "a" then the group "aaa" will be remembered as
+ * paused and any subsequently added triggers in that group be paused,
+ * however if a trigger is added to group "axx" it will not be paused,
+ * as "axx" wasn't known at the time the "group starts with a" matcher
+ * was applied. HOWEVER, if there are pre-existing groups "aaa" and
+ * "bbb" and a matcher is given to pause the group "axx" (with a
+ * group equals matcher) then no triggers will be paused, but it will be
+ * remembered that group "axx" is paused and later when a trigger is added
+ * in that group, it will become paused.
+ *
+ * @param matcher The matcher to evaluate against know groups
+ * @throws SchedulerException
+ * @see #resumeTriggers(org.quartz.impl.matchers.GroupMatcher)
*/
- public void pauseTriggerGroup(String groupName) throws SchedulerException;
+ void pauseTriggers(GroupMatcher matcher) throws SchedulerException;
/**
- *
* Resume (un-pause) the {@link org.quartz.JobDetail} with
- * the given name.
- *
+ * the given key.
*
*
* If any of the Job'sTrigger s missed one
* or more fire-times, then the Trigger's misfire
* instruction will be applied.
*
*
- * @see #pauseJob(String, String)
+ * @see #pauseJob(JobKey)
*/
- public void resumeJob(String jobName, String groupName)
- throws SchedulerException;
+ void resumeJob(JobKey jobKey)
+ throws SchedulerException;
/**
- *
* Resume (un-pause) all of the {@link org.quartz.JobDetail}s
- * in the given group.
- *
+ * in matching groups.
*
*
* If any of the Job s had Trigger s that
* missed one or more fire-times, then the Trigger's
* misfire instruction will be applied.
*
*
- * @see #pauseJobGroup(String)
+ * @param matcher The matcher to evaluate against known paused groups
+ * @throws SchedulerException On error
+ * @see #pauseJobs(GroupMatcher)
*/
- public void resumeJobGroup(String groupName) throws SchedulerException;
+ void resumeJobs(GroupMatcher matcher) throws SchedulerException;
/**
- *
* Resume (un-pause) the {@link Trigger} with the given
- * name.
- *
+ * key.
*
*
* If the Trigger missed one or more fire-times, then the
* Trigger's misfire instruction will be applied.
*
*
- * @see #pauseTrigger(String, String)
+ * @see #pauseTrigger(TriggerKey)
*/
- public void resumeTrigger(String triggerName, String groupName)
- throws SchedulerException;
+ void resumeTrigger(TriggerKey triggerKey)
+ throws SchedulerException;
/**
- *
- * Resume (un-pause) all of the {@link Trigger}s in the
- * given group.
- *
+ * Resume (un-pause) all of the {@link Trigger}s in matching groups.
*
*
* If any Trigger missed one or more fire-times, then the
* Trigger's misfire instruction will be applied.
*
*
- * @see #pauseTriggerGroup(String)
+ * @param matcher The matcher to evaluate against know paused groups
+ * @throws SchedulerException On error
+ * @see #pauseTriggers(org.quartz.impl.matchers.GroupMatcher)
*/
- public void resumeTriggerGroup(String groupName) throws SchedulerException;
+ void resumeTriggers(GroupMatcher matcher) throws SchedulerException;
/**
- *
* Pause all triggers - similar to calling pauseTriggerGroup(group)
* on every group, however, after using this method resumeAll()
* must be called to clear the scheduler's state of 'remembering' that all
* new triggers will be paused as they are added.
- *
*
*
* When resumeAll() is called (to un-pause), trigger misfire
* instructions WILL be applied.
*
*
* @see #resumeAll()
- * @see #pauseTriggerGroup(String)
+ * @see #pauseTriggers(org.quartz.impl.matchers.GroupMatcher)
* @see #standby()
*/
- public void pauseAll() throws SchedulerException;
+ void pauseAll() throws SchedulerException;
/**
- *
* Resume (un-pause) all triggers - similar to calling
* resumeTriggerGroup(group) on every group.
- *
*
*
* If any Trigger missed one or more fire-times, then the
@@ -635,95 +744,89 @@
*
* @see #pauseAll()
*/
- public void resumeAll() throws SchedulerException;
+ void resumeAll() throws SchedulerException;
/**
- *
* Get the names of all known {@link org.quartz.JobDetail}
* groups.
- *
*/
- public String[] getJobGroupNames() throws SchedulerException;
+ List getJobGroupNames() throws SchedulerException;
/**
- *
- * Get the names of all the {@link org.quartz.JobDetail}s
- * in the given group.
- *
+ * Get the keys of all the {@link org.quartz.JobDetail}s
+ * in the matching groups.
+ * @param matcher Matcher to evaluate against known groups
+ * @return Set of all keys matching
+ * @throws SchedulerException On error
*/
- public String[] getJobNames(String groupName) throws SchedulerException;
+ Set getJobKeys(GroupMatcher matcher) throws SchedulerException;
/**
- *
* Get all {@link Trigger} s that are associated with the
* identified {@link org.quartz.JobDetail}.
+ *
+ *
The returned Trigger objects will be snap-shots of the actual stored
+ * triggers. If you wish to modify a trigger, you must re-store the
+ * trigger afterward (e.g. see {@link #rescheduleJob(TriggerKey, Trigger)}).
*
+ *
*/
- public Trigger[] getTriggersOfJob(String jobName, String groupName)
- throws SchedulerException;
+ List extends Trigger> getTriggersOfJob(JobKey jobKey)
+ throws SchedulerException;
/**
- *
* Get the names of all known {@link Trigger} groups.
- *
*/
- public String[] getTriggerGroupNames() throws SchedulerException;
+ List getTriggerGroupNames() throws SchedulerException;
/**
- *
* Get the names of all the {@link Trigger}s in the given
* group.
- *
+ * @param matcher Matcher to evaluate against known groups
+ * @return List of all keys matching
+ * @throws SchedulerException On error
*/
- public String[] getTriggerNames(String groupName) throws SchedulerException;
+ Set getTriggerKeys(GroupMatcher matcher) throws SchedulerException;
/**
- *
* Get the names of all {@link Trigger} groups that are paused.
- *
- *
- * @return
- * @throws SchedulerException
*/
- public Set getPausedTriggerGroups() throws SchedulerException;
+ Set getPausedTriggerGroups() throws SchedulerException;
/**
- *
* Get the {@link JobDetail} for the Job
- * instance with the given name and group.
+ * instance with the given key.
+ *
+ *
The returned JobDetail object will be a snap-shot of the actual stored
+ * JobDetail. If you wish to modify the JobDetail, you must re-store the
+ * JobDetail afterward (e.g. see {@link #addJob(JobDetail, boolean)}).
*
+ *
*/
- public JobDetail getJobDetail(String jobName, String jobGroup)
- throws SchedulerException;
+ JobDetail getJobDetail(JobKey jobKey)
+ throws SchedulerException;
/**
- *
- * Get the {@link Trigger} instance with the given name and
- * group.
+ * Get the {@link Trigger} instance with the given key.
+ *
+ *
The returned Trigger object will be a snap-shot of the actual stored
+ * trigger. If you wish to modify the trigger, you must re-store the
+ * trigger afterward (e.g. see {@link #rescheduleJob(TriggerKey, Trigger)}).
*
*/
- public Trigger getTrigger(String triggerName, String triggerGroup)
- throws SchedulerException;
+ Trigger getTrigger(TriggerKey triggerKey)
+ throws SchedulerException;
/**
- *
* Get the current state of the identified {@link Trigger}.
- *
*
- * @see Trigger#STATE_NORMAL
- * @see Trigger#STATE_PAUSED
- * @see Trigger#STATE_COMPLETE
- * @see Trigger#STATE_ERROR
- * @see Trigger#STATE_BLOCKED
- * @see Trigger#STATE_NONE
+ * @see Trigger.TriggerState
*/
- public int getTriggerState(String triggerName, String triggerGroup)
- throws SchedulerException;
+ TriggerState getTriggerState(TriggerKey triggerKey)
+ throws SchedulerException;
/**
- *
* Add (register) the given Calendar to the Scheduler.
- *
*
* @param updateTriggers whether or not to update existing triggers that
* referenced the already existing calendar so that they are 'correct'
@@ -735,40 +838,39 @@
* the same name already exists, and replace is
* false.
*/
- public void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers)
- throws SchedulerException;
+ void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers)
+ throws SchedulerException;
/**
- *
* Delete the identified Calendar from the Scheduler.
+ *
+ *
+ * If removal of the Calendar would result in
+ * Triggers pointing to non-existent calendars, then a
+ * SchedulerException will be thrown.
*
*
* @return true if the Calendar was found and deleted.
* @throws SchedulerException
- * if there is an internal Scheduler error.
+ * if there is an internal Scheduler error, or one or more
+ * triggers reference the calendar
*/
- public boolean deleteCalendar(String calName) throws SchedulerException;
+ boolean deleteCalendar(String calName) throws SchedulerException;
/**
- *
* Get the {@link Calendar} instance with the given name.
- *
*/
- public Calendar getCalendar(String calName) throws SchedulerException;
+ Calendar getCalendar(String calName) throws SchedulerException;
/**
- *
* Get the names of all registered {@link Calendar}s.
- *
*/
- public String[] getCalendarNames() throws SchedulerException;
+ List getCalendarNames() throws SchedulerException;
/**
- *
- * Request the interruption of all currently executing instances of the
- * identified Job, which must be an implementor of the
- * InterruptableJob interface.
- *
+ * Request the interruption, within this Scheduler instance, of all
+ * currently executing instances of the identified Job, which
+ * must be an implementor of the InterruptableJob interface.
*
*
* If more than one instance of the identified job is currently executing,
@@ -780,198 +882,73 @@
*
*
*
- * If you wish to interrupt a specific instance of a job (when more than
- * one is executing) you can do so by calling
- * {@link #getCurrentlyExecutingJobs()} to obtain a handle
- * to the job instance, and then invoke interrupt() on it
- * yourself.
+ * This method is not cluster aware. That is, it will only interrupt
+ * instances of the identified InterruptableJob currently executing in this
+ * Scheduler instance, not across the entire cluster.
*
*
- * @param jobName
- * @param groupName
- * @return true is at least one instance of the identified job was found
+ * @return true if at least one instance of the identified job was found
* and interrupted.
* @throws UnableToInterruptJobException if the job does not implement
* InterruptableJob, or there is an exception while
* interrupting the job.
* @see InterruptableJob#interrupt()
* @see #getCurrentlyExecutingJobs()
+ * @see #interrupt(String)
*/
- public boolean interrupt(String jobName, String groupName) throws UnableToInterruptJobException;
+ boolean interrupt(JobKey jobKey) throws UnableToInterruptJobException;
- ///////////////////////////////////////////////////////////////////////////
- ///
- /// Listener-related Methods
- ///
- ///////////////////////////////////////////////////////////////////////////
-
/**
- *
- * Add the given {@link JobListener} to the Scheduler's
- * global list.
- *
+ * Request the interruption, within this Scheduler instance, of the
+ * identified executing Job instance, which
+ * must be an implementor of the InterruptableJob interface.
*
*
- * Listeners in the 'global' list receive notification of execution events
- * for ALL {@link org.quartz.JobDetail}s.
+ * This method is not cluster aware. That is, it will only interrupt
+ * instances of the identified InterruptableJob currently executing in this
+ * Scheduler instance, not across the entire cluster.
*
- */
- public void addGlobalJobListener(JobListener jobListener)
- throws SchedulerException;
-
- /**
- *
- * Add the given {@link JobListener} to the Scheduler's
- * list, of registered JobListeners.
- */
- public void addJobListener(JobListener jobListener)
- throws SchedulerException;
-
- /**
- *
- * Remove the given {@link JobListener} from the Scheduler's
- * list of global listeners.
- *
*
- * @return true if the identifed listener was found in the list, and
- * removed.
+ * @param fireInstanceId the unique identifier of the job instance to
+ * be interrupted (see {@link JobExecutionContext#getFireInstanceId()}
+ * @return true if the identified job instance was found and interrupted.
+ * @throws UnableToInterruptJobException if the job does not implement
+ * InterruptableJob, or there is an exception while
+ * interrupting the job.
+ * @see InterruptableJob#interrupt()
+ * @see #getCurrentlyExecutingJobs()
+ * @see JobExecutionContext#getFireInstanceId()
+ * @see #interrupt(JobKey)
*/
- public boolean removeGlobalJobListener(JobListener jobListener)
- throws SchedulerException;
-
+ boolean interrupt(String fireInstanceId) throws UnableToInterruptJobException;
+
/**
- *
- * Remove the identifed {@link JobListener} from the Scheduler's
- * list of registered listeners.
- *
+ * Determine whether a {@link Job} with the given identifier already
+ * exists within the scheduler.
*
- * @return true if the identifed listener was found in the list, and
- * removed.
+ * @param jobKey the identifier to check for
+ * @return true if a Job exists with the given identifier
+ * @throws SchedulerException
*/
- public boolean removeJobListener(String name) throws SchedulerException;
-
+ boolean checkExists(JobKey jobKey) throws SchedulerException;
+
/**
- *
- * Get a List containing all of the {@link JobListener} s in
- * the Scheduler'sglobal list.
- *
- */
- public List getGlobalJobListeners() throws SchedulerException;
-
- /**
- *
- * Get a Set containing the names of all the non-global{@link JobListener}
- * s registered with the Scheduler.
- *
- */
- public Set getJobListenerNames() throws SchedulerException;
-
- /**
- *
- * Get the non-global{@link JobListener} that has
- * the given name.
- *
- */
- public JobListener getJobListener(String name) throws SchedulerException;
-
- /**
- *
- * Add the given {@link TriggerListener} to the Scheduler's
- * global list.
- *
+ * Determine whether a {@link Trigger} with the given identifier already
+ * exists within the scheduler.
*
- *
- * Listeners in the 'global' list receive notification of execution events
- * for ALL {@link Trigger}s.
- *
+ * @param triggerKey the identifier to check for
+ * @return true if a Trigger exists with the given identifier
+ * @throws SchedulerException
*/
- public void addGlobalTriggerListener(TriggerListener triggerListener)
- throws SchedulerException;
-
+ boolean checkExists(TriggerKey triggerKey) throws SchedulerException;
+
/**
- *
- * Add the given {@link TriggerListener} to the Scheduler's
- * list, of registered TriggerListeners.
- */
- public void addTriggerListener(TriggerListener triggerListener)
- throws SchedulerException;
-
- /**
- *
- * Remove the given {@link TriggerListener} from the Scheduler's
- * list of global listeners.
- *
+ * Clears (deletes!) all scheduling data - all {@link Job}s, {@link Trigger}s
+ * {@link Calendar}s.
*
- * @return true if the identifed listener was found in the list, and
- * removed.
+ * @throws SchedulerException
*/
- public boolean removeGlobalTriggerListener(TriggerListener triggerListener)
- throws SchedulerException;
+ void clear() throws SchedulerException;
- /**
- *
- * Remove the identifed {@link TriggerListener} from the
- * Scheduler's list of registered listeners.
- *
- *
- * @return true if the identifed listener was found in the list, and
- * removed.
- */
- public boolean removeTriggerListener(String name) throws SchedulerException;
- /**
- *
- * Get a List containing all of the {@link TriggerListener}
- * s in the Scheduler'sglobal list.
- *
- */
- public List getGlobalTriggerListeners() throws SchedulerException;
-
- /**
- *
- * Get a Set containing the names of all the non-global{@link TriggerListener}
- * s registered with the Scheduler.
- *
- */
- public Set getTriggerListenerNames() throws SchedulerException;
-
- /**
- *
- * Get the non-global{@link TriggerListener} that
- * has the given name.
- *
- */
- public TriggerListener getTriggerListener(String name)
- throws SchedulerException;
-
- /**
- *
- * Register the given {@link SchedulerListener} with the
- * Scheduler.
- *
- */
- public void addSchedulerListener(SchedulerListener schedulerListener)
- throws SchedulerException;
-
- /**
- *
- * Remove the given {@link SchedulerListener} from the
- * Scheduler.
- *
- *
- * @return true if the identifed listener was found in the list, and
- * removed.
- */
- public boolean removeSchedulerListener(SchedulerListener schedulerListener)
- throws SchedulerException;
-
- /**
- *
- * Get a List containing all of the {@link SchedulerListener}
- * s registered with the Scheduler.
- *
- */
- public List getSchedulerListeners() throws SchedulerException;
-
-
}
Index: 3rdParty_sources/quartz/org/quartz/SchedulerConfigException.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SchedulerConfigException.java (.../SchedulerConfigException.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SchedulerConfigException.java (.../SchedulerConfigException.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,21 +16,18 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* An exception that is thrown to indicate that there is a misconfiguration of
* the SchedulerFactory- or one of the components it
* configures.
- *
*
* @author James House
*/
public class SchedulerConfigException extends SchedulerException {
+
+ private static final long serialVersionUID = -5921239824646083098L;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -46,7 +43,7 @@
*
*/
public SchedulerConfigException(String msg) {
- super(msg, ERR_BAD_CONFIGURATION);
+ super(msg);
}
/**
@@ -55,9 +52,8 @@
* and cause.
*
*/
- public SchedulerConfigException(String msg, Exception cause) {
+ public SchedulerConfigException(String msg, Throwable cause) {
super(msg, cause);
- setErrorCode(ERR_BAD_CONFIGURATION);
}
}
Index: 3rdParty_sources/quartz/org/quartz/SchedulerContext.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SchedulerContext.java (.../SchedulerContext.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SchedulerContext.java (.../SchedulerContext.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,361 +16,46 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
import java.io.Serializable;
-import java.util.Iterator;
import java.util.Map;
-import org.quartz.utils.DirtyFlagMap;
+import org.quartz.utils.StringKeyDirtyFlagMap;
/**
- *
* Holds context/environment data that can be made available to Jobs as they
* are executed. This feature is much like the ServletContext feature when
* working with J2EE servlets.
- *
*
+ *
+ * Future versions of Quartz may make distinctions on how it propagates
+ * data in SchedulerContext between instances of proxies to a
+ * single scheduler instance - i.e. if Quartz is being used via RMI.
+ *
+ *
* @see Scheduler#getContext
*
* @author James House
*/
-public class SchedulerContext extends DirtyFlagMap implements Serializable {
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- private boolean allowsTransientData = false;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
+public class SchedulerContext extends StringKeyDirtyFlagMap implements Serializable {
+
+ private static final long serialVersionUID = -6659641334616491764L;
+
/**
- *
- * Create an empty JobDataMap.
- *
+ * Create an empty SchedulerContext.
*/
public SchedulerContext() {
super(15);
}
/**
- *
- * Create a JobDataMap with the given data.
- *
+ * Create a SchedulerContext with the given data.
*/
- public SchedulerContext(Map map) {
+ public SchedulerContext(Map, ?> map) {
this();
-
- putAll(map);
+ @SuppressWarnings("unchecked") // param must be a String key map.
+ Map mapTyped = (Map)map;
+ putAll(mapTyped);
}
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- *
- * Tell the SchedulerContext that it should allow non-
- * Serializable data.
- *
- *
- *
- * Future versions of Quartz may make distinctions on how it propogates
- * data in the SchedulerContext between instances of proxies to a single
- * scheduler instance - i.e. if Quartz is being used via RMI.
- *
- */
- public void setAllowsTransientData(boolean allowsTransientData) {
-
- if (containsTransientData() && !allowsTransientData)
- throw new IllegalStateException(
- "Cannot set property 'allowsTransientData' to 'false' "
- + "when data map contains non-serializable objects.");
-
- this.allowsTransientData = allowsTransientData;
- }
-
- public boolean getAllowsTransientData() {
- return allowsTransientData;
- }
-
- public boolean containsTransientData() {
-
- if (!getAllowsTransientData()) // short circuit...
- return false;
-
- String[] keys = getKeys();
-
- for (int i = 0; i < keys.length; i++) {
- Object o = super.get(keys[i]);
- if (!(o instanceof Serializable)) return true;
- }
-
- return false;
- }
-
- /**
- *
- * Nulls-out any data values that are non-Serializable.
- *
- */
- public void removeTransientData() {
-
- if (!getAllowsTransientData()) // short circuit...
- return;
-
- String[] keys = getKeys();
-
- for (int i = 0; i < keys.length; i++) {
- Object o = super.get(keys[i]);
- if (!(o instanceof Serializable)) remove(keys[i]);
- }
-
- }
-
- /**
- *
- * Adds the name-value pairs in the given Map to the SchedulerContext.
- *
- *
- *
- * All keys must be Strings.
- *
- */
- public void putAll(Map map) {
- Iterator itr = map.keySet().iterator();
- while (itr.hasNext()) {
- Object key = itr.next();
- Object val = map.get(key);
-
- put(key, val);
- // will throw IllegalArgumentException if value not serilizable
- }
- }
-
- /**
- *
- * Adds the given int value to the SchedulerContext.
- *
- */
- public void put(String key, int value) {
- super.put(key, new Integer(value));
- }
-
- /**
- *
- * Adds the given long value to the SchedulerContext.
- *
- */
- public void put(String key, long value) {
- super.put(key, new Long(value));
- }
-
- /**
- *
- * Adds the given float value to the SchedulerContext.
- *
- */
- public void put(String key, float value) {
- super.put(key, new Float(value));
- }
-
- /**
- *
- * Adds the given double value to the SchedulerContext.
- *
- */
- public void put(String key, double value) {
- super.put(key, new Double(value));
- }
-
- /**
- *
- * Adds the given boolean value to the SchedulerContext.
- *
- */
- public void put(String key, boolean value) {
- super.put(key, new Boolean(value));
- }
-
- /**
- *
- * Adds the given char value to the SchedulerContext.
- *
- */
- public void put(String key, char value) {
- super.put(key, new Character(value));
- }
-
- /**
- *
- * Adds the given String value to the SchedulerContext.
- *
- */
- public void put(String key, String value) {
- super.put(key, value);
- }
-
- /**
- *
- * Adds the given Object value to the SchedulerContext.
- *
- */
- public Object put(Object key, Object value) {
- if (!(key instanceof String))
- throw new IllegalArgumentException(
- "Keys in map must be Strings.");
-
- return super.put(key, value);
- }
-
- /**
- *
- * Retrieve the identified int value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not an Integer.
- */
- public int getInt(String key) {
- Object obj = get(key);
-
- try {
- return ((Integer) obj).intValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not an Integer.");
- }
- }
-
- /**
- *
- * Retrieve the identified long value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Long.
- */
- public long getLong(String key) {
- Object obj = get(key);
-
- try {
- return ((Long) obj).longValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Long.");
- }
- }
-
- /**
- *
- * Retrieve the identified float value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Float.
- */
- public float getFloat(String key) {
- Object obj = get(key);
-
- try {
- return ((Float) obj).floatValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Float.");
- }
- }
-
- /**
- *
- * Retrieve the identified double value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Double.
- */
- public double getDouble(String key) {
- Object obj = get(key);
-
- try {
- return ((Double) obj).doubleValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Double.");
- }
- }
-
- /**
- *
- * Retrieve the identified boolean value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Boolean.
- */
- public boolean getBoolean(String key) {
- Object obj = get(key);
-
- try {
- return ((Boolean) obj).booleanValue();
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a Boolean.");
- }
- }
-
- /**
- *
- * Retrieve the identified char value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a Character.
- */
- public char getChar(String key) {
- Object obj = get(key);
-
- try {
- return ((Character) obj).charValue();
- } catch (Exception e) {
- throw new ClassCastException(
- "Identified object is not a Character.");
- }
- }
-
- /**
- *
- * Retrieve the identified String value from the SchedulerContext.
- *
- *
- * @throws ClassCastException
- * if the identified object is not a String.
- */
- public String getString(String key) {
- Object obj = get(key);
-
- try {
- return (String) obj;
- } catch (Exception e) {
- throw new ClassCastException("Identified object is not a String.");
- }
- }
-
- public String[] getKeys() {
- return (String[]) keySet().toArray(new String[size()]);
- }
-
}
Index: 3rdParty_sources/quartz/org/quartz/SchedulerException.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SchedulerException.java (.../SchedulerException.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SchedulerException.java (.../SchedulerException.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,91 +16,27 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
-import java.io.PrintStream;
-import java.io.PrintWriter;
+
/**
- *
* Base class for exceptions thrown by the Quartz {@link Scheduler}.
- *
*
*
- * SchedulerException s may contain a reference to another
+ * SchedulerExceptions may contain a reference to another
* Exception, which was the underlying cause of the SchedulerException.
*
*
* @author James House
*/
public class SchedulerException extends Exception {
+
+ private static final long serialVersionUID = 174841398690789156L;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
- * Constants.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public static final int ERR_UNSPECIFIED = 0;
-
- public static final int ERR_BAD_CONFIGURATION = 50;
-
- public static final int ERR_TIME_BROKER_FAILURE = 70;
-
- public static final int ERR_CLIENT_ERROR = 100;
-
- public static final int ERR_COMMUNICATION_FAILURE = 200;
-
- public static final int ERR_UNSUPPORTED_FUNCTION_IN_THIS_CONFIGURATION = 210;
-
- public static final int ERR_PERSISTENCE = 400;
-
- public static final int ERR_PERSISTENCE_JOB_DOES_NOT_EXIST = 410;
-
- public static final int ERR_PERSISTENCE_CALENDAR_DOES_NOT_EXIST = 420;
-
- public static final int ERR_PERSISTENCE_TRIGGER_DOES_NOT_EXIST = 430;
-
- public static final int ERR_PERSISTENCE_CRITICAL_FAILURE = 499;
-
- public static final int ERR_THREAD_POOL = 500;
-
- public static final int ERR_THREAD_POOL_EXHAUSTED = 510;
-
- public static final int ERR_THREAD_POOL_CRITICAL_FAILURE = 599;
-
- public static final int ERR_JOB_LISTENER = 600;
-
- public static final int ERR_JOB_LISTENER_NOT_FOUND = 610;
-
- public static final int ERR_TRIGGER_LISTENER = 700;
-
- public static final int ERR_TRIGGER_LISTENER_NOT_FOUND = 710;
-
- public static final int ERR_JOB_EXECUTION_THREW_EXCEPTION = 800;
-
- public static final int ERR_TRIGGER_THREW_EXCEPTION = 850;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- private Exception cause;
-
- private int errorCode = ERR_UNSPECIFIED;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
* Constructors.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -114,27 +50,16 @@
super(msg);
}
- public SchedulerException(String msg, int errorCode) {
- super(msg);
- setErrorCode(errorCode);
+ public SchedulerException(Throwable cause) {
+ super(cause);
}
- public SchedulerException(Exception cause) {
- super(cause.toString());
- this.cause = cause;
+ public SchedulerException(String msg, Throwable cause) {
+ super(msg, cause);
}
- public SchedulerException(String msg, Exception cause) {
- super(msg);
- this.cause = cause;
- }
- public SchedulerException(String msg, Exception cause, int errorCode) {
- super(msg);
- this.cause = cause;
- setErrorCode(errorCode);
- }
-
+
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -156,167 +81,18 @@
* one.
*/
public Throwable getUnderlyingException() {
- return cause;
+ return super.getCause();
}
- /**
- *
- * Get the error code associated with this exception.
- *
- *
- *
- * This may be used to find more detail about the cause of the error.
- *
- *
- * @return one of the ERR_XXX constants defined in this class.
- */
- public int getErrorCode() {
- return errorCode;
- }
-
- /**
- *
- * Get the error code associated with this exception.
- *
- *
- *
- * This may be used to provide more detail about the cause of the error.
- *
- *
- * @param errorCode
- * one of the ERR_XXX constants defined in this class.
- */
- public void setErrorCode(int errorCode) {
- this.errorCode = errorCode;
- }
-
- /**
- *
- * Determine if the specified error code is in the 'ERR_PERSISTENCE'
- * category of errors.
- *
- */
- public boolean isPersistenceError() {
- return (errorCode >= ERR_PERSISTENCE && errorCode <= ERR_PERSISTENCE + 99);
- }
-
- /**
- *
- * Determine if the specified error code is in the 'ERR_THREAD_POOL'
- * category of errors.
- *
- */
- public boolean isThreadPoolError() {
- return (errorCode >= ERR_THREAD_POOL && errorCode <= ERR_THREAD_POOL + 99);
- }
-
- /**
- *
- * Determine if the specified error code is in the 'ERR_JOB_LISTENER'
- * category of errors.
- *
- */
- public boolean isJobListenerError() {
- return (errorCode >= ERR_JOB_LISTENER && errorCode <= ERR_JOB_LISTENER + 99);
- }
-
- /**
- *
- * Determine if the specified error code is in the 'ERR_TRIGGER_LISTENER'
- * category of errors.
- *
- */
- public boolean isTriggerListenerError() {
- return (errorCode >= ERR_TRIGGER_LISTENER && errorCode <= ERR_TRIGGER_LISTENER + 99);
- }
-
- /**
- *
- * Determine if the specified error code is in the 'ERR_CLIENT_ERROR'
- * category of errors.
- *
- */
- public boolean isClientError() {
- return (errorCode >= ERR_CLIENT_ERROR && errorCode <= ERR_CLIENT_ERROR + 99);
- }
-
- /**
- *
- * Determine if the specified error code is in the 'ERR_CLIENT_ERROR'
- * category of errors.
- *
- */
- public boolean isConfigurationError() {
- return (errorCode >= ERR_BAD_CONFIGURATION && errorCode <= ERR_BAD_CONFIGURATION + 49);
- }
-
+ @Override
public String toString() {
- if (cause == null) return super.toString();
- else
- return super.toString() + " [See nested exception: "
- + cause.toString() + "]";
- }
-
- /**
- *
- * Print a stack trace to the standard error stream.
- *
- *
- *
- * This overridden version will print the nested stack trace if available,
- * otherwise it prints only this exception's stack.
- *
- */
- public void printStackTrace() {
- printStackTrace(System.err);
- }
-
- /**
- *
- * Print a stack trace to the specified stream.
- *
- *
- *
- * This overridden version will print the nested stack trace if available,
- * otherwise it prints only this exception's stack.
- *
- *
- * @param out
- * the stream to which the stack traces will be printed.
- */
- public void printStackTrace(PrintStream out) {
- super.printStackTrace(out);
- if ((cause != null)) {
- synchronized (out) {
- out
- .println("* Nested Exception (Underlying Cause) ---------------");
- cause.printStackTrace(out);
- }
+ Throwable cause = getUnderlyingException();
+ if (cause == null || cause == this) {
+ return super.toString();
+ } else {
+ return super.toString() + " [See nested exception: " + cause + "]";
}
}
- /**
- *
- * Print a stack trace to the specified writer.
- *
- *
- *
- * This overridden version will print the nested stack trace if available,
- * otherwise it prints this exception's stack.
- *
- *
- * @param out
- * the writer to which the stack traces will be printed.
- */
- public void printStackTrace(PrintWriter out) {
- super.printStackTrace(out);
- if ((cause != null)) {
- synchronized (out) {
- out
- .println("* Nested Exception (Underlying Cause) ---------------");
- cause.printStackTrace(out);
- }
- }
- }
}
Index: 3rdParty_sources/quartz/org/quartz/SchedulerFactory.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SchedulerFactory.java (.../SchedulerFactory.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SchedulerFactory.java (.../SchedulerFactory.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,18 +16,13 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
import java.util.Collection;
/**
- *
* Provides a mechanism for obtaining client-usable handles to Scheduler
* instances.
- *
*
* @see Scheduler
* @see org.quartz.impl.StdSchedulerFactory
@@ -52,21 +47,21 @@
* @throws SchedulerException
* if there is a problem with the underlying Scheduler.
*/
- public Scheduler getScheduler() throws SchedulerException;
+ Scheduler getScheduler() throws SchedulerException;
/**
*
* Returns a handle to the Scheduler with the given name, if it exists.
*
*/
- public Scheduler getScheduler(String schedName) throws SchedulerException;
+ Scheduler getScheduler(String schedName) throws SchedulerException;
/**
*
* Returns handles to all known Schedulers (made by any SchedulerFactory
* within this jvm.).
*
*/
- public Collection getAllSchedulers() throws SchedulerException;
+ Collection getAllSchedulers() throws SchedulerException;
}
Index: 3rdParty_sources/quartz/org/quartz/SchedulerListener.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SchedulerListener.java (.../SchedulerListener.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SchedulerListener.java (.../SchedulerListener.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,16 +16,11 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* The interface to be implemented by classes that want to be informed of major
* {@link Scheduler} events.
- *
*
* @see Scheduler
* @see JobListener
@@ -49,82 +44,116 @@
* is scheduled.
*
*/
- public void jobScheduled(Trigger trigger);
+ void jobScheduled(Trigger trigger);
/**
*
* Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
* is unscheduled.
*
+ *
+ * @see SchedulerListener#schedulingDataCleared()
*/
- public void jobUnscheduled(String triggerName, String triggerGroup);
+ void jobUnscheduled(TriggerKey triggerKey);
/**
*
* Called by the {@link Scheduler} when a {@link Trigger}
* has reached the condition in which it will never fire again.
*
*/
- public void triggerFinalized(Trigger trigger);
+ void triggerFinalized(Trigger trigger);
/**
*
* Called by the {@link Scheduler} when a {@link Trigger}
- * or group of {@link Trigger}s has been paused.
+ * has been paused.
*
- *
+ */
+ void triggerPaused(TriggerKey triggerKey);
+
+ /**
*
- * If a group was paused, then the triggerName parameter
- * will be null.
+ * Called by the {@link Scheduler} when a
+ * group of {@link Trigger}s has been paused.
*
+ *
+ * If all groups were paused then triggerGroup will be null
+ *
+ * @param triggerGroup the paused group, or null if all were paused
*/
- public void triggersPaused(String triggerName, String triggerGroup);
-
+ void triggersPaused(String triggerGroup);
+
/**
*
* Called by the {@link Scheduler} when a {@link Trigger}
- * or group of {@link Trigger}s has been un-paused.
+ * has been un-paused.
*
- *
+ */
+ void triggerResumed(TriggerKey triggerKey);
+
+ /**
*
- * If a group was resumed, then the triggerName parameter
- * will be null.
+ * Called by the {@link Scheduler} when a
+ * group of {@link Trigger}s has been un-paused.
*
*/
- public void triggersResumed(String triggerName, String triggerGroup);
+ void triggersResumed(String triggerGroup);
/**
*
* Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
- * or group of {@link org.quartz.JobDetail}s has been
- * paused.
+ * has been added.
*
- *
+ */
+ void jobAdded(JobDetail jobDetail);
+
+ /**
*
- * If a group was paused, then the jobName parameter will be
- * null. If all jobs were paused, then both parameters will be null.
+ * Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
+ * has been deleted.
*
*/
- public void jobsPaused(String jobName, String jobGroup);
-
+ void jobDeleted(JobKey jobKey);
+
/**
*
* Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
- * or group of {@link org.quartz.JobDetail}s has been
- * un-paused.
+ * has been paused.
*
+ */
+ void jobPaused(JobKey jobKey);
+
+ /**
+ *
+ * Called by the {@link Scheduler} when a
+ * group of {@link org.quartz.JobDetail}s has been paused.
+ *
*
+ * @param jobGroup the paused group, or null if all were paused
+ */
+ void jobsPaused(String jobGroup);
+
+ /**
*
- * If a group was resumed, then the jobName parameter will
- * be null. If all jobs were paused, then both parameters will be null.
+ * Called by the {@link Scheduler} when a {@link org.quartz.JobDetail}
+ * has been un-paused.
*
*/
- public void jobsResumed(String jobName, String jobGroup);
+ void jobResumed(JobKey jobKey);
/**
*
+ * Called by the {@link Scheduler} when a
+ * group of {@link org.quartz.JobDetail}s has been un-paused.
+ *
+ */
+ void jobsResumed(String jobGroup);
+
+ /**
+ *
* Called by the {@link Scheduler} when a serious error has
- * occured within the scheduler - such as repeated failures in the JobStore,
+ * occurred within the scheduler - such as repeated failures in the JobStore,
* or the inability to instantiate a Job instance when its
* Trigger has fired.
*
@@ -135,14 +164,51 @@
* error that was encountered.
*
*/
- public void schedulerError(String msg, SchedulerException cause);
+ void schedulerError(String msg, SchedulerException cause);
/**
*
* Called by the {@link Scheduler} to inform the listener
+ * that it has move to standby mode.
+ *
+ */
+ void schedulerInStandbyMode();
+
+ /**
+ *
+ * Called by the {@link Scheduler} to inform the listener
+ * that it has started.
+ *
+ */
+ void schedulerStarted();
+
+ /**
+ *
+ * Called by the {@link Scheduler} to inform the listener
+ * that it is starting.
+ *
+ */
+ void schedulerStarting();
+
+ /**
+ *
+ * Called by the {@link Scheduler} to inform the listener
* that it has shutdown.
*
*/
- public void schedulerShutdown();
+ void schedulerShutdown();
+
+ /**
+ *
+ * Called by the {@link Scheduler} to inform the listener
+ * that it has begun the shutdown sequence.
+ *
+ */
+ void schedulerShuttingdown();
+ /**
+ * Called by the {@link Scheduler} to inform the listener
+ * that all jobs, triggers and calendars were deleted.
+ */
+ void schedulingDataCleared();
}
Index: 3rdParty_sources/quartz/org/quartz/SchedulerMetaData.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SchedulerMetaData.java (.../SchedulerMetaData.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SchedulerMetaData.java (.../SchedulerMetaData.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,22 +16,19 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
import java.util.Date;
/**
- *
* Describes the settings and capabilities of a given {@link Scheduler}
* instance.
- *
*
* @author James House
*/
public class SchedulerMetaData implements java.io.Serializable {
+
+ private static final long serialVersionUID = 4203690002633917647L;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -45,26 +42,28 @@
private String schedInst;
- private Class schedClass;
+ private Class> schedClass;
private boolean isRemote;
private boolean started;
- private boolean paused;
+ private boolean isInStandbyMode;
private boolean shutdown;
private Date startTime;
private int numJobsExec;
- private Class jsClass;
+ private Class> jsClass;
private boolean jsPersistent;
- private Class tpClass;
+ private boolean jsClustered;
+ private Class> tpClass;
+
private int tpSize;
private String version;
@@ -78,21 +77,22 @@
*/
public SchedulerMetaData(String schedName, String schedInst,
- Class schedClass, boolean isRemote, boolean started,
- boolean paused, boolean shutdown, Date startTime, int numJobsExec,
- Class jsClass, boolean jsPersistent, Class tpClass, int tpSize,
+ Class> schedClass, boolean isRemote, boolean started,
+ boolean isInStandbyMode, boolean shutdown, Date startTime, int numJobsExec,
+ Class> jsClass, boolean jsPersistent, boolean jsClustered, Class> tpClass, int tpSize,
String version) {
this.schedName = schedName;
this.schedInst = schedInst;
this.schedClass = schedClass;
this.isRemote = isRemote;
this.started = started;
- this.paused = paused;
+ this.isInStandbyMode = isInStandbyMode;
this.shutdown = shutdown;
this.startTime = startTime;
this.numJobsExec = numJobsExec;
this.jsClass = jsClass;
this.jsPersistent = jsPersistent;
+ this.jsClustered = jsClustered;
this.tpClass = tpClass;
this.tpSize = tpSize;
this.version = version;
@@ -129,7 +129,7 @@
* Returns the class-name of the Scheduler instance.
*
*/
- public Class getSchedulerClass() {
+ public Class> getSchedulerClass() {
return schedClass;
}
@@ -140,17 +140,17 @@
*
* @return null if the scheduler has not been started.
*/
- public Date runningSince() {
+ public Date getRunningSince() {
return startTime;
}
-
+
/**
*
* Returns the number of jobs executed since the Scheduler
* started..
*
*/
- public int numJobsExecuted() {
+ public int getNumberOfJobsExecuted() {
return numJobsExec;
}
@@ -171,25 +171,18 @@
*
*
* Note: isStarted() may return true even if
- * isPaused() returns true.
+ * isInStandbyMode() returns true.
*
*/
public boolean isStarted() {
return started;
}
/**
- *
- * Reports whether the Scheduler is paused.
- *
- *
- *
- * Note: isStarted() may return true even if
- * isPaused() returns true.
- *
+ * Reports whether the Scheduler is in standby mode.
*/
- public boolean isPaused() {
- return paused;
+ public boolean isInStandbyMode() {
+ return isInStandbyMode;
}
/**
@@ -207,27 +200,37 @@
* being used by the Scheduler.
*
*/
- public Class getJobStoreClass() {
+ public Class> getJobStoreClass() {
return jsClass;
}
-
+
/**
*
* Returns whether or not the Scheduler'sJobStore
* instance supports persistence.
*
*/
- public boolean jobStoreSupportsPersistence() {
+ public boolean isJobStoreSupportsPersistence() {
return jsPersistent;
}
/**
*
+ * Returns whether or not the Scheduler'sJobStore
+ * is clustered.
+ *
+ */
+ public boolean isJobStoreClustered() {
+ return jsClustered;
+ }
+
+ /**
+ *
* Returns the class-name of the ThreadPool instance that is
* being used by the Scheduler.
*
*/
- public Class getThreadPoolClass() {
+ public Class> getThreadPoolClass() {
return tpClass;
}
@@ -255,6 +258,7 @@
* Return a simple string representation of this object.
*
*/
+ @Override
public String toString() {
try {
return getSummary();
@@ -281,7 +285,7 @@
*
*/
public String getSummary() throws SchedulerException {
- StringBuffer str = new StringBuffer("Quartz Scheduler (v");
+ StringBuilder str = new StringBuilder("Quartz Scheduler (v");
str.append(getVersion());
str.append(") '");
@@ -293,29 +297,34 @@
str.append(" Scheduler class: '");
str.append(getSchedulerClass().getName());
str.append("'");
- if (isSchedulerRemote()) str.append(" - access via RMI.");
- else
+ if (isSchedulerRemote()) {
+ str.append(" - access via RMI.");
+ } else {
str.append(" - running locally.");
+ }
str.append("\n");
if (!isShutdown()) {
- if (runningSince() != null) {
+ if (getRunningSince() != null) {
str.append(" Running since: ");
- str.append(runningSince());
- } else
- str.append("NOT STARTED.");
+ str.append(getRunningSince());
+ } else {
+ str.append(" NOT STARTED.");
+ }
str.append("\n");
- if (isPaused()) str.append(" Currently PAUSED.");
- else
- str.append(" Not currently paused.");
+ if (isInStandbyMode()) {
+ str.append(" Currently in standby mode.");
+ } else {
+ str.append(" Not currently in standby mode.");
+ }
} else {
str.append(" Scheduler has been SHUTDOWN.");
}
str.append("\n");
str.append(" Number of jobs executed: ");
- str.append(numJobsExecuted());
+ str.append(getNumberOfJobsExecuted());
str.append("\n");
str.append(" Using thread pool '");
@@ -328,9 +337,16 @@
str.append(" Using job-store '");
str.append(getJobStoreClass().getName());
str.append("' - which ");
- if (jobStoreSupportsPersistence()) str.append("supports persistence.");
- else
+ if (isJobStoreSupportsPersistence()) {
+ str.append("supports persistence.");
+ } else {
str.append("does not support persistence.");
+ }
+ if (isJobStoreClustered()) {
+ str.append(" and is clustered.");
+ } else {
+ str.append(" and is not clustered.");
+ }
str.append("\n");
return str.toString();
Index: 3rdParty_sources/quartz/org/quartz/SimpleScheduleBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/SimpleScheduleBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/SimpleScheduleBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,429 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import org.quartz.impl.triggers.SimpleTriggerImpl;
+import org.quartz.spi.MutableTrigger;
+
+/**
+ * SimpleScheduleBuilder is a {@link ScheduleBuilder}
+ * that defines strict/literal interval-based schedules for
+ * Triggers.
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(simpleSchedule()
+ * .withIntervalInHours(1)
+ * .repeatForever())
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ * @see SimpleTrigger
+ * @see CalendarIntervalScheduleBuilder
+ * @see CronScheduleBuilder
+ * @see ScheduleBuilder
+ * @see TriggerBuilder
+ */
+public class SimpleScheduleBuilder extends ScheduleBuilder {
+
+ private long interval = 0;
+ private int repeatCount = 0;
+ private int misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_SMART_POLICY;
+
+ protected SimpleScheduleBuilder() {
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder simpleSchedule() {
+ return new SimpleScheduleBuilder();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat forever with a 1 minute interval.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatMinutelyForever() {
+
+ return simpleSchedule()
+ .withIntervalInMinutes(1)
+ .repeatForever();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat forever with an interval
+ * of the given number of minutes.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatMinutelyForever(int minutes) {
+
+ return simpleSchedule()
+ .withIntervalInMinutes(minutes)
+ .repeatForever();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat forever with a 1 second interval.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatSecondlyForever() {
+
+ return simpleSchedule()
+ .withIntervalInSeconds(1)
+ .repeatForever();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat forever with an interval
+ * of the given number of seconds.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatSecondlyForever(int seconds) {
+
+ return simpleSchedule()
+ .withIntervalInSeconds(seconds)
+ .repeatForever();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat forever with a 1 hour interval.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatHourlyForever() {
+
+ return simpleSchedule()
+ .withIntervalInHours(1)
+ .repeatForever();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat forever with an interval
+ * of the given number of hours.
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatHourlyForever(int hours) {
+
+ return simpleSchedule()
+ .withIntervalInHours(hours)
+ .repeatForever();
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat the given number
+ * of times - 1 with a 1 minute interval.
+ *
+ * Note: Total count = 1 (at start time) + repeat count
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatMinutelyForTotalCount(int count) {
+ if(count < 1)
+ throw new IllegalArgumentException("Total count of firings must be at least one! Given count: " + count);
+
+ return simpleSchedule()
+ .withIntervalInMinutes(1)
+ .withRepeatCount(count - 1);
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat the given number
+ * of times - 1 with an interval of the given number of minutes.
+ *
+ * Note: Total count = 1 (at start time) + repeat count
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatMinutelyForTotalCount(int count, int minutes) {
+ if(count < 1)
+ throw new IllegalArgumentException("Total count of firings must be at least one! Given count: " + count);
+
+ return simpleSchedule()
+ .withIntervalInMinutes(minutes)
+ .withRepeatCount(count - 1);
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat the given number
+ * of times - 1 with a 1 second interval.
+ *
+ * Note: Total count = 1 (at start time) + repeat count
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatSecondlyForTotalCount(int count) {
+ if(count < 1)
+ throw new IllegalArgumentException("Total count of firings must be at least one! Given count: " + count);
+
+ return simpleSchedule()
+ .withIntervalInSeconds(1)
+ .withRepeatCount(count - 1);
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat the given number
+ * of times - 1 with an interval of the given number of seconds.
+ *
+ * Note: Total count = 1 (at start time) + repeat count
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatSecondlyForTotalCount(int count, int seconds) {
+ if(count < 1)
+ throw new IllegalArgumentException("Total count of firings must be at least one! Given count: " + count);
+
+ return simpleSchedule()
+ .withIntervalInSeconds(seconds)
+ .withRepeatCount(count - 1);
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat the given number
+ * of times - 1 with a 1 hour interval.
+ *
+ * Note: Total count = 1 (at start time) + repeat count
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatHourlyForTotalCount(int count) {
+ if(count < 1)
+ throw new IllegalArgumentException("Total count of firings must be at least one! Given count: " + count);
+
+ return simpleSchedule()
+ .withIntervalInHours(1)
+ .withRepeatCount(count - 1);
+ }
+
+ /**
+ * Create a SimpleScheduleBuilder set to repeat the given number
+ * of times - 1 with an interval of the given number of hours.
+ *
+ * Note: Total count = 1 (at start time) + repeat count
+ *
+ * @return the new SimpleScheduleBuilder
+ */
+ public static SimpleScheduleBuilder repeatHourlyForTotalCount(int count, int hours) {
+ if(count < 1)
+ throw new IllegalArgumentException("Total count of firings must be at least one! Given count: " + count);
+
+ return simpleSchedule()
+ .withIntervalInHours(hours)
+ .withRepeatCount(count - 1);
+ }
+
+ /**
+ * Build the actual Trigger -- NOT intended to be invoked by end users,
+ * but will rather be invoked by a TriggerBuilder which this
+ * ScheduleBuilder is given to.
+ *
+ * @see TriggerBuilder#withSchedule(ScheduleBuilder)
+ */
+ @Override
+ public MutableTrigger build() {
+
+ SimpleTriggerImpl st = new SimpleTriggerImpl();
+ st.setRepeatInterval(interval);
+ st.setRepeatCount(repeatCount);
+ st.setMisfireInstruction(misfireInstruction);
+
+ return st;
+ }
+
+ /**
+ * Specify a repeat interval in milliseconds.
+ *
+ * @param intervalInMillis the number of seconds at which the trigger should repeat.
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#getRepeatInterval()
+ * @see #withRepeatCount(int)
+ */
+ public SimpleScheduleBuilder withIntervalInMilliseconds(long intervalInMillis) {
+ this.interval = intervalInMillis;
+ return this;
+ }
+
+ /**
+ * Specify a repeat interval in seconds - which will then be multiplied
+ * by 1000 to produce milliseconds.
+ *
+ * @param intervalInSeconds the number of seconds at which the trigger should repeat.
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#getRepeatInterval()
+ * @see #withRepeatCount(int)
+ */
+ public SimpleScheduleBuilder withIntervalInSeconds(int intervalInSeconds) {
+ this.interval = intervalInSeconds * 1000L;
+ return this;
+ }
+
+ /**
+ * Specify a repeat interval in minutes - which will then be multiplied
+ * by 60 * 1000 to produce milliseconds.
+ *
+ * @param intervalInMinutes the number of seconds at which the trigger should repeat.
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#getRepeatInterval()
+ * @see #withRepeatCount(int)
+ */
+ public SimpleScheduleBuilder withIntervalInMinutes(int intervalInMinutes) {
+ this.interval = intervalInMinutes * DateBuilder.MILLISECONDS_IN_MINUTE;
+ return this;
+ }
+
+ /**
+ * Specify a repeat interval in minutes - which will then be multiplied
+ * by 60 * 60 * 1000 to produce milliseconds.
+ *
+ * @param intervalInHours the number of seconds at which the trigger should repeat.
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#getRepeatInterval()
+ * @see #withRepeatCount(int)
+ */
+ public SimpleScheduleBuilder withIntervalInHours(int intervalInHours) {
+ this.interval = intervalInHours * DateBuilder.MILLISECONDS_IN_HOUR;
+ return this;
+ }
+
+ /**
+ * Specify a the number of time the trigger will repeat - total number of
+ * firings will be this number + 1.
+ *
+ * @param triggerRepeatCount the number of seconds at which the trigger should repeat.
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#getRepeatCount()
+ * @see #repeatForever()
+ */
+ public SimpleScheduleBuilder withRepeatCount(int triggerRepeatCount) {
+ this.repeatCount = triggerRepeatCount;
+ return this;
+ }
+
+ /**
+ * Specify that the trigger will repeat indefinitely.
+ *
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#getRepeatCount()
+ * @see SimpleTrigger#REPEAT_INDEFINITELY
+ * @see #withIntervalInMilliseconds(long)
+ * @see #withIntervalInSeconds(int)
+ * @see #withIntervalInMinutes(int)
+ * @see #withIntervalInHours(int)
+ */
+ public SimpleScheduleBuilder repeatForever() {
+ this.repeatCount = SimpleTrigger.REPEAT_INDEFINITELY;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY} instruction.
+ *
+ * @return the updated CronScheduleBuilder
+ * @see Trigger#MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
+ */
+ public SimpleScheduleBuilder withMisfireHandlingInstructionIgnoreMisfires() {
+ misfireInstruction = Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link SimpleTrigger#MISFIRE_INSTRUCTION_FIRE_NOW} instruction.
+ *
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#MISFIRE_INSTRUCTION_FIRE_NOW
+ */
+
+ public SimpleScheduleBuilder withMisfireHandlingInstructionFireNow() {
+ misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT} instruction.
+ *
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT
+ */
+ public SimpleScheduleBuilder withMisfireHandlingInstructionNextWithExistingCount() {
+ misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT} instruction.
+ *
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
+ */
+ public SimpleScheduleBuilder withMisfireHandlingInstructionNextWithRemainingCount() {
+ misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT} instruction.
+ *
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
+ */
+ public SimpleScheduleBuilder withMisfireHandlingInstructionNowWithExistingCount() {
+ misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT;
+ return this;
+ }
+
+ /**
+ * If the Trigger misfires, use the
+ * {@link SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT} instruction.
+ *
+ * @return the updated SimpleScheduleBuilder
+ * @see SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
+ */
+ public SimpleScheduleBuilder withMisfireHandlingInstructionNowWithRemainingCount() {
+ misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT;
+ return this;
+ }
+
+}
Index: 3rdParty_sources/quartz/org/quartz/SimpleTrigger.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/SimpleTrigger.java (.../SimpleTrigger.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/SimpleTrigger.java (.../SimpleTrigger.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,5 @@
-
-/*
- * Copyright 2004-2005 OpenSymphony
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*
* 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
@@ -16,37 +15,22 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
-import java.util.Date;
-
-
/**
- *
- * A concrete {@link Trigger} that is used to fire a {@link org.quartz.JobDetail}
+ * A {@link Trigger} that is used to fire a Job
* at a given moment in time, and optionally repeated at a specified interval.
- *
*
- * @see Trigger
- * @see CronTrigger
- * @see TriggerUtils
+ * @see TriggerBuilder
+ * @see SimpleScheduleBuilder
*
* @author James House
* @author contributions by Lieven Govaerts of Ebitec Nv, Belgium.
*/
-public class SimpleTrigger extends Trigger {
+public interface SimpleTrigger extends Trigger {
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constants.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
+ public static final long serialVersionUID = -3735980074222850397L;
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
@@ -62,13 +46,15 @@
*
*/
public static final int MISFIRE_INSTRUCTION_FIRE_NOW = 1;
-
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
* situation, the {@link SimpleTrigger} wants to be
* re-scheduled to 'now' (even if the associated {@link Calendar}
- * excludes 'now') with the repeat count left as-is.
+ * excludes 'now') with the repeat count left as-is. This does obey the
+ * Trigger end-time however, so if 'now' is after the
+ * end-time the Trigger will not fire again.
*
*
*
@@ -77,29 +63,27 @@
* is only an issue if you for some reason wanted to be able to tell what
* the original values were at some later time).
*
- *
- *
- * NOTE: This instruction could cause the Trigger
- * to go to the 'COMPLETE' state after firing 'now', if all the
- * repeat-fire-times where missed.
- *
*/
public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2;
-
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
* situation, the {@link SimpleTrigger} wants to be
* re-scheduled to 'now' (even if the associated {@link Calendar}
* excludes 'now') with the repeat count set to what it would be, if it had
- * not missed any firings.
+ * not missed any firings. This does obey the Trigger end-time
+ * however, so if 'now' is after the end-time the Trigger will
+ * not fire again.
*
*
*
* NOTE: Use of this instruction causes the trigger to 'forget'
- * the start-time and repeat-count that it was originally setup with (this
- * is only an issue if you for some reason wanted to be able to tell what
- * the original values were at some later time).
+ * the start-time and repeat-count that it was originally setup with.
+ * Instead, the repeat count on the trigger will be changed to whatever
+ * the remaining repeat count is (this is only an issue if you for some
+ * reason wanted to be able to tell what the original values were at some
+ * later time).
*
*
*
@@ -109,7 +93,7 @@
*
*/
public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3;
-
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
@@ -125,7 +109,7 @@
*
*/
public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4;
-
+
/**
*
* Instructs the {@link Scheduler} that upon a mis-fire
@@ -136,705 +120,45 @@
*
*
*
- * NOTE: Use of this instruction causes the trigger to 'forget'
- * the repeat-count that it was originally setup with (this is only an
- * issue if you for some reason wanted to be able to tell what the original
- * values were at some later time).
- *
- *
- *
* NOTE/WARNING: This instruction could cause the Trigger
- * to go directly to the 'COMPLETE' state if all fire-times where missed.
+ * to go directly to the 'COMPLETE' state if the end-time of the trigger
+ * has arrived.
*
*/
public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5;
-
+
/**
*
* Used to indicate the 'repeat count' of the trigger is indefinite. Or in
* other words, the trigger should repeat continually until the trigger's
* ending timestamp.
*
*/
- public static int REPEAT_INDEFINITELY = -1;
+ public static final int REPEAT_INDEFINITELY = -1;
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- private Date startTime = null;
-
- private Date endTime = null;
-
- private Date nextFireTime = null;
-
- private Date previousFireTime = null;
-
- private int repeatCount = 0;
-
- private long repeatInterval = 0;
-
- private int timesTriggered = 0;
-
- private boolean complete = false;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
/**
*
- * Create a SimpleTrigger with no settings.
- *
- */
- public SimpleTrigger() {
- super();
- }
-
- /**
- *
- * Create a SimpleTrigger that will occur immediately, and
- * not repeat.
- *
- */
- public SimpleTrigger(String name, String group) {
- this(name, group, new Date(), null, 0, 0);
- }
-
- /**
- *
- * Create a SimpleTrigger that will occur immediately, and
- * repeat at the the given interval the given number of times.
- *
- */
- public SimpleTrigger(String name, String group, int repeatCount,
- long repeatInterval) {
- this(name, group, new Date(), null, repeatCount, repeatInterval);
- }
-
- /**
- *
- * Create a SimpleTrigger that will occur at the given time,
- * and not repeat.
- *
- */
- public SimpleTrigger(String name, String group, Date startTime) {
- this(name, group, startTime, null, 0, 0);
- }
-
- /**
- *
- * Create a SimpleTrigger that will occur at the given time,
- * and repeat at the the given interval the given number of times, or until
- * the given end time.
- *
- *
- * @param startTime
- * A Date set to the time for the Trigger
- * to fire.
- * @param endTime
- * A Date set to the time for the Trigger
- * to quit repeat firing.
- * @param repeatCount
- * The number of times for the Trigger to repeat
- * firing, use {@link #REPEAT_INDEFINITELY}for unlimitted times.
- * @param repeatInterval
- * The number of milliseconds to pause between the repeat firing.
- */
- public SimpleTrigger(String name, String group, Date startTime,
- Date endTime, int repeatCount, long repeatInterval) {
- super(name, group);
-
- setStartTime(startTime);
- setEndTime(endTime);
- setRepeatCount(repeatCount);
- setRepeatInterval(repeatInterval);
- }
-
- /**
- *
- * Create a SimpleTrigger that will occur at the given time,
- * fire the identified Job and repeat at the the given
- * interval the given number of times, or until the given end time.
- *
- *
- * @param startTime
- * A Date set to the time for the Trigger
- * to fire.
- * @param endTime
- * A Date set to the time for the Trigger
- * to quit repeat firing.
- * @param repeatCount
- * The number of times for the Trigger to repeat
- * firing, use {@link #REPEAT_INDEFINITELY}for unlimitted times.
- * @param repeatInterval
- * The number of milliseconds to pause between the repeat firing.
- */
- public SimpleTrigger(String name, String group, String jobName,
- String jobGroup, Date startTime, Date endTime, int repeatCount,
- long repeatInterval) {
- super(name, group, jobName, jobGroup);
-
- setStartTime(startTime);
- setEndTime(endTime);
- setRepeatCount(repeatCount);
- setRepeatInterval(repeatInterval);
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- *
- * Get the time at which the SimpleTrigger should occur.
- *
- */
- public Date getStartTime() {
- return startTime;
- }
-
- /**
- *
- * Set the time at which the SimpleTrigger should occur.
- *
- *
- * @exception IllegalArgumentException
- * if startTime is null.
- */
- public void setStartTime(Date startTime) {
- if (startTime == null)
- throw new IllegalArgumentException("Start time cannot be null");
-
- Date eTime = getEndTime();
- if (eTime != null && startTime != null && eTime.before(startTime))
- throw new IllegalArgumentException(
- "End time cannot be before start time");
-
- this.startTime = startTime;
- }
-
- /**
- *
- * Get the time at which the SimpleTrigger should quit
- * repeating - even if repeastCount isn't yet satisfied.
- *
- *
- * @see #getFinalFireTime()
- */
- public Date getEndTime() {
- return endTime;
- }
-
- /**
- *
- * Set the time at which the SimpleTrigger should quit
- * repeating (and be automatically deleted).
- *
- *
- * @exception IllegalArgumentException
- * if endTime is before start time.
- */
- public void setEndTime(Date endTime) {
- Date sTime = getStartTime();
- if (sTime != null && endTime != null && sTime.after(endTime))
- throw new IllegalArgumentException(
- "End time cannot be before start time");
-
- this.endTime = endTime;
- }
-
- /**
- *
* Get the the number of times the SimpleTrigger should
* repeat, after which it will be automatically deleted.
*
*
* @see #REPEAT_INDEFINITELY
*/
- public int getRepeatCount() {
- return repeatCount;
- }
+ public int getRepeatCount();
/**
*
- * Set the the number of time the SimpleTrigger should
- * repeat, after which it will be automatically deleted.
+ * Get the the time interval (in milliseconds) at which the SimpleTrigger should repeat.
*
- *
- * @see #REPEAT_INDEFINITELY
- * @exception IllegalArgumentException
- * if repeatCount is < 0
*/
- public void setRepeatCount(int repeatCount) {
- if (repeatCount < 0 && repeatCount != REPEAT_INDEFINITELY)
- throw new IllegalArgumentException(
- "Repeat count must be >= 0, use the "
- + "constant REPEAT_INDEFINITELY for infinite.");
-
- this.repeatCount = repeatCount;
- }
-
+ public long getRepeatInterval();
+
/**
*
- * Get the the time interval (in milliseconds) at which the SimpleTrigger
- * should repeat.
+ * Get the number of times the SimpleTrigger has already fired.
*
*/
- public long getRepeatInterval() {
- return repeatInterval;
- }
+ public int getTimesTriggered();
- /**
- *
- * Set the the time interval (in milliseconds) at which the SimpleTrigger
- * should repeat.
- *
- *
- * @exception IllegalArgumentException
- * if repeatInterval is <= 0
- */
- public void setRepeatInterval(long repeatInterval) {
- if (repeatInterval < 0)
- throw new IllegalArgumentException(
- "Repeat interval must be >= 0");
-
- this.repeatInterval = repeatInterval;
- }
-
- /**
- *
- * Get the number of times the SimpleTrigger has already
- * fired.
- *
- */
- public int getTimesTriggered() {
- return timesTriggered;
- }
-
- /**
- *
- * Set the number of times the SimpleTrigger has already
- * fired.
- *
- */
- public void setTimesTriggered(int timesTriggered) {
- this.timesTriggered = timesTriggered;
- }
-
- protected boolean validateMisfireInstruction(int misfireInstruction) {
- if (misfireInstruction < MISFIRE_INSTRUCTION_SMART_POLICY)
- return false;
-
- if (misfireInstruction > MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT)
- return false;
-
- return true;
- }
-
- /**
- *
- * Updates the SimpleTrigger's state based on the
- * MISFIRE_INSTRUCTION_XXX that was selected when the SimpleTrigger
- * was created.
- *
- *
- *
- * If the misfire instruction is set to MISFIRE_INSTRUCTION_SMART_POLICY,
- * then the following scheme will be used:
- *
- * - If the Repeat Count is
0, then the instruction will
- * be interpreted as MISFIRE_INSTRUCTION_FIRE_NOW.
- * - If the Repeat Count is
REPEAT_INDEFINITELY, then
- * the instruction will be interpreted as MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT.
- * WARNING: using MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
- * with a trigger that has a non-null end-time may cause the trigger to
- * never fire again if the end-time arrived during the misfire time span.
- *
- * - If the Repeat Count is
> 0, then the instruction
- * will be interpreted as MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT.
- *
- *
- *
- */
- public void updateAfterMisfire(Calendar cal) {
- int instr = getMisfireInstruction();
- if (instr == Trigger.MISFIRE_INSTRUCTION_SMART_POLICY) {
- if (getRepeatCount() == 0) instr = MISFIRE_INSTRUCTION_FIRE_NOW;
- else if (getRepeatCount() == REPEAT_INDEFINITELY) instr = MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT;
- else
- // if (getRepeatCount() > 0)
- instr = MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT;
- } else if (instr == MISFIRE_INSTRUCTION_FIRE_NOW
- && getRepeatCount() != 0)
- instr = MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT;
-
- if (instr == MISFIRE_INSTRUCTION_FIRE_NOW) {
- setNextFireTime(new Date());
- } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT) {
- Date newFireTime = getFireTimeAfter(new Date());
- while (newFireTime != null && cal != null
- && !cal.isTimeIncluded(newFireTime.getTime())) {
- newFireTime = getFireTimeAfter(newFireTime);
- }
- setNextFireTime(newFireTime);
- } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT) {
- Date newFireTime = getFireTimeAfter(new Date());
- while (newFireTime != null && cal != null
- && !cal.isTimeIncluded(newFireTime.getTime())) {
- newFireTime = getFireTimeAfter(newFireTime);
- }
- if (newFireTime != null) {
- int timesMissed = computeNumTimesFiredBetween(nextFireTime,
- newFireTime);
- setTimesTriggered(getTimesTriggered() + timesMissed);
- }
-
- setNextFireTime(newFireTime);
- } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT) {
- Date newFireTime = new Date();
- if (repeatCount != 0 && repeatCount != REPEAT_INDEFINITELY) {
- setRepeatCount(getRepeatCount() - getTimesTriggered());
- setTimesTriggered(0);
- }
- setStartTime(newFireTime);
- setNextFireTime(newFireTime);
- } else if (instr == MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT) {
- Date newFireTime = new Date();
-
- int timesMissed = computeNumTimesFiredBetween(nextFireTime,
- newFireTime);
-
- if (repeatCount != 0 && repeatCount != REPEAT_INDEFINITELY) {
- int remainingCount = getRepeatCount()
- - (getTimesTriggered() + timesMissed);
- if (remainingCount <= 0) {
- remainingCount = 0;
- }
- setRepeatCount(remainingCount);
- setTimesTriggered(0);
- }
-
- if(getEndTime() != null && getEndTime().before(newFireTime))
- setEndTime(new Date(newFireTime.getTime() + 50));
-
- setStartTime(newFireTime);
- setNextFireTime(newFireTime);
- }
-
- }
-
- /**
- *
- * 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 void triggered(Calendar calendar) {
- timesTriggered++;
- previousFireTime = nextFireTime;
- nextFireTime = getFireTimeAfter(nextFireTime);
-
- while (nextFireTime != null && calendar != null
- && !calendar.isTimeIncluded(nextFireTime.getTime())) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- }
- }
-
- /**
- *
- * @see org.quartz.Trigger#updateWithNewCalendar(org.quartz.Calendar, long)
- */
- public void updateWithNewCalendar(Calendar calendar, long misfireThreshold)
- {
- nextFireTime = getFireTimeAfter(previousFireTime);
-
- Date now = new Date();
- do {
- while (nextFireTime != null && calendar != null
- && !calendar.isTimeIncluded(nextFireTime.getTime())) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- }
-
- if(nextFireTime != null && nextFireTime.before(now)) {
- long diff = now.getTime() - nextFireTime.getTime();
- if(diff >= misfireThreshold) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- continue;
- }
- }
- }while(false);
- }
-
- /**
- *
- * 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 Date computeFirstFireTime(Calendar calendar) {
- nextFireTime = getStartTime();
-
- while (nextFireTime != null && calendar != null
- && !calendar.isTimeIncluded(nextFireTime.getTime())) {
- nextFireTime = getFireTimeAfter(nextFireTime);
- }
-
- return nextFireTime;
- }
-
- /**
- *
- * 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 int executionComplete(JobExecutionContext context,
- JobExecutionException result) {
- if (result != null && result.refireImmediately())
- return INSTRUCTION_RE_EXECUTE_JOB;
-
- if (result != null && result.unscheduleFiringTrigger())
- return INSTRUCTION_SET_TRIGGER_COMPLETE;
-
- if (result != null && result.unscheduleAllTriggers())
- return INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE;
-
- if (!mayFireAgain()) return INSTRUCTION_DELETE_TRIGGER;
-
- return INSTRUCTION_NOOP;
- }
-
- /**
- *
- * Returns the next time at which the SimpleTrigger 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 Date getNextFireTime() {
- return nextFireTime;
- }
-
- /**
- *
- * Returns the previous time at which the SimpleTrigger will
- * fire. If the trigger has not yet fired, null will be
- * returned.
- */
- public Date getPreviousFireTime() {
- return previousFireTime;
- }
-
- /**
- *
- * Set the next time at which the SimpleTrigger should fire.
- *
- *
- *
- * This method should not be invoked by client code.
- *
- */
- public void setNextFireTime(Date nextFireTime) {
- this.nextFireTime = nextFireTime;
- }
-
- /**
- *
- * Set the previous time at which the SimpleTrigger fired.
- *
- *
- *
- * This method should not be invoked by client code.
- *
- */
- public void setPreviousFireTime(Date previousFireTime) {
- this.previousFireTime = previousFireTime;
- }
-
- /**
- *
- * Returns the next time at which the SimpleTrigger will
- * fire, after the given time. If the trigger will not fire after the given
- * time, null will be returned.
- *
- */
- public Date getFireTimeAfter(Date afterTime) {
- if (complete) return null;
-
- if ((timesTriggered > repeatCount)
- && (repeatCount != REPEAT_INDEFINITELY)) return null;
-
- if (afterTime == null) afterTime = new Date();
-
- if (repeatCount == 0 && afterTime.compareTo(getStartTime()) >= 0)
- return null;
-
- long startMillis = getStartTime().getTime();
- long afterMillis = afterTime.getTime();
- long endMillis = (getEndTime() == null) ? Long.MAX_VALUE : getEndTime()
- .getTime();
-
- if (endMillis <= afterMillis) return null;
-
- if (startMillis < afterMillis && repeatCount == 0) return null;
-
- if (afterMillis < startMillis) return new Date(startMillis);
-
- long numberoftimesexecutedplusone = ((afterMillis - startMillis) / repeatInterval) + 1;
-
- if ((numberoftimesexecutedplusone > repeatCount)
- && (repeatCount != REPEAT_INDEFINITELY)) return null;
-
- Date time = new Date((numberoftimesexecutedplusone * repeatInterval)
- + startMillis);
-
- if (endMillis <= time.getTime()) return null;
-
- return time;
- }
-
- /**
- *
- * Returns the last time at which the SimpleTrigger will
- * fire, before the given time. If the trigger will not fire before the
- * given time, null will be returned.
- *
- */
- public Date getFireTimeBefore(Date end) {
- if (end.getTime() < getStartTime().getTime()) return null;
-
- int numFires = computeNumTimesFiredBetween(getStartTime(), end);
-
- return new Date(getStartTime().getTime() + (numFires * repeatInterval));
- }
-
- public int computeNumTimesFiredBetween(Date start, Date end) {
- long time = end.getTime() - start.getTime();
-
- return (int) (time / repeatInterval);
- }
-
- /**
- *
- * Returns the final time at which the SimpleTrigger will
- * fire, if repeatCount is REPEAT_INDEFINITELY, null will be returned.
- *
- *
- *
- * Note that the return time may be in the past.
- *
- */
- public Date getFinalFireTime() {
- if (repeatCount == 0) return startTime;
-
- if (repeatCount == REPEAT_INDEFINITELY && getEndTime() == null)
- return null;
-
- if (repeatCount == REPEAT_INDEFINITELY && getEndTime() == null) return null;
- else if (repeatCount == REPEAT_INDEFINITELY)
- return getFireTimeBefore(getEndTime());
-
- long lastTrigger = startTime.getTime() + (repeatCount * repeatInterval);
-
- if ((getEndTime() == null) || (lastTrigger < getEndTime().getTime())) return new Date(
- lastTrigger);
- else
- return getFireTimeBefore(getEndTime());
- }
-
- /**
- *
- * Determines whether or not the SimpleTrigger will occur
- * again.
- *
- */
- public boolean mayFireAgain() {
- return (getNextFireTime() != null);
- }
-
- /**
- *
- * 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 {
- super.validate();
-
- if (repeatCount != 0 && repeatInterval < 1)
- throw new SchedulerException("Repeat Interval cannot be zero.",
- SchedulerException.ERR_CLIENT_ERROR);
- }
-
- public static void main(String[] args) // TODO: remove method after good
- // unit testing
- throws Exception {
-
- Date sdt = new Date();
-
- Date edt = new Date(sdt.getTime() + 55000L);
-
- SimpleTrigger st = new SimpleTrigger("t", "g", "j", "g", sdt, edt, 10,
- 10000L);
-
- System.err.println();
-
- st.computeFirstFireTime(null);
-
- System.err.println("lastTime=" + st.getFinalFireTime());
-
- java.util.List times = TriggerUtils.computeFireTimes(st, null, 50);
-
- for (int i = 0; i < times.size(); i++) {
- System.err.println("firetime = " + times.get(i));
- }
- }
-
+ TriggerBuilder getTriggerBuilder();
}
Index: 3rdParty_sources/quartz/org/quartz/StatefulJob.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/StatefulJob.java (.../StatefulJob.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/StatefulJob.java (.../StatefulJob.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,16 +16,11 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
/**
- *
* A marker interface for {@link org.quartz.JobDetail} s that
* wish to have their state maintained between executions.
- *
*
*
* StatefulJob instances follow slightly different rules from
@@ -37,13 +32,21 @@
* the execute(xx) method will be delayed.
*
*
+ * @see DisallowConcurrentExecution
+ * @see PersistJobDataAfterExecution
+ *
* @see Job
* @see JobDetail
* @see JobDataMap
* @see Scheduler
*
+ *
+ * @deprecated use DisallowConcurrentExecution and/or PersistJobDataAfterExecution annotations instead.
+ *
* @author James House
*/
+@PersistJobDataAfterExecution
+@DisallowConcurrentExecution
public interface StatefulJob extends Job {
/*
Index: 3rdParty_sources/quartz/org/quartz/TimeOfDay.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/TimeOfDay.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/TimeOfDay.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,243 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+package org.quartz;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Represents a time in hour, minute and second of any given day.
+ *
+ * The hour is in 24-hour convention, meaning values are from 0 to 23.
+ *
+ * @see DailyTimeIntervalScheduleBuilder
+ *
+ * @since 2.0.3
+ *
+ * @author James House
+ * @author Zemian Deng
+ */
+public class TimeOfDay implements Serializable {
+
+ private static final long serialVersionUID = 2964774315889061771L;
+
+ private final int hour;
+ private final int minute;
+ private final int second;
+
+ /**
+ * Create a TimeOfDay instance for the given hour, minute and second.
+ *
+ * @param hour The hour of day, between 0 and 23.
+ * @param minute The minute of the hour, between 0 and 59.
+ * @param second The second of the minute, between 0 and 59.
+ * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+ */
+ public TimeOfDay(int hour, int minute, int second) {
+ this.hour = hour;
+ this.minute = minute;
+ this.second = second;
+ validate();
+ }
+
+ /**
+ * Create a TimeOfDay instance for the given hour and minute (at the zero second of the minute).
+ *
+ * @param hour The hour of day, between 0 and 23.
+ * @param minute The minute of the hour, between 0 and 59.
+ * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+ */
+ public TimeOfDay(int hour, int minute) {
+ this.hour = hour;
+ this.minute = minute;
+ this.second = 0;
+ validate();
+ }
+
+ private void validate() {
+ if(hour < 0 || hour > 23)
+ throw new IllegalArgumentException("Hour must be from 0 to 23");
+ if(minute < 0 || minute > 59)
+ throw new IllegalArgumentException("Minute must be from 0 to 59");
+ if(second < 0 || second > 59)
+ throw new IllegalArgumentException("Second must be from 0 to 59");
+ }
+
+ /**
+ * Create a TimeOfDay instance for the given hour, minute and second.
+ *
+ * @param hour The hour of day, between 0 and 23.
+ * @param minute The minute of the hour, between 0 and 59.
+ * @param second The second of the minute, between 0 and 59.
+ * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+ */
+ public static TimeOfDay hourMinuteAndSecondOfDay(int hour, int minute, int second) {
+ return new TimeOfDay(hour, minute, second);
+ }
+
+ /**
+ * Create a TimeOfDay instance for the given hour and minute (at the zero second of the minute).
+ *
+ * @param hour The hour of day, between 0 and 23.
+ * @param minute The minute of the hour, between 0 and 59.
+ * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+ */
+ public static TimeOfDay hourAndMinuteOfDay(int hour, int minute) {
+ return new TimeOfDay(hour, minute);
+ }
+
+ /**
+ * The hour of the day (between 0 and 23).
+ *
+ * @return The hour of the day (between 0 and 23).
+ */
+ public int getHour() {
+ return hour;
+ }
+
+ /**
+ * The minute of the hour.
+ *
+ * @return The minute of the hour (between 0 and 59).
+ */
+ public int getMinute() {
+ return minute;
+ }
+
+ /**
+ * The second of the minute.
+ *
+ * @return The second of the minute (between 0 and 59).
+ */
+ public int getSecond() {
+ return second;
+ }
+
+ /**
+ * Determine with this time of day is before the given time of day.
+ *
+ * @return true this time of day is before the given time of day.
+ */
+ public boolean before(TimeOfDay timeOfDay) {
+
+ if(timeOfDay.hour > hour)
+ return true;
+ if(timeOfDay.hour < hour)
+ return false;
+
+ if(timeOfDay.minute > minute)
+ return true;
+ if(timeOfDay.minute < minute)
+ return false;
+
+ if(timeOfDay.second > second)
+ return true;
+ if(timeOfDay.second < second)
+ return false;
+
+ return false; // must be equal...
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(!(obj instanceof TimeOfDay))
+ return false;
+
+ TimeOfDay other = (TimeOfDay)obj;
+
+ return (other.hour == hour && other.minute == minute && other.second == second);
+ }
+
+ @Override
+ public int hashCode() {
+ return (hour + 1) ^ (minute + 1) ^ (second + 1);
+ }
+
+ /** Return a date with time of day reset to this object values. The millisecond value will be zero. */
+ public Date getTimeOfDayForDate(Date dateTime) {
+ if (dateTime == null)
+ return null;
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dateTime);
+ cal.set(Calendar.HOUR_OF_DAY, hour);
+ cal.set(Calendar.MINUTE, minute);
+ cal.set(Calendar.SECOND, second);
+ cal.clear(Calendar.MILLISECOND);
+ return cal.getTime();
+ }
+
+ /**
+ * Create a TimeOfDay from the given date, in the system default TimeZone.
+ *
+ * @param dateTime The java.util.Date from which to extract Hour, Minute and Second.
+ */
+ public static TimeOfDay hourAndMinuteAndSecondFromDate(Date dateTime) {
+ return hourAndMinuteAndSecondFromDate(dateTime, null);
+ }
+
+ /**
+ * Create a TimeOfDay from the given date, in the given TimeZone.
+ *
+ * @param dateTime The java.util.Date from which to extract Hour, Minute and Second.
+ * @param tz The TimeZone from which relate Hour, Minute and Second for the given date. If null, system default
+ * TimeZone will be used.
+ */
+ public static TimeOfDay hourAndMinuteAndSecondFromDate(Date dateTime, TimeZone tz) {
+ if (dateTime == null)
+ return null;
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dateTime);
+ if(tz != null)
+ cal.setTimeZone(tz);
+
+ return new TimeOfDay(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
+ }
+
+ /**
+ * Create a TimeOfDay from the given date (at the zero-second), in the system default TimeZone.
+ *
+ * @param dateTime The java.util.Date from which to extract Hour and Minute.
+ */
+ public static TimeOfDay hourAndMinuteFromDate(Date dateTime) {
+ return hourAndMinuteFromDate(dateTime, null);
+ }
+
+ /**
+ * Create a TimeOfDay from the given date (at the zero-second), in the system default TimeZone.
+ *
+ * @param dateTime The java.util.Date from which to extract Hour and Minute.
+ * @param tz The TimeZone from which relate Hour and Minute for the given date. If null, system default
+ * TimeZone will be used.
+ */
+ public static TimeOfDay hourAndMinuteFromDate(Date dateTime, TimeZone tz) {
+ if (dateTime == null)
+ return null;
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dateTime);
+ if(tz != null)
+ cal.setTimeZone(tz);
+
+ return new TimeOfDay(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
+ }
+
+ @Override
+ public String toString() {
+ return "TimeOfDay[" + hour + ":" + minute + ":" + second + "]";
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/Trigger.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/Trigger.java (.../Trigger.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/Trigger.java (.../Trigger.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,126 +16,85 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
+import java.io.Serializable;
+import java.util.Comparator;
import java.util.Date;
-import java.util.LinkedList;
+
/**
- *
- * The base abstract class to be extended by all Triggers.
- *
+ * The base interface with properties common to all Triggers -
+ * use {@link TriggerBuilder} to instantiate an actual Trigger.
*
*
- * Triggers s have a name and group associated with them, which
+ * Triggerss have a {@link TriggerKey} 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,
+ * Triggers are the 'mechanism' by which Jobs
+ * are scheduled. Many Triggers 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 TriggerBuilder
* @see JobDataMap
* @see JobExecutionContext
+ * @see TriggerUtils
+ * @see SimpleTrigger
+ * @see CronTrigger
+ * @see CalendarIntervalTrigger
*
* @author James House
- * @author Sharada Jambula
*/
-public abstract class Trigger implements java.io.Serializable, Cloneable,
- Comparable {
+public interface Trigger extends Serializable, Cloneable, Comparable {
- private static final long serialVersionUID = -3904243490805975570L;
+ public static final long serialVersionUID = -3904243490805975570L;
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ public enum TriggerState { NONE, NORMAL, PAUSED, COMPLETE, ERROR, BLOCKED }
+
+ /**
+ * NOOP Instructs the {@link Scheduler} that the
+ * {@link Trigger} has no further instructions.
*
- * Constants.
+ * RE_EXECUTE_JOB 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
+ * ability to 'see' anything placed in the context by its last execution).
*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * SET_TRIGGER_COMPLETE Instructs the {@link Scheduler} that the
+ * {@link Trigger} should be put in the COMPLETE state.
+ *
+ * DELETE_TRIGGER Instructs the {@link Scheduler} that the
+ * {@link Trigger} wants itself deleted.
+ *
+ * SET_ALL_JOB_TRIGGERS_COMPLETE Instructs the {@link Scheduler}
+ * that all Triggers referencing the same {@link org.quartz.JobDetail}
+ * as this one should be put in the COMPLETE state.
+ *
+ * SET_TRIGGER_ERROR Instructs the {@link Scheduler} that all
+ * Triggers referencing the same {@link org.quartz.JobDetail} as
+ * this one should be put in the ERROR state.
+ *
+ * SET_ALL_JOB_TRIGGERS_ERROR Instructs the {@link Scheduler} that
+ * the Trigger should be put in the ERROR state.
*/
+ public enum CompletedExecutionInstruction { NOOP, RE_EXECUTE_JOB, SET_TRIGGER_COMPLETE, DELETE_TRIGGER,
+ SET_ALL_JOB_TRIGGERS_COMPLETE, SET_TRIGGER_ERROR, SET_ALL_JOB_TRIGGERS_ERROR }
/**
- *
- * 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.
- *
+ * on the Trigger to determine the mis-fire instruction,
+ * which logic will be trigger-implementation-dependent.
*
*
* In order to see if this instruction fits your needs, you should look at
@@ -144,788 +103,227 @@
*
*/
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.
- *
+ * Instructs the {@link Scheduler} that the
+ * Trigger will never be evaluated for a misfire situation,
+ * and that the scheduler will simply try to fire it as soon as it can,
+ * and then update the Trigger as if it had fired at the proper time.
*
- *
- * "Complete" indicates that the trigger has not remaining fire-times in
- * its schedule.
- *
+ * NOTE: if a trigger uses this instruction, and it has missed
+ * several of its scheduled firings, then several rapid firings may occur
+ * as the trigger attempt to catch back up to where it would have been.
+ * For example, a SimpleTrigger that fires every 15 seconds which has
+ * misfired for 5 minutes will fire 20 times once it gets the chance to
+ * fire.
*/
- public final static int STATE_COMPLETE = 2;
-
+ public static final int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;
+
/**
- *
- * 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.
- *
+ * The default value for priority.
*/
- public final static int STATE_ERROR = 3;
+ public static final int DEFAULT_PRIORITY = 5;
+ public TriggerKey getKey();
- /**
- *
- * 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;
+ public JobKey getJobKey();
- 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;
- }
+ public String getDescription();
/**
- *
- * 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;
- }
+ public String getCalendarName();
/**
- *
* 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;
- }
+ public JobDataMap getJobDataMap();
-
/**
- *
- * 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.
- *
+ * The priority of a Trigger acts as a tiebreaker such that if
+ * two Triggers have the same scheduled fire time, then the
+ * one with the higher priority will get first access to a worker
+ * thread.
*
*
- * If not explicitly set, the default value is false.
+ * If not explicitly set, the default value is 5.
*
*
- * @return true if the Trigger should be
- * garbage collected along with the {@link Scheduler}.
+ * @see #DEFAULT_PRIORITY
*/
- public boolean isVolatile() {
- return volatility;
- }
+ public int getPriority();
/**
- *
- * 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();
+ public boolean mayFireAgain();
/**
- *
* Get the time at which the Trigger should occur.
- *
*/
- public abstract Date getStartTime();
+ public 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.
- *
+ * regardless of any remaining repeats (based on the trigger's particular
+ * repeat settings).
*
* @see #getFinalFireTime()
*/
- public abstract Date getEndTime();
+ public 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
+ * Returns the next time at which the Trigger is scheduled to fire. If
+ * the trigger will not fire again, null will be returned. Note that
+ * the time returned can possibly be in the past, if the time that was computed
+ * for the trigger to next fire has already arrived, but the scheduler has not yet
+ * been able to fire the trigger (which would likely be due to lack of resources
+ * e.g. threads).
+ *
+ *
The value returned is not guaranteed to be valid until after the Trigger
* has been added to the scheduler.
*
+ *
+ * @see TriggerUtils#computeFireTimesBetween(org.quartz.spi.OperableTrigger, Calendar, java.util.Date, java.util.Date)
*/
- public abstract Date getNextFireTime();
+ public Date getNextFireTime();
/**
- *
- * Returns the previous time at which the Trigger will fire.
+ * Returns the previous time at which the Trigger fired.
* If the trigger has not yet fired, null will be returned.
*/
- public abstract Date getPreviousFireTime();
+ public 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);
+ public 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();
+ public 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.
- *
+ * constants that may be set as this property's value.
*
*
* 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;
- }
+ public int getMisfireInstruction();
/**
- *
- * This method should not be used by the Quartz client.
- *
+ * Get a {@link TriggerBuilder} that is configured to produce a
+ * Trigger identical to this one.
*
- *
- * 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.
- *
+ * @see #getScheduleBuilder()
*/
- public abstract void updateAfterMisfire(Calendar cal);
-
+ public TriggerBuilder extends Trigger> getTriggerBuilder();
+
/**
- *
- * This method should not be used by the Quartz client.
- *
+ * Get a {@link ScheduleBuilder} that is configured to produce a
+ * schedule identical to this trigger's schedule.
*
- *
- * 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
+ * @see #getTriggerBuilder()
*/
- public abstract void updateWithNewCalendar(Calendar cal, long misfireThreshold);
+ public ScheduleBuilder extends Trigger> getScheduleBuilder();
/**
- *
- * Validates whether the properties of the JobDetail are
- * valid for submission into a Scheduler.
+ * Trigger equality is based upon the equality of the TriggerKey.
*
- * @throws IllegalStateException
- * if a required property (such as Name, Group, Class) is not
- * set.
+ * @return true if the key of this Trigger equals that of the given Trigger.
*/
- 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);
- }
-
+ public boolean equals(Object other);
+
/**
*
- * This method should not be used by the Quartz client.
+ * Compare the next fire time of this Trigger to that of
+ * another by comparing their keys, or in other words, sorts them
+ * according to the natural (i.e. alphabetical) order of their keys.
*
- *
- *
- * 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;
- }
+ public int compareTo(Trigger other);
/**
- *
- * This method should not be used by the Quartz client.
- *
+ * A Comparator that compares trigger's next fire times, or in other words,
+ * sorts them according to earliest next fire time. If the fire times are
+ * the same, then the triggers are sorted according to priority (highest
+ * value first), if the priorities are the same, then they are sorted
+ * by key.
*/
- public String getFireInstanceId() {
- return fireInstanceId;
- }
+ class TriggerTimeComparator implements Comparator, Serializable {
+
+ private static final long serialVersionUID = -3904243490805975570L;
+
+ // This static method exists for comparator in TC clustered quartz
+ public static int compare(Date nextFireTime1, int priority1, TriggerKey key1, Date nextFireTime2, int priority2, TriggerKey key2) {
+ if (nextFireTime1 != null || nextFireTime2 != null) {
+ if (nextFireTime1 == null) {
+ return 1;
+ }
- /**
- *
- * 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();
- }
+ if (nextFireTime2 == null) {
+ return -1;
+ }
- /**
- *
- * Compare the next fire time of this Trigger to that of
- * another.
- *
- */
- public int compareTo(Object obj) {
- Trigger other = (Trigger) obj;
+ if(nextFireTime1.before(nextFireTime2)) {
+ return -1;
+ }
- Date myTime = getNextFireTime();
- Date otherTime = other.getNextFireTime();
+ if(nextFireTime1.after(nextFireTime2)) {
+ return 1;
+ }
+ }
- if (myTime == null && otherTime == null) return 0;
+ int comp = priority2 - priority1;
+ if (comp != 0) {
+ return comp;
+ }
- if (myTime == null) return 1;
+ return key1.compareTo(key2);
+ }
- 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.");
+ public int compare(Trigger t1, Trigger t2) {
+ return compare(t1.getNextFireTime(), t1.getPriority(), t1.getKey(), t2.getNextFireTime(), t2.getPriority(), t2.getKey());
}
- return copy;
}
-
}
Index: 3rdParty_sources/quartz/org/quartz/TriggerBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/TriggerBuilder.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/TriggerBuilder.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,416 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import java.util.Date;
+
+import org.quartz.spi.MutableTrigger;
+import org.quartz.utils.Key;
+
+/**
+ * TriggerBuilder is used to instantiate {@link Trigger}s.
+ *
+ * The builder will always try to keep itself in a valid state, with
+ * reasonable defaults set for calling build() at any point. For instance
+ * if you do not invoke withSchedule(..) method, a default schedule
+ * of firing once immediately will be used. As another example, if you
+ * do not invoked withIdentity(..) a trigger name will be generated
+ * for you.
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(simpleSchedule()
+ * .withIntervalInHours(1)
+ * .repeatForever())
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ * @see JobBuilder
+ * @see ScheduleBuilder
+ * @see DateBuilder
+ * @see Trigger
+ */
+public class TriggerBuilder {
+
+ private TriggerKey key;
+ private String description;
+ private Date startTime = new Date();
+ private Date endTime;
+ private int priority = Trigger.DEFAULT_PRIORITY;
+ private String calendarName;
+ private JobKey jobKey;
+ private JobDataMap jobDataMap = new JobDataMap();
+
+ private ScheduleBuilder> scheduleBuilder = null;
+
+ private TriggerBuilder() {
+
+ }
+
+ /**
+ * Create a new TriggerBuilder with which to define a
+ * specification for a Trigger.
+ *
+ * @return the new TriggerBuilder
+ */
+ public static TriggerBuilder newTrigger() {
+ return new TriggerBuilder();
+ }
+
+ /**
+ * Produce the Trigger.
+ *
+ * @return a Trigger that meets the specifications of the builder.
+ */
+ @SuppressWarnings("unchecked")
+ public T build() {
+
+ if(scheduleBuilder == null)
+ scheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
+ MutableTrigger trig = scheduleBuilder.build();
+
+ trig.setCalendarName(calendarName);
+ trig.setDescription(description);
+ trig.setStartTime(startTime);
+ trig.setEndTime(endTime);
+ if(key == null)
+ key = new TriggerKey(Key.createUniqueName(null), null);
+ trig.setKey(key);
+ if(jobKey != null)
+ trig.setJobKey(jobKey);
+ trig.setPriority(priority);
+
+ if(!jobDataMap.isEmpty())
+ trig.setJobDataMap(jobDataMap);
+
+ return (T) trig;
+ }
+
+ /**
+ * Use a TriggerKey with the given name and default group to
+ * identify the Trigger.
+ *
+ * If none of the 'withIdentity' methods are set on the TriggerBuilder,
+ * then a random, unique TriggerKey will be generated.
+ *
+ * @param name the name element for the Trigger's TriggerKey
+ * @return the updated TriggerBuilder
+ * @see TriggerKey
+ * @see Trigger#getKey()
+ */
+ public TriggerBuilder withIdentity(String name) {
+ key = new TriggerKey(name, null);
+ return this;
+ }
+
+ /**
+ * Use a TriggerKey with the given name and group to
+ * identify the Trigger.
+ *
+ * If none of the 'withIdentity' methods are set on the TriggerBuilder,
+ * then a random, unique TriggerKey will be generated.
+ *
+ * @param name the name element for the Trigger's TriggerKey
+ * @param group the group element for the Trigger's TriggerKey
+ * @return the updated TriggerBuilder
+ * @see TriggerKey
+ * @see Trigger#getKey()
+ */
+ public TriggerBuilder withIdentity(String name, String group) {
+ key = new TriggerKey(name, group);
+ return this;
+ }
+
+ /**
+ * Use the given TriggerKey to identify the Trigger.
+ *
+ * If none of the 'withIdentity' methods are set on the TriggerBuilder,
+ * then a random, unique TriggerKey will be generated.
+ *
+ * @param triggerKey the TriggerKey for the Trigger to be built
+ * @return the updated TriggerBuilder
+ * @see TriggerKey
+ * @see Trigger#getKey()
+ */
+ public TriggerBuilder withIdentity(TriggerKey triggerKey) {
+ this.key = triggerKey;
+ return this;
+ }
+
+ /**
+ * Set the given (human-meaningful) description of the Trigger.
+ *
+ * @param triggerDescription the description for the Trigger
+ * @return the updated TriggerBuilder
+ * @see Trigger#getDescription()
+ */
+ public TriggerBuilder withDescription(String triggerDescription) {
+ this.description = triggerDescription;
+ return this;
+ }
+
+ /**
+ * Set the Trigger's priority. When more than one Trigger have the same
+ * fire time, the scheduler will fire the one with the highest priority
+ * first.
+ *
+ * @param triggerPriority the priority for the Trigger
+ * @return the updated TriggerBuilder
+ * @see Trigger#DEFAULT_PRIORITY
+ * @see Trigger#getPriority()
+ */
+ public TriggerBuilder withPriority(int triggerPriority) {
+ this.priority = triggerPriority;
+ return this;
+ }
+
+ /**
+ * Set the name of the {@link Calendar} that should be applied to this
+ * Trigger's schedule.
+ *
+ * @param calName the name of the Calendar to reference.
+ * @return the updated TriggerBuilder
+ * @see Calendar
+ * @see Trigger#getCalendarName()
+ */
+ public TriggerBuilder modifiedByCalendar(String calName) {
+ this.calendarName = calName;
+ return this;
+ }
+
+ /**
+ * Set the time the Trigger should start at - the trigger may or may
+ * not fire at this time - depending upon the schedule configured for
+ * the Trigger. However the Trigger will NOT fire before this time,
+ * regardless of the Trigger's schedule.
+ *
+ * @param triggerStartTime the start time for the Trigger.
+ * @return the updated TriggerBuilder
+ * @see Trigger#getStartTime()
+ * @see DateBuilder
+ */
+ public TriggerBuilder startAt(Date triggerStartTime) {
+ this.startTime = triggerStartTime;
+ return this;
+ }
+
+ /**
+ * Set the time the Trigger should start at to the current moment -
+ * the trigger may or may not fire at this time - depending upon the
+ * schedule configured for the Trigger.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getStartTime()
+ */
+ public TriggerBuilder startNow() {
+ this.startTime = new Date();
+ return this;
+ }
+
+ /**
+ * Set the time at which the Trigger will no longer fire - even if it's
+ * schedule has remaining repeats.
+ *
+ * @param triggerEndTime the end time for the Trigger. If null, the end time is indefinite.
+ * @return the updated TriggerBuilder
+ * @see Trigger#getEndTime()
+ * @see DateBuilder
+ */
+ public TriggerBuilder endAt(Date triggerEndTime) {
+ this.endTime = triggerEndTime;
+ return this;
+ }
+
+ /**
+ * Set the {@link ScheduleBuilder} that will be used to define the
+ * Trigger's schedule.
+ *
+ * The particular SchedulerBuilder used will dictate
+ * the concrete type of Trigger that is produced by the TriggerBuilder.
+ *
+ * @param schedBuilder the SchedulerBuilder to use.
+ * @return the updated TriggerBuilder
+ * @see ScheduleBuilder
+ * @see SimpleScheduleBuilder
+ * @see CronScheduleBuilder
+ * @see CalendarIntervalScheduleBuilder
+ */
+ @SuppressWarnings("unchecked")
+ public TriggerBuilder withSchedule(ScheduleBuilder schedBuilder) {
+ this.scheduleBuilder = schedBuilder;
+ return (TriggerBuilder) this;
+ }
+
+ /**
+ * Set the identity of the Job which should be fired by the produced
+ * Trigger.
+ *
+ * @param keyOfJobToFire the identity of the Job to fire.
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobKey()
+ */
+ public TriggerBuilder forJob(JobKey keyOfJobToFire) {
+ this.jobKey = keyOfJobToFire;
+ return this;
+ }
+
+ /**
+ * Set the identity of the Job which should be fired by the produced
+ * Trigger - a JobKey will be produced with the given
+ * name and default group.
+ *
+ * @param jobName the name of the job (in default group) to fire.
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobKey()
+ */
+ public TriggerBuilder forJob(String jobName) {
+ this.jobKey = new JobKey(jobName, null);
+ return this;
+ }
+
+ /**
+ * Set the identity of the Job which should be fired by the produced
+ * Trigger - a JobKey will be produced with the given
+ * name and group.
+ *
+ * @param jobName the name of the job to fire.
+ * @param jobGroup the group of the job to fire.
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobKey()
+ */
+ public TriggerBuilder forJob(String jobName, String jobGroup) {
+ this.jobKey = new JobKey(jobName, jobGroup);
+ return this;
+ }
+
+ /**
+ * Set the identity of the Job which should be fired by the produced
+ * Trigger, by extracting the JobKey from the given job.
+ *
+ * @param jobDetail the Job to fire.
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobKey()
+ */
+ public TriggerBuilder forJob(JobDetail jobDetail) {
+ JobKey k = jobDetail.getKey();
+ if(k.getName() == null)
+ throw new IllegalArgumentException("The given job has not yet had a name assigned to it.");
+ this.jobKey = k;
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the Trigger's {@link JobDataMap}.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(String dataKey, String value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the Trigger's {@link JobDataMap}.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(String dataKey, Integer value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the Trigger's {@link JobDataMap}.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(String dataKey, Long value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the Trigger's {@link JobDataMap}.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(String dataKey, Float value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the Trigger's {@link JobDataMap}.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(String dataKey, Double value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Add the given key-value pair to the Trigger's {@link JobDataMap}.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(String dataKey, Boolean value) {
+ jobDataMap.put(dataKey, value);
+ return this;
+ }
+
+ /**
+ * Set the Trigger's {@link JobDataMap}, adding any values to it
+ * that were already set on this TriggerBuilder using any of the
+ * other 'usingJobData' methods.
+ *
+ * @return the updated TriggerBuilder
+ * @see Trigger#getJobDataMap()
+ */
+ public TriggerBuilder usingJobData(JobDataMap newJobDataMap) {
+ // add any existing data to this new map
+ for(String dataKey: jobDataMap.keySet()) {
+ newJobDataMap.put(dataKey, jobDataMap.get(dataKey));
+ }
+ jobDataMap = newJobDataMap; // set new map as the map to use
+ return this;
+ }
+
+}
Index: 3rdParty_sources/quartz/org/quartz/TriggerKey.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/TriggerKey.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/TriggerKey.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,78 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package org.quartz;
+
+import org.quartz.utils.Key;
+
+/**
+ * Uniquely identifies a {@link Trigger}.
+ *
+ * Keys are composed of both a name and group, and the name must be unique
+ * within the group. If only a name is specified then the default group
+ * name will be used.
+ *
+ *
+ * Quartz provides a builder-style API for constructing scheduling-related
+ * entities via a Domain-Specific Language (DSL). The DSL can best be
+ * utilized through the usage of static imports of the methods on the classes
+ * TriggerBuilder, JobBuilder,
+ * DateBuilder, JobKey, TriggerKey
+ * and the various ScheduleBuilder implementations.
+ *
+ * Client code can then use the DSL to write code such as this:
+ *
+ * JobDetail job = newJob(MyJob.class)
+ * .withIdentity("myJob")
+ * .build();
+ *
+ * Trigger trigger = newTrigger()
+ * .withIdentity(triggerKey("myTrigger", "myTriggerGroup"))
+ * .withSchedule(simpleSchedule()
+ * .withIntervalInHours(1)
+ * .repeatForever())
+ * .startAt(futureDate(10, MINUTES))
+ * .build();
+ *
+ * scheduler.scheduleJob(job, trigger);
+ *
+ *
+ *
+ * @see Trigger
+ * @see Key#DEFAULT_GROUP
+ */
+public final class TriggerKey extends Key {
+
+ private static final long serialVersionUID = 8070357886703449660L;
+
+ public TriggerKey(String name) {
+ super(name, null);
+ }
+
+ public TriggerKey(String name, String group) {
+ super(name, group);
+ }
+
+ public static TriggerKey triggerKey(String name) {
+ return new TriggerKey(name, null);
+ }
+
+ public static TriggerKey triggerKey(String name, String group) {
+ return new TriggerKey(name, group);
+ }
+
+}
Index: 3rdParty_sources/quartz/org/quartz/TriggerListener.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/TriggerListener.java (.../TriggerListener.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/TriggerListener.java (.../TriggerListener.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,19 +16,17 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
+import org.quartz.Trigger.CompletedExecutionInstruction;
+
/**
- *
* The interface to be implemented by classes that want to be informed when a
* {@link Trigger} fires. In general, applications that use a
* Scheduler will not have use for this mechanism.
- *
*
- * @see Scheduler
+ * @see ListenerManager#addTriggerListener(TriggerListener, Matcher)
+ * @see Matcher
* @see Trigger
* @see JobListener
* @see JobExecutionContext
@@ -50,7 +48,7 @@
* Get the name of the TriggerListener.
*
*/
- public String getName();
+ String getName();
/**
*
@@ -70,13 +68,14 @@
* The JobExecutionContext that will be passed to
* the Job'sexecute(xx) method.
*/
- public void triggerFired(Trigger trigger, JobExecutionContext context);
+ void triggerFired(Trigger trigger, JobExecutionContext context);
/**
*
* Called by the {@link Scheduler} when a {@link Trigger}
* has fired, and it's associated {@link org.quartz.JobDetail}
- * is about to be executed.
+ * is about to be executed. If the implementation vetos the execution (via
+ * returning true), the job's execute method will not be called.
*
*
*
@@ -90,7 +89,7 @@
* The JobExecutionContext that will be passed to
* the Job'sexecute(xx) method.
*/
- public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context);
+ boolean vetoJobExecution(Trigger trigger, JobExecutionContext context);
/**
@@ -109,7 +108,7 @@
* @param trigger
* The Trigger that has misfired.
*/
- public void triggerMisfired(Trigger trigger);
+ void triggerMisfired(Trigger trigger);
/**
*
@@ -124,11 +123,11 @@
* @param context
* The JobExecutionContext that was passed to the
* Job'sexecute(xx) method.
- * @param triggerIntructionCode
+ * @param triggerInstructionCode
* the result of the call on the Trigger'striggered(xx)
* method.
*/
- public void triggerComplete(Trigger trigger, JobExecutionContext context,
- int triggerInstructionCode);
+ void triggerComplete(Trigger trigger, JobExecutionContext context,
+ CompletedExecutionInstruction triggerInstructionCode);
}
Index: 3rdParty_sources/quartz/org/quartz/TriggerUtils.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/TriggerUtils.java (.../TriggerUtils.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/TriggerUtils.java (.../TriggerUtils.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,31 +16,21 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz;
-import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
-import java.util.TimeZone;
+import org.quartz.spi.OperableTrigger;
+
/**
- *
- * Convenience and utility methods for simplifying the construction and
- * configuration of {@link Trigger}s.
- *
+ * Convenience and utility methods for working with {@link Trigger}s.
*
- *
- * Please submit suggestions for additional convenience methods to either the
- * Quartz user forum or the developer's mail list at
- * source forge.
- *
*
* @see CronTrigger
* @see SimpleTrigger
+ * @see DateBuilder
*
* @author James House
*/
@@ -54,30 +44,12 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
- public static final int SUNDAY = 1;
-
- public static final int MONDAY = 2;
-
- public static final int TUESDAY = 3;
-
- public static final int WEDNESDAY = 4;
-
- public static final int THURSDAY = 5;
-
- public static final int FRIDAY = 6;
-
- public static final int SATURDAY = 7;
-
- public static final int LAST_DAY_OF_MONTH = -1;
-
- public static final long MILLISECONDS_IN_MINUTE = 60l * 1000l;
-
- public static final long MILLISECONDS_IN_HOUR = 60l * 60l * 1000l;
-
- public static final long SECONDS_IN_DAY = 24l * 60l * 60L;
-
- public static final long MILLISECONDS_IN_DAY = SECONDS_IN_DAY * 1000l;
-
+ /**
+ * Private constructor because this is a pure utility class.
+ */
+ private TriggerUtils() {
+ }
+
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -86,1134 +58,48 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
- private static void validateDayOfWeek(int dayOfWeek) {
- if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY)
- throw new IllegalArgumentException("Invalid day of week.");
- }
-
- private static void validateHour(int hour) {
- if (hour < 0 || hour > 23)
- throw new IllegalArgumentException(
- "Invalid hour (must be >= 0 and <= 23).");
- }
-
- private static void validateMinute(int minute) {
- if (minute < 0 || minute > 59)
- throw new IllegalArgumentException(
- "Invalid minute (must be >= 0 and <= 59).");
- }
-
- private static void validateSecond(int second) {
- if (second < 0 || second > 59)
- throw new IllegalArgumentException(
- "Invalid second (must be >= 0 and <= 59).");
- }
-
- private static void validateDayOfMonth(int day) {
- if ((day < 1 || day > 31) && day != LAST_DAY_OF_MONTH)
- throw new IllegalArgumentException("Invalid day of month.");
- }
-
- private static void validateMonth(int month) {
- if (month < 1 || month > 12)
- throw new IllegalArgumentException(
- "Invalid month (must be >= 1 and <= 12.");
- }
-
- private static void validateYear(int year) {
- if (year < 1970 || year > 2099)
- throw new IllegalArgumentException(
- "Invalid year (must be >= 1970 and <= 2099.");
- }
-
/**
- *
- * Set the given Trigger's name to the given value, and its
- * group to the default group (Scheduler.DEFAULT_GROUP).
- *
+ * Returns a list of Dates that are the next fire times of a
+ * Trigger.
+ * The input trigger will be cloned before any work is done, so you need
+ * not worry about its state being altered by this method.
*
- * @param trig the tigger to change name to
- * @param name the new trigger name
+ * @param trigg
+ * The trigger upon which to do the work
+ * @param cal
+ * The calendar to apply to the trigger's schedule
+ * @param numTimes
+ * The number of next fire times to produce
+ * @return List of java.util.Date objects
*/
- public static void setTriggerIdentity(Trigger trig, String name) {
- setTriggerIdentity(trig, name, Scheduler.DEFAULT_GROUP);
- }
+ public static List computeFireTimes(OperableTrigger trigg, org.quartz.Calendar cal,
+ int numTimes) {
+ LinkedList lst = new LinkedList();
- /**
- *
- * Set the given Trigger's name to the given value, and its
- * group to the given group.
- *
- *
- * @param trig the tigger to change name to
- * @param name the new trigger name
- * @param group the new trigger group
- */
- public static void setTriggerIdentity(
- Trigger trig, String name, String group) {
- trig.setName(name);
- trig.setGroup(group);
- }
+ OperableTrigger t = (OperableTrigger) trigg.clone();
- /**
- *
- * Make a trigger that will fire every day at the given time.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param hour the hour (0-23) upon which to fire
- * @param minute the minute (0-59) upon which to fire
- * @return the new trigger
- */
- public static Trigger makeDailyTrigger(int hour, int minute) {
- validateHour(hour);
- validateMinute(minute);
-
- CronTrigger trig = new CronTrigger();
-
- try {
- trig.setCronExpression("0 " + minute + " " + hour + " ? * *");
- } catch (Exception ignore) {
- return null; /* never happens... */
+ if (t.getNextFireTime() == null) {
+ t.computeFirstFireTime(cal);
}
- trig.setStartTime(new Date());
-
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every day at the given time.
- *
- *
- *
- * The generated trigger will not have its group or end-time set.
- * The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @param hour the hour (0-23) upon which to fire
- * @param minute the minute (0-59) upon which to fire
- * @return the newly created trigger
- */
- public static Trigger makeDailyTrigger(
- String trigName, int hour, int minute) {
- Trigger trig = makeDailyTrigger(hour, minute);
- trig.setName(trigName);
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every week at the given day and time.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param dayOfWeek (1-7) the day of week upon which to fire
- * @param hour the hour (0-23) upon which to fire
- * @param minute the minute (0-59) upon which to fire
- * @return the new trigger
- *
- * @see #SUNDAY
- * @see #MONDAY
- * @see #TUESDAY
- * @see #WEDNESDAY
- * @see #THURSDAY
- * @see #FRIDAY
- * @see #SATURDAY
- */
- public static Trigger makeWeeklyTrigger(
- int dayOfWeek, int hour, int minute) {
- validateDayOfWeek(dayOfWeek);
- validateHour(hour);
- validateMinute(minute);
-
- CronTrigger trig = new CronTrigger();
-
- try {
- trig.setCronExpression("0 " + minute + " " + hour + " ? * "
- + dayOfWeek);
- } catch (Exception ignore) {
- return null; /* never happens... */
+ for (int i = 0; i < numTimes; i++) {
+ Date d = t.getNextFireTime();
+ if (d != null) {
+ lst.add(d);
+ t.triggered(cal);
+ } else {
+ break;
+ }
}
-
- trig.setStartTime(new Date());
- return trig;
+ return java.util.Collections.unmodifiableList(lst);
}
-
- /**
- *
- * Make a trigger that will fire every week at the given day and time.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @param dayOfWeek (1-7) the day of week upon which to fire
- * @param hour the hour (0-23) upon which to fire
- * @param minute the minute (0-59) upon which to fire
- * @return the newly created trigger
- *
- * @see #SUNDAY
- * @see #MONDAY
- * @see #TUESDAY
- * @see #WEDNESDAY
- * @see #THURSDAY
- * @see #FRIDAY
- * @see #SATURDAY
- */
- public static Trigger makeWeeklyTrigger(
- String trigName, int dayOfWeek, int hour, int minute) {
- Trigger trig = makeWeeklyTrigger(dayOfWeek, hour, minute);
- trig.setName(trigName);
- return trig;
- }
-
/**
- *
- * Make a trigger that will fire every month at the given day and time.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- *
- * If the day of the month specified does not occur in a given month, a
- * firing will not occur that month. (i.e. if dayOfMonth is specified as
- * 31, no firing will occur in the months of the year with fewer than 31
- * days).
- *
- *
- * @param dayOfMonth (1-31, or -1) the day of week upon which to fire
- * @param hour the hour (0-23) upon which to fire
- * @param minute the minute (0-59) upon which to fire
- * @return the newly created trigger
- */
- public static Trigger makeMonthlyTrigger(
- int dayOfMonth, int hour, int minute) {
- validateDayOfMonth(dayOfMonth);
- validateHour(hour);
- validateMinute(minute);
-
- CronTrigger trig = new CronTrigger();
-
- try {
- if (dayOfMonth != LAST_DAY_OF_MONTH) trig.setCronExpression("0 "
- + minute + " " + hour + " " + dayOfMonth + " * ?");
- else
- trig.setCronExpression("0 " + minute + " " + hour + " L * ?");
- } catch (Exception ignore) {
- return null; /* never happens... */
- }
-
- trig.setStartTime(new Date());
-
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every month at the given day and time.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- *
- * If the day of the month specified does not occur in a given month, a
- * firing will not occur that month. (i.e. if dayOfMonth is specified as
- * 31, no firing will occur in the months of the year with fewer than 31
- * days).
- *
- *
- * @param trigName the trigger's name
- * @param dayOfMonth (1-31, or -1) the day of week upon which to fire
- * @param hour the hour (0-23) upon which to fire
- * @param minute the minute (0-59) upon which to fire
- * @return the newly created trigger
- */
- public static Trigger makeMonthlyTrigger(
- String trigName, int dayOfMonth, int hour, int minute) {
- Trigger trig = makeMonthlyTrigger(dayOfMonth, hour, minute);
- trig.setName(trigName);
- return trig;
- }
-
- /*
- * Make a trigger that will fire every N days at the given time.
- *
- * TThe generated trigger will not have its name, group,
- * start-time and end-time set.
- *
- * @param hour the hour (0-23) upon which to fire @param minute the minute
- * (0-59) upon which to fire @param interval the number of days between
- * firings public static Trigger makeDailyTrigger(int interval, int hour,
- * int minute) {
- *
- * SimpleTrigger trig = new SimpleTrigger();
- *
- * MILLISECONDS_IN_DAY);
- * trig.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
- *
- * return trig;
- * }
- */
-
- /**
- *
- * Make a trigger that will fire repeatCount times, waiting
- * repeatInterval milliseconds between each fire.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
+ * Compute the Date that is 1 second after the Nth firing of
+ * the given Trigger, taking the triger's associated
+ * Calendar into consideration.
*
- * @param repeatCount the number of times to fire the trigger
- * @param repeatInterval the number of milliseconds to wait between fires
- * @return the newly created trigger
- */
- public static Trigger makeImmediateTrigger(
- int repeatCount, long repeatInterval) {
- SimpleTrigger trig = new SimpleTrigger();
- trig.setStartTime( new Date() );
- trig.setRepeatCount(repeatCount);
- trig.setRepeatInterval(repeatInterval);
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire repeatCount times, waiting
- * repeatInterval milliseconds between each fire.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @param repeatCount the number of times to fire the trigger
- * @param repeatInterval the number of milliseconds to wait between fires
- * @return the new trigger
- */
- public static Trigger makeImmediateTrigger(
- String trigName, int repeatCount, long repeatInterval) {
- Trigger trig = makeImmediateTrigger(repeatCount, repeatInterval);
- trig.setName(trigName);
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every second, indefinitely.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- * @return the new trigger
- */
- public static Trigger makeSecondlyTrigger() {
- return makeSecondlyTrigger(1, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every second, indefinitely.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @return the new trigger
- */
- public static Trigger makeSecondlyTrigger(String trigName) {
- return makeSecondlyTrigger(
- trigName, 1, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
-
- /**
- *
- * Make a trigger that will fire every N seconds, indefinitely.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param intervalInSeconds the number of seconds between firings
- * @return the new trigger
- */
- public static Trigger makeSecondlyTrigger(int intervalInSeconds) {
- return makeSecondlyTrigger(
- intervalInSeconds, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every N seconds, with the given number of
- * repeats.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param intervalInSeconds the number of seconds between firings
- * @param repeatCount the number of times to repeat the firing
- * @return the new trigger
- */
- public static Trigger makeSecondlyTrigger(
- int intervalInSeconds, int repeatCount) {
- SimpleTrigger trig = new SimpleTrigger();
-
- trig.setRepeatInterval(intervalInSeconds * 1000l);
- trig.setRepeatCount(repeatCount);
-
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every N seconds, with the given number of
- * repeats.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @param intervalInSeconds the number of seconds between firings
- * @param repeatCount the number of times to repeat the firing
- * @return the new trigger
- */
- public static Trigger makeSecondlyTrigger(
- String trigName, int intervalInSeconds, int repeatCount) {
- Trigger trig = makeSecondlyTrigger(intervalInSeconds, repeatCount);
- trig.setName(trigName);
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every minute, indefinitely.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @return the new trigger
- */
- public static Trigger makeMinutelyTrigger() {
- return makeMinutelyTrigger(1, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every minute, indefinitely.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @return the new trigger
- */
- public static Trigger makeMinutelyTrigger(String trigName) {
- return makeMinutelyTrigger(
- trigName, 1, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every N minutes, indefinitely.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param intervalInMinutes the number of minutes between firings
- * @return the new trigger
- */
- public static Trigger makeMinutelyTrigger(int intervalInMinutes) {
- return makeMinutelyTrigger(
- intervalInMinutes, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every N minutes, with the given number of
- * repeats.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param intervalInMinutes the number of minutes between firings
- * @param repeatCount the number of times to repeat the firing
- * @return the new trigger
- */
- public static Trigger makeMinutelyTrigger(
- int intervalInMinutes, int repeatCount) {
- SimpleTrigger trig = new SimpleTrigger();
-
- trig.setRepeatInterval(intervalInMinutes * MILLISECONDS_IN_MINUTE);
- trig.setRepeatCount(repeatCount);
-
- trig.setStartTime(new Date());
-
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every N minutes, with the given number of
- * repeats.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @param intervalInMinutes the number of minutes between firings
- * @param repeatCount the number of times to repeat the firing
- * @return the new trigger
- */
- public static Trigger makeMinutelyTrigger(
- String trigName, int intervalInMinutes, int repeatCount) {
- Trigger trig = makeMinutelyTrigger(intervalInMinutes, repeatCount);
- trig.setName(trigName);
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every hour, indefinitely.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @return the new trigger
- */
- public static Trigger makeHourlyTrigger() {
- return makeHourlyTrigger(1, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every hour, indefinitely.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @return the new trigger
- */
- public static Trigger makeHourlyTrigger(String trigName) {
- return makeHourlyTrigger(
- trigName, 1, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every N hours, indefinitely.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param intervalInHours the number of hours between firings
- * @return the new trigger
- */
- public static Trigger makeHourlyTrigger(int intervalInHours) {
- return makeHourlyTrigger(
- intervalInHours, SimpleTrigger.REPEAT_INDEFINITELY);
- }
-
- /**
- *
- * Make a trigger that will fire every N hours, with the given number of
- * repeats.
- *
- *
- *
- * The generated trigger will not have its name, group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param intervalInHours the number of hours between firings
- * @param repeatCount the number of times to repeat the firing
- * @return the new trigger
- */
- public static Trigger makeHourlyTrigger(
- int intervalInHours, int repeatCount) {
- SimpleTrigger trig = new SimpleTrigger();
-
- trig.setRepeatInterval(intervalInHours * MILLISECONDS_IN_HOUR);
- trig.setRepeatCount(repeatCount);
-
- trig.setStartTime(new Date());
-
- return trig;
- }
-
- /**
- *
- * Make a trigger that will fire every N hours, with the given number of
- * repeats.
- *
- *
- *
- * The generated trigger will not have its group,
- * or end-time set. The Start time defaults to 'now'.
- *
- *
- * @param trigName the trigger's name
- * @param intervalInHours the number of hours between firings
- * @param repeatCount the number of times to repeat the firing
- * @return the new trigger
- */
- public static Trigger makeHourlyTrigger(
- String trigName, int intervalInHours, int repeatCount) {
- Trigger trig =makeHourlyTrigger(intervalInHours, repeatCount);
- trig.setName(trigName);
- return trig;
- }
-
- /**
- *
- * Returns a date that is rounded to the next even hour above the given
- * date.
- *
- *
- *
- * For example an input date with a time of 08:13:54 would result in a date
- * with the time of 09:00:00. If the date's time is in the 23rd hour, the
- * date's 'day' will be promoted, and the time will be set to 00:00:00.
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @return the new rounded date
- */
- public static Date getEvenHourDate(Date date) {
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- c.setLenient(true);
-
- c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + 1);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Returns a date that is rounded to the previous even hour below the given
- * date.
- *
- *
- *
- * For example an input date with a time of 08:13:54 would result in a date
- * with the time of 08:00:00.
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @return the new rounded date
- */
- public static Date getEvenHourDateBefore(Date date) {
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
-
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Returns a date that is rounded to the next even minute above the given
- * date.
- *
- *
- *
- * For example an input date with a time of 08:13:54 would result in a date
- * with the time of 08:14:00. If the date's time is in the 59th minute,
- * then the hour (and possibly the day) will be promoted.
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @return the new rounded date
- */
- public static Date getEvenMinuteDate(Date date) {
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- c.setLenient(true);
-
- c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 1);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Returns a date that is rounded to the previous even minute below the
- * given date.
- *
- *
- *
- * For example an input date with a time of 08:13:54 would result in a date
- * with the time of 08:13:00.
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @return the new rounded date
- */
- public static Date getEvenMinuteDateBefore(Date date) {
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
-
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Returns a date that is rounded to the next even second above the given
- * date.
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @return the new rounded date
- */
- public static Date getEvenSecondDate(Date date) {
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- c.setLenient(true);
-
- c.set(Calendar.SECOND, c.get(Calendar.SECOND) + 1);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Returns a date that is rounded to the previous even second below the
- * given date.
- *
- *
- *
- * For example an input date with a time of 08:13:54.341 would result in a
- * date with the time of 08:13:00.000.
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @return the new rounded date
- */
- public static Date getEvenSecondDateBefore(Date date) {
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
-
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Returns a date that is rounded to the next even multiple of the given
- * minute.
- *
- *
- *
- * For example an input date with a time of 08:13:54, and an input
- * minute-base of 5 would result in a date with the time of 08:15:00. The
- * same input date with an input minute-base of 10 would result in a date
- * with the time of 08:20:00. But a date with the time 08:53:31 and an
- * input minute-base of 45 would result in 09:00:00, because the even-hour
- * is the next 'base' for 45-minute intervals.
- *
- *
- *
- * More examples:
- *
- * Input Time
- * Minute-Base
- * Result Time
- *
- *
- * 11:16:41
- * 20
- * 11:20:00
- *
- *
- * 11:36:41
- * 20
- * 11:40:00
- *
- *
- * 11:46:41
- * 20
- * 12:00:00
- *
- *
- * 11:26:41
- * 30
- * 11:30:00
- *
- *
- * 11:36:41
- * 30
- * 12:00:00
- *
- * 11:16:41
- * 17
- * 11:17:00
- *
- *
- * 11:17:41
- * 17
- * 11:34:00
- *
- *
- * 11:52:41
- * 17
- * 12:00:00
- *
- *
- * 11:52:41
- * 5
- * 11:55:00
- *
- *
- * 11:57:41
- * 5
- * 12:00:00
- *
- *
- * 11:17:41
- * 0
- * 12:00:00
- *
- *
- * 11:17:41
- * 1
- * 11:08:00
- *
- *
- *
- *
- * @param date
- * the Date to round, if null the current time will
- * be used
- * @param minuteBase
- * the base-minute to set the time on
- * @return the new rounded date
- *
- * @see #getNextGivenSecondDate(Date, int)
- */
- public static Date getNextGivenMinuteDate(Date date, int minuteBase) {
- if (minuteBase < 0 || minuteBase > 59)
- throw new IllegalArgumentException(
- "minuteBase must be >=0 and <= 59");
-
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- c.setLenient(true);
-
- if (minuteBase == 0) {
- c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + 1);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- int minute = c.get(Calendar.MINUTE);
-
- int arItr = minute / minuteBase;
-
- int nextMinuteOccurance = minuteBase * (arItr + 1);
-
- if (nextMinuteOccurance < 60) {
- c.set(Calendar.MINUTE, nextMinuteOccurance);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- } else {
- c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + 1);
- c.set(Calendar.MINUTE, 0);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
- }
-
- /**
- *
- * Returns a date that is rounded to the next even multiple of the given
- * minute.
- *
- *
- *
- * The rules for calculating the second are the same as those for
- * calculating the minute in the method
- * getNextGivenMinuteDate(..).
- *
- *
- * @param date the Date to round, if null the current time will
- * be used
- * @param secondBase the base-second to set the time on
- * @return the new rounded date
- *
- * @see #getNextGivenMinuteDate(Date, int)
- */
- public static Date getNextGivenSecondDate(Date date, int secondBase) {
- if (secondBase < 0 || secondBase > 59)
- throw new IllegalArgumentException(
- "secondBase must be >=0 and <= 59");
-
- if (date == null) date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- c.setLenient(true);
-
- if (secondBase == 0) {
- c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 1);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- int second = c.get(Calendar.SECOND);
-
- int arItr = second / secondBase;
-
- int nextSecondOccurance = secondBase * (arItr + 1);
-
- if (nextSecondOccurance < 60) {
- c.set(Calendar.SECOND, nextSecondOccurance);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- } else {
- c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + 1);
- c.set(Calendar.SECOND, 0);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
- }
-
- /**
- *
- * Get a Date object that represents the given time, on
- * today's date.
- *
- *
- * @param second
- * The value (0-59) to give the seconds field of the date
- * @param minute
- * The value (0-59) to give the minutes field of the date
- * @param hour
- * The value (0-23) to give the hours field of the date
- * @return the new date
- */
- public static Date getDateOf(int second, int minute, int hour) {
- validateSecond(second);
- validateMinute(minute);
- validateHour(hour);
-
- Date date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- c.setLenient(true);
-
- c.set(Calendar.HOUR_OF_DAY, hour);
- c.set(Calendar.MINUTE, minute);
- c.set(Calendar.SECOND, second);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Get a Date object that represents the given time, on the
- * given date.
- *
- *
- * @param second
- * The value (0-59) to give the seconds field of the date
- * @param minute
- * The value (0-59) to give the minutes field of the date
- * @param hour
- * The value (0-23) to give the hours field of the date
- * @param dayOfMonth
- * The value (1-31) to give the day of month field of the date
- * @param month
- * The value (1-12) to give the month field of the date
- * @return the new date
- */
- public static Date getDateOf(int second, int minute, int hour,
- int dayOfMonth, int month) {
- validateSecond(second);
- validateMinute(minute);
- validateHour(hour);
- validateDayOfMonth(dayOfMonth);
- validateMonth(month);
-
- Date date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
-
- c.set(Calendar.MONTH, month - 1);
- c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- c.set(Calendar.HOUR_OF_DAY, hour);
- c.set(Calendar.MINUTE, minute);
- c.set(Calendar.SECOND, second);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- *
- * Get a Date object that represents the given time, on the
- * given date.
- *
- *
- * @param second
- * The value (0-59) to give the seconds field of the date
- * @param minute
- * The value (0-59) to give the minutes field of the date
- * @param hour
- * The value (0-23) to give the hours field of the date
- * @param dayOfMonth
- * The value (1-31) to give the day of month field of the date
- * @param month
- * The value (1-12) to give the month field of the date
- * @param year
- * The value (1970-2099) to give the year field of the date
- * @return the new date
- */
- public static Date getDateOf(int second, int minute, int hour,
- int dayOfMonth, int month, int year) {
- validateSecond(second);
- validateMinute(minute);
- validateHour(hour);
- validateDayOfMonth(dayOfMonth);
- validateMonth(month);
- validateYear(year);
-
- Date date = new Date();
-
- Calendar c = Calendar.getInstance();
- c.setTime(date);
-
- c.set(Calendar.YEAR, year);
- c.set(Calendar.MONTH, month - 1);
- c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- c.set(Calendar.HOUR_OF_DAY, hour);
- c.set(Calendar.MINUTE, minute);
- c.set(Calendar.SECOND, second);
- c.set(Calendar.MILLISECOND, 0);
-
- return c.getTime();
- }
-
- /**
- * Returns a list of Dates that are the next fire times of a
- * Trigger.
* The input trigger will be cloned before any work is done, so you need
* not worry about its state being altered by this method.
*
@@ -1223,28 +109,38 @@
* The calendar to apply to the trigger's schedule
* @param numTimes
* The number of next fire times to produce
- * @return List of java.util.Date objects
+ * @return the computed Date, or null if the trigger (as configured) will not fire that many times.
*/
- public static List computeFireTimes(Trigger trigg, org.quartz.Calendar cal,
+ public static Date computeEndTimeToAllowParticularNumberOfFirings(OperableTrigger trigg, org.quartz.Calendar cal,
int numTimes) {
- LinkedList lst = new LinkedList();
- Trigger t = (Trigger) trigg.clone();
+ OperableTrigger t = (OperableTrigger) trigg.clone();
if (t.getNextFireTime() == null) {
t.computeFirstFireTime(cal);
}
-
+
+ int c = 0;
+ Date endTime = null;
+
for (int i = 0; i < numTimes; i++) {
Date d = t.getNextFireTime();
if (d != null) {
- lst.add(d);
+ c++;
t.triggered(cal);
- } else
+ if(c == numTimes)
+ endTime = d;
+ } else {
break;
+ }
}
-
- return java.util.Collections.unmodifiableList(lst);
+
+ if(endTime == null)
+ return null;
+
+ endTime = new Date(endTime.getTime() + 1000L);
+
+ return endTime;
}
/**
@@ -1256,7 +152,7 @@
*
*
* NOTE: if this is a trigger that has previously fired within the given
- * date range, then firings which have already occured will not be listed
+ * date range, then firings which have already occurred will not be listed
* in the output List.
*
*
@@ -1270,96 +166,36 @@
* The ending date at which to stop finding fire times
* @return List of java.util.Date objects
*/
- public static List computeFireTimesBetween(Trigger trigg,
+ public static List computeFireTimesBetween(OperableTrigger trigg,
org.quartz.Calendar cal, Date from, Date to) {
- LinkedList lst = new LinkedList();
+ LinkedList lst = new LinkedList();
- Trigger t = (Trigger) trigg.clone();
+ OperableTrigger t = (OperableTrigger) trigg.clone();
if (t.getNextFireTime() == null) {
t.setStartTime(from);
t.setEndTime(to);
t.computeFirstFireTime(cal);
}
- // TODO: this method could be more efficient by using logic specific
- // to the type of trigger ...
while (true) {
Date d = t.getNextFireTime();
if (d != null) {
if (d.before(from)) {
t.triggered(cal);
continue;
}
- if (d.after(to)) break;
+ if (d.after(to)) {
+ break;
+ }
lst.add(d);
t.triggered(cal);
- } else
+ } else {
break;
+ }
}
return java.util.Collections.unmodifiableList(lst);
}
- /**
- * Translate a date & time from a users timezone to the another
- * (probably server) timezone to assist in creating a simple trigger with
- * the right date & time.
- *
- * @param date the date to translate
- * @param src the original time-zone
- * @param dest the destination time-zone
- * @return the translated date
- */
- public static Date translateTime(Date date, TimeZone src, TimeZone dest) {
-
- Date newDate = new Date();
-
- int offset = (
- getOffset(date.getTime(), dest) - getOffset(date.getTime(), src)
- );
-
- newDate.setTime(date.getTime() - offset);
-
- return newDate;
- }
-
- /**
- * Gets the offset from UT for the given date in the given timezone,
- * taking into account daylight savings.
- *
- *
- * Equivalent of TimeZone.getOffset(date) in JDK 1.4, but Quartz is trying
- * to support JDK 1.3.
- *
- *
- * @param date the date (in milliseconds) that is the base for the offset
- * @param tz the time-zone to calculate to offset to
- * @return the offset
- */
- public static int getOffset(long date, TimeZone tz) {
-
- if (tz.inDaylightTime(new Date(date))) {
- return tz.getRawOffset() + getDSTSavings(tz);
- }
-
- return tz.getRawOffset();
- }
-
- /**
- *
- * Equivalent of TimeZone.getDSTSavings() in JDK 1.4, but Quartz is trying
- * to support JDK 1.3.
- *
- *
- * @param tz the target time-zone
- * @return the amount of saving time in milliseconds
- */
- public static int getDSTSavings(TimeZone tz) {
-
- if (tz.useDaylightTime()) {
- return 3600000;
- }
- return 0;
- }
}
Fisheye: Tag c208628989d52041b3765784f4c8cbfd6c80d47b refers to a dead (removed) revision in file `3rdParty_sources/quartz/org/quartz/UICronTrigger.java'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/quartz/org/quartz/UnableToInterruptJobException.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/UnableToInterruptJobException.java (.../UnableToInterruptJobException.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/UnableToInterruptJobException.java (.../UnableToInterruptJobException.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,23 +16,19 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
-
package org.quartz;
/**
- *
* An exception that is thrown to indicate that a call to
* InterruptableJob.interrupt() failed without interrupting the Job.
- *
*
* @see org.quartz.InterruptableJob#interrupt()
*
* @author James House
*/
public class UnableToInterruptJobException extends SchedulerException {
+
+ private static final long serialVersionUID = -490863760696463776L;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -56,7 +52,7 @@
* Create a UnableToInterruptJobException with the given cause.
*
*/
- public UnableToInterruptJobException(Exception cause) {
+ public UnableToInterruptJobException(Throwable cause) {
super(cause);
}
Index: 3rdParty_sources/quartz/org/quartz/commonj/WorkManagerThreadExecutor.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/commonj/WorkManagerThreadExecutor.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/commonj/WorkManagerThreadExecutor.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,111 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * 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.
+ *
+ */
+ package org.quartz.commonj;
+
+import commonj.work.Work;
+import commonj.work.WorkManager;
+import org.quartz.spi.ThreadExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+/**
+ * CommonJ WorkManager implementation of hacked Quartz ThreadExecutor class.
+ * This class schedules work on a WorkManager which is looked up in JNDI. The
+ * advantage is that all the work performed is done on a managed thread which is
+ * required by WebSphere, see QUARTZ-743 for
+ * details.
+ *
+ * @author matt.accola
+ * @version $Revision$ $Date$
+ */
+public class WorkManagerThreadExecutor implements ThreadExecutor {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private String workManagerName;
+ private WorkManager workManager;
+
+ public void execute(Thread thread) {
+ Work work = new org.quartz.commonj.DelegatingWork(thread);
+ try {
+ this.workManager.schedule(work);
+ } catch (Exception e) {
+ log.error("Error attempting to schedule QuartzSchedulerThread: " + e.getMessage(), e);
+ }
+ }
+
+ public void initialize() {
+ try {
+ this.workManager = (WorkManager) new InitialContext().lookup(workManagerName);
+ } catch (NamingException e) {
+ throw new IllegalStateException("Could not locate WorkManager: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Sets the JNDI name of the work manager to use.
+ *
+ * @param workManagerName the JNDI name to use to lookup the work manager
+ */
+ public void setWorkManagerName(String workManagerName) {
+ this.workManagerName = workManagerName;
+ }
+
+}
+
+class DelegatingWork implements Work {
+
+ private final Runnable delegate;
+
+ /**
+ * Create a new DelegatingWork.
+ *
+ * @param delegate the Runnable implementation to delegate to
+ */
+ public DelegatingWork(Runnable delegate) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * @return the wrapped Runnable implementation.
+ */
+ public final Runnable getDelegate() {
+ return this.delegate;
+ }
+
+ /**
+ * Delegates execution to the underlying Runnable.
+ */
+ public void run() {
+ this.delegate.run();
+ }
+
+ public boolean isDaemon() {
+ return false;
+ }
+
+ /**
+ * This implementation is empty, since we expect the Runnable to terminate
+ * based on some specific shutdown signal.
+ */
+ public void release() {
+ }
+
+}
Index: 3rdParty_sources/quartz/org/quartz/core/JobRunShell.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/core/JobRunShell.java (.../JobRunShell.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/core/JobRunShell.java (.../JobRunShell.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,37 +1,36 @@
-/*
- * 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
+/*
+ * Copyright 2001-2009 Terracotta, Inc.
+ *
+ * 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.core;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
-import org.quartz.JobPersistenceException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
-import org.quartz.Trigger;
+import org.quartz.Trigger.CompletedExecutionInstruction;
+import org.quartz.impl.JobExecutionContextImpl;
+import org.quartz.listeners.SchedulerListenerSupport;
+import org.quartz.spi.OperableTrigger;
import org.quartz.spi.TriggerFiredBundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*
@@ -41,372 +40,343 @@
* the Trigger with the Job's completion code,
* etc.
*
- *
+ *
*
* A JobRunShell instance is created by a JobRunShellFactory
* on behalf of the QuartzSchedulerThread which then runs the
* shell in a thread from the configured ThreadPool when the
* scheduler determines that a Job has been triggered.
*
- *
+ *
* @see JobRunShellFactory
* @see org.quartz.core.QuartzSchedulerThread
* @see org.quartz.Job
* @see org.quartz.Trigger
- *
+ *
* @author James House
*/
-public class JobRunShell implements Runnable {
+public class JobRunShell extends SchedulerListenerSupport implements Runnable {
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
+ *
* Data members.
- *
+ *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
- protected JobExecutionContext jec = null;
+ protected JobExecutionContextImpl jec = null;
protected QuartzScheduler qs = null;
+
+ protected TriggerFiredBundle firedTriggerBundle = null;
protected Scheduler scheduler = null;
- protected SchedulingContext schdCtxt = null;
+ protected volatile boolean shutdownRequested = false;
- protected JobRunShellFactory jobRunShellFactory = null;
+ private final Logger log = LoggerFactory.getLogger(getClass());
- protected boolean shutdownRequested = false;
-
- protected Log log = LogFactory.getLog(getClass());
-
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
+ *
* Constructors.
- *
+ *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/**
*
* Create a JobRunShell instance with the given settings.
*
- *
- * @param jobRunShellFactory
- * A handle to the JobRunShellFactory that produced
- * this JobRunShell.
+ *
* @param scheduler
* The Scheduler instance that should be made
* available within the JobExecutionContext.
- * @param schdCtxt
- * the SchedulingContext that should be used by the
- * JobRunShell when making updates to the JobStore.
*/
- public JobRunShell(JobRunShellFactory jobRunShellFactory,
- Scheduler scheduler, SchedulingContext schdCtxt) {
- this.jobRunShellFactory = jobRunShellFactory;
+ public JobRunShell(Scheduler scheduler, TriggerFiredBundle bndle) {
this.scheduler = scheduler;
- this.schdCtxt = schdCtxt;
+ this.firedTriggerBundle = bndle;
}
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
+ *
* Interface.
- *
+ *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
- private static Log getLog()
- {
- return LogFactory.getLog(JobRunShell.class);
+ @Override
+ public void schedulerShuttingdown() {
+ requestShutdown();
}
-
- public void initialize(QuartzScheduler qs, TriggerFiredBundle firedBundle)
- throws SchedulerException {
- this.qs = qs;
+ @Override
+ protected Logger getLog() {
+ return log;
+ }
+
+ public void initialize(QuartzScheduler sched)
+ throws SchedulerException {
+ this.qs = sched;
+
Job job = null;
- JobDetail jobDetail = firedBundle.getJobDetail();
+ JobDetail jobDetail = firedTriggerBundle.getJobDetail();
try {
- job = qs.getJobFactory().newJob(firedBundle);
+ job = sched.getJobFactory().newJob(firedTriggerBundle, scheduler);
} catch (SchedulerException se) {
- qs.notifySchedulerListenersError(
+ sched.notifySchedulerListenersError(
"An error occured instantiating job to be executed. job= '"
- + jobDetail.getFullName() + "'", se);
+ + jobDetail.getKey() + "'", se);
throw se;
- } catch (Exception e) {
- SchedulerException se = new SchedulerException(
- "Problem instantiating class '"
- + jobDetail.getJobClass().getName() + "'", e);
- qs.notifySchedulerListenersError(
- "An error occured instantiating job to be executed. job= '"
- + jobDetail.getFullName() + "'", se);
- throw se;
} catch (Throwable ncdfe) { // such as NoClassDefFoundError
SchedulerException se = new SchedulerException(
"Problem instantiating class '"
- + jobDetail.getJobClass().getName() + "' - " + ncdfe);
- qs.notifySchedulerListenersError(
+ + jobDetail.getJobClass().getName() + "' - ", ncdfe);
+ sched.notifySchedulerListenersError(
"An error occured instantiating job to be executed. job= '"
- + jobDetail.getFullName() + "'", se);
+ + jobDetail.getKey() + "'", se);
throw se;
}
- this.jec = new JobExecutionContext(scheduler, firedBundle, job);
+ this.jec = new JobExecutionContextImpl(scheduler, firedTriggerBundle, job);
}
public void requestShutdown() {
shutdownRequested = true;
}
public void run() {
- Trigger trigger = jec.getTrigger();
- JobDetail jobDetail = jec.getJobDetail();
+ qs.addInternalSchedulerListener(this);
- do {
+ try {
+ OperableTrigger trigger = (OperableTrigger) jec.getTrigger();
+ JobDetail jobDetail = jec.getJobDetail();
- JobExecutionException jobExEx = null;
- Job job = jec.getJobInstance();
+ do {
- try {
- begin();
- } catch (SchedulerException se) {
- qs.notifySchedulerListenersError("Error executing Job ("
- + jec.getJobDetail().getFullName()
- + ": couldn't begin execution.", se);
- break;
- }
+ JobExecutionException jobExEx = null;
+ Job job = jec.getJobInstance();
- // notify job & trigger listeners...
- try {
- if (!notifyListenersBeginning(jec)) break;
- }
- catch(VetoedException ve) {
try {
- complete(true);
+ begin();
} catch (SchedulerException se) {
- qs.notifySchedulerListenersError("Error during veto of Job ("
- + jec.getJobDetail().getFullName()
- + ": couldn't finalize execution.", se);
+ qs.notifySchedulerListenersError("Error executing Job ("
+ + jec.getJobDetail().getKey()
+ + ": couldn't begin execution.", se);
+ break;
}
- break;
- }
- long startTime = System.currentTimeMillis();
- long endTime = startTime;
-
- // execute the job
- try {
- log.debug("Calling execute on job " + jobDetail.getFullName());
- job.execute(jec);
- endTime = System.currentTimeMillis();
- } catch (JobExecutionException jee) {
- endTime = System.currentTimeMillis();
- jobExEx = jee;
- getLog().info("Job " + jobDetail.getFullName() +
- " threw a JobExecutionException: ", jobExEx);
- } catch (Exception e) {
- endTime = System.currentTimeMillis();
- getLog().error("Job " + jobDetail.getFullName() +
- " threw an unhandled Exception: ", e);
- SchedulerException se = new SchedulerException(
- "Job threw an unhandled exception.", e);
- se.setErrorCode(SchedulerException.ERR_JOB_EXECUTION_THREW_EXCEPTION);
- qs.notifySchedulerListenersError("Job ("
- + jec.getJobDetail().getFullName()
- + " threw an exception.", se);
- jobExEx = new JobExecutionException(se, false);
- jobExEx.setErrorCode(JobExecutionException.ERR_JOB_EXECUTION_THREW_EXCEPTION);
- }
-
- jec.setJobRunTime(endTime - startTime);
+ // notify job & trigger listeners...
+ try {
+ if (!notifyListenersBeginning(jec)) {
+ break;
+ }
+ } catch(VetoedException ve) {
+ try {
+ CompletedExecutionInstruction instCode = trigger.executionComplete(jec, null);
+ qs.notifyJobStoreJobVetoed(trigger, jobDetail, instCode);
+
+ // QTZ-205
+ // Even if trigger got vetoed, we still needs to check to see if it's the trigger's finalized run or not.
+ if (jec.getTrigger().getNextFireTime() == null) {
+ qs.notifySchedulerListenersFinalized(jec.getTrigger());
+ }
- // notify all job listeners
- if (!notifyJobListenersComplete(jec, jobExEx)) break;
+ complete(true);
+ } catch (SchedulerException se) {
+ qs.notifySchedulerListenersError("Error during veto of Job ("
+ + jec.getJobDetail().getKey()
+ + ": couldn't finalize execution.", se);
+ }
+ break;
+ }
- int instCode = Trigger.INSTRUCTION_NOOP;
+ long startTime = System.currentTimeMillis();
+ long endTime = startTime;
- // update the trigger
- try {
- instCode = trigger.executionComplete(jec, jobExEx);
- } catch (Exception e) {
- // If this happens, there's a bug in the trigger...
- SchedulerException se = new SchedulerException(
- "Trigger threw an unhandled exception.", e);
- se.setErrorCode(SchedulerException.ERR_TRIGGER_THREW_EXCEPTION);
- qs.notifySchedulerListenersError(
- "Please report this error to the Quartz developers.",
- se);
- }
+ // execute the job
+ try {
+ log.debug("Calling execute on job " + jobDetail.getKey());
+ job.execute(jec);
+ endTime = System.currentTimeMillis();
+ } catch (JobExecutionException jee) {
+ endTime = System.currentTimeMillis();
+ jobExEx = jee;
+ getLog().info("Job " + jobDetail.getKey() +
+ " threw a JobExecutionException: ", jobExEx);
+ } catch (Throwable e) {
+ endTime = System.currentTimeMillis();
+ getLog().error("Job " + jobDetail.getKey() +
+ " threw an unhandled Exception: ", e);
+ SchedulerException se = new SchedulerException(
+ "Job threw an unhandled exception.", e);
+ qs.notifySchedulerListenersError("Job ("
+ + jec.getJobDetail().getKey()
+ + " threw an exception.", se);
+ jobExEx = new JobExecutionException(se, false);
+ }
- // notify all trigger listeners
- if (!notifyTriggerListenersComplete(jec, instCode)) break;
+ jec.setJobRunTime(endTime - startTime);
- // update job/trigger or re-execute job
- if (instCode == Trigger.INSTRUCTION_RE_EXECUTE_JOB) {
- jec.incrementRefireCount();
+ // notify all job listeners
+ if (!notifyJobListenersComplete(jec, jobExEx)) {
+ break;
+ }
+
+ CompletedExecutionInstruction instCode = CompletedExecutionInstruction.NOOP;
+
+ // update the trigger
try {
- complete(false);
+ instCode = trigger.executionComplete(jec, jobExEx);
+ } catch (Exception e) {
+ // If this happens, there's a bug in the trigger...
+ SchedulerException se = new SchedulerException(
+ "Trigger threw an unhandled exception.", e);
+ qs.notifySchedulerListenersError(
+ "Please report this error to the Quartz developers.",
+ se);
+ }
+
+ // notify all trigger listeners
+ if (!notifyTriggerListenersComplete(jec, instCode)) {
+ break;
+ }
+
+ // update job/trigger or re-execute job
+ if (instCode == CompletedExecutionInstruction.RE_EXECUTE_JOB) {
+ jec.incrementRefireCount();
+ try {
+ complete(false);
+ } catch (SchedulerException se) {
+ qs.notifySchedulerListenersError("Error executing Job ("
+ + jec.getJobDetail().getKey()
+ + ": couldn't finalize execution.", se);
+ }
+ continue;
+ }
+
+ try {
+ complete(true);
} catch (SchedulerException se) {
qs.notifySchedulerListenersError("Error executing Job ("
- + jec.getJobDetail().getFullName()
+ + jec.getJobDetail().getKey()
+ ": couldn't finalize execution.", se);
+ continue;
}
- continue;
- }
- try {
- complete(true);
- } catch (SchedulerException se) {
- qs.notifySchedulerListenersError("Error executing Job ("
- + jec.getJobDetail().getFullName()
- + ": couldn't finalize execution.", se);
- continue;
- }
+ qs.notifyJobStoreJobComplete(trigger, jobDetail, instCode);
+ break;
+ } while (true);
- try {
- qs.notifyJobStoreJobComplete(schdCtxt, trigger, jobDetail,
- instCode);
- } catch (JobPersistenceException jpe) {
- qs.notifySchedulerListenersError(
- "An error occured while marking executed job complete. job= '"
- + jobDetail.getFullName() + "'", jpe);
- if (!completeTriggerRetryLoop(trigger, jobDetail, instCode))
- ;
- return;
- }
-
- break;
- } while (true);
-
- qs.notifySchedulerThread();
-
- jobRunShellFactory.returnJobRunShell(this);
+ } finally {
+ qs.removeInternalSchedulerListener(this);
+ }
}
protected void begin() throws SchedulerException {
}
protected void complete(boolean successfulExecution)
- throws SchedulerException {
+ throws SchedulerException {
}
public void passivate() {
jec = null;
qs = null;
}
- private boolean notifyListenersBeginning(JobExecutionContext jec) throws VetoedException {
-
+ private boolean notifyListenersBeginning(JobExecutionContext jobExCtxt) throws VetoedException {
+
boolean vetoed = false;
-
+
// notify all trigger listeners
try {
- vetoed = qs.notifyTriggerListenersFired(jec);
+ vetoed = qs.notifyTriggerListenersFired(jobExCtxt);
} catch (SchedulerException se) {
qs.notifySchedulerListenersError(
"Unable to notify TriggerListener(s) while firing trigger "
+ "(Trigger and Job will NOT be fired!). trigger= "
- + jec.getTrigger().getFullName() + " job= "
- + jec.getJobDetail().getFullName(), se);
+ + jobExCtxt.getTrigger().getKey() + " job= "
+ + jobExCtxt.getJobDetail().getKey(), se);
return false;
}
if(vetoed) {
try {
- qs.notifyJobListenersWasVetoed(jec);
+ qs.notifyJobListenersWasVetoed(jobExCtxt);
} catch (SchedulerException se) {
qs.notifySchedulerListenersError(
"Unable to notify JobListener(s) of vetoed execution " +
"while firing trigger (Trigger and Job will NOT be " +
"fired!). trigger= "
- + jec.getTrigger().getFullName() + " job= "
- + jec.getJobDetail().getFullName(), se);
+ + jobExCtxt.getTrigger().getKey() + " job= "
+ + jobExCtxt.getJobDetail().getKey(), se);
}
throw new VetoedException();
}
-
+
// notify all job listeners
try {
- qs.notifyJobListenersToBeExecuted(jec);
+ qs.notifyJobListenersToBeExecuted(jobExCtxt);
} catch (SchedulerException se) {
qs.notifySchedulerListenersError(
"Unable to notify JobListener(s) of Job to be executed: "
+ "(Job will NOT be executed!). trigger= "
- + jec.getTrigger().getFullName() + " job= "
- + jec.getJobDetail().getFullName(), se);
+ + jobExCtxt.getTrigger().getKey() + " job= "
+ + jobExCtxt.getJobDetail().getKey(), se);
return false;
}
return true;
}
- private boolean notifyJobListenersComplete(JobExecutionContext jec,
- JobExecutionException jobExEx) {
+ private boolean notifyJobListenersComplete(JobExecutionContext jobExCtxt, JobExecutionException jobExEx) {
try {
- qs.notifyJobListenersWasExecuted(jec, jobExEx);
+ qs.notifyJobListenersWasExecuted(jobExCtxt, jobExEx);
} catch (SchedulerException se) {
qs.notifySchedulerListenersError(
"Unable to notify JobListener(s) of Job that was executed: "
+ "(error will be ignored). trigger= "
- + jec.getTrigger().getFullName() + " job= "
- + jec.getJobDetail().getFullName(), se);
+ + jobExCtxt.getTrigger().getKey() + " job= "
+ + jobExCtxt.getJobDetail().getKey(), se);
return false;
}
return true;
}
- private boolean notifyTriggerListenersComplete(JobExecutionContext jec,
- int instCode) {
+ private boolean notifyTriggerListenersComplete(JobExecutionContext jobExCtxt, CompletedExecutionInstruction instCode) {
try {
- qs.notifyTriggerListenersComplete(jec, instCode);
+ qs.notifyTriggerListenersComplete(jobExCtxt, instCode);
} catch (SchedulerException se) {
qs.notifySchedulerListenersError(
"Unable to notify TriggerListener(s) of Job that was executed: "
+ "(error will be ignored). trigger= "
- + jec.getTrigger().getFullName() + " job= "
- + jec.getJobDetail().getFullName(), se);
+ + jobExCtxt.getTrigger().getKey() + " job= "
+ + jobExCtxt.getJobDetail().getKey(), se);
return false;
}
- if (jec.getTrigger().getNextFireTime() == null)
- qs.notifySchedulerListenersFinalized(jec.getTrigger());
+ if (jobExCtxt.getTrigger().getNextFireTime() == null) {
+ qs.notifySchedulerListenersFinalized(jobExCtxt.getTrigger());
+ }
return true;
}
- public boolean completeTriggerRetryLoop(Trigger trigger,
- JobDetail jobDetail, int instCode) {
- while (!shutdownRequested) {
- try {
- Thread.sleep(5 * 1000l); // retry every 5 seconds (the db
- // connection must be failed)
- qs.notifyJobStoreJobComplete(schdCtxt, trigger, jobDetail,
- instCode);
- return true;
- } catch (JobPersistenceException jpe) {
- qs.notifySchedulerListenersError(
- "An error occured while marking executed job complete. job= '"
- + jobDetail.getFullName() + "'", jpe);
- } catch (InterruptedException ignore) {
- }
- }
- return false;
- }
+ static class VetoedException extends Exception {
-
- class VetoedException extends Exception
- {
- public VetoedException()
- {
+ private static final long serialVersionUID = 1539955697495918463L;
+
+ public VetoedException() {
}
}
-}
\ No newline at end of file
+
+}
Index: 3rdParty_sources/quartz/org/quartz/core/JobRunShellFactory.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/core/JobRunShellFactory.java (.../JobRunShellFactory.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/core/JobRunShellFactory.java (.../JobRunShellFactory.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,29 +16,19 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz.core;
import org.quartz.Scheduler;
import org.quartz.SchedulerConfigException;
import org.quartz.SchedulerException;
+import org.quartz.spi.TriggerFiredBundle;
/**
*
* Responsible for creating the instances of {@link JobRunShell}
* to be used within the {@link QuartzScheduler} instance.
*
*
- *
- * Although this interface looks a lot like an 'object pool', implementations
- * do not have to support the re-use of instances. If an implementation does
- * not wish to pool instances, then the borrowJobRunShell()
- * method would simply create a new instance, and the returnJobRunShell
- * method would do nothing.
- *
- *
* @author James House
*/
public interface JobRunShellFactory {
@@ -55,28 +45,17 @@
*
* Initialize the factory, providing a handle to the Scheduler
* that should be made available within the JobRunShell and
- * the JobExecutionCOntext s within it, and a handle to the
- * SchedulingContext that the shell will use in its own
- * operations with the JobStore.
+ * the JobExecutionContext s within it.
*
*/
- public void initialize(Scheduler scheduler, SchedulingContext schedCtxt)
- throws SchedulerConfigException;
+ void initialize(Scheduler scheduler)
+ throws SchedulerConfigException;
/**
*
* Called by the {@link org.quartz.core.QuartzSchedulerThread}
* to obtain instances of {@link JobRunShell}.
*
*/
- public JobRunShell borrowJobRunShell() throws SchedulerException;
-
- /**
- *
- * Called by the {@link org.quartz.core.QuartzSchedulerThread}
- * to return instances of {@link JobRunShell}.
- *
- */
- public void returnJobRunShell(JobRunShell jobRunShell);
-
+ JobRunShell createJobRunShell(TriggerFiredBundle bundle) throws SchedulerException;
}
\ No newline at end of file
Index: 3rdParty_sources/quartz/org/quartz/core/ListenerManagerImpl.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/core/ListenerManagerImpl.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/core/ListenerManagerImpl.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,275 @@
+package org.quartz.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.quartz.JobKey;
+import org.quartz.JobListener;
+import org.quartz.ListenerManager;
+import org.quartz.Matcher;
+import org.quartz.SchedulerListener;
+import org.quartz.TriggerKey;
+import org.quartz.TriggerListener;
+import org.quartz.impl.matchers.EverythingMatcher;
+
+public class ListenerManagerImpl implements ListenerManager {
+
+ private Map globalJobListeners = new LinkedHashMap(10);
+
+ private Map globalTriggerListeners = new LinkedHashMap(10);
+
+ private Map>> globalJobListenersMatchers = new LinkedHashMap>>(10);
+
+ private Map>> globalTriggerListenersMatchers = new LinkedHashMap>>(10);
+
+ private ArrayList schedulerListeners = new ArrayList(10);
+
+
+ public void addJobListener(JobListener jobListener, Matcher ... matchers) {
+ addJobListener(jobListener, Arrays.asList(matchers));
+ }
+
+ public void addJobListener(JobListener jobListener, List> matchers) {
+ if (jobListener.getName() == null || jobListener.getName().length() == 0) {
+ throw new IllegalArgumentException(
+ "JobListener name cannot be empty.");
+ }
+
+ synchronized (globalJobListeners) {
+ globalJobListeners.put(jobListener.getName(), jobListener);
+ LinkedList> matchersL = new LinkedList>();
+ if(matchers != null && matchers.size() > 0)
+ matchersL.addAll(matchers);
+ else
+ matchersL.add(EverythingMatcher.allJobs());
+
+ globalJobListenersMatchers.put(jobListener.getName(), matchersL);
+ }
+ }
+
+
+ public void addJobListener(JobListener jobListener) {
+ addJobListener(jobListener, EverythingMatcher.allJobs());
+ }
+
+ public void addJobListener(JobListener jobListener, Matcher matcher) {
+ if (jobListener.getName() == null || jobListener.getName().length() == 0) {
+ throw new IllegalArgumentException(
+ "JobListener name cannot be empty.");
+ }
+
+ synchronized (globalJobListeners) {
+ globalJobListeners.put(jobListener.getName(), jobListener);
+ LinkedList> matchersL = new LinkedList>();
+ if(matcher != null)
+ matchersL.add(matcher);
+ else
+ matchersL.add(EverythingMatcher.allJobs());
+
+ globalJobListenersMatchers.put(jobListener.getName(), matchersL);
+ }
+ }
+
+
+ public boolean addJobListenerMatcher(String listenerName, Matcher matcher) {
+ if(matcher == null)
+ throw new IllegalArgumentException("Null value not acceptable.");
+
+ synchronized (globalJobListeners) {
+ List> matchers = globalJobListenersMatchers.get(listenerName);
+ if(matchers == null)
+ return false;
+ matchers.add(matcher);
+ return true;
+ }
+ }
+
+ public boolean removeJobListenerMatcher(String listenerName, Matcher matcher) {
+ if(matcher == null)
+ throw new IllegalArgumentException("Non-null value not acceptable.");
+
+ synchronized (globalJobListeners) {
+ List> matchers = globalJobListenersMatchers.get(listenerName);
+ if(matchers == null)
+ return false;
+ return matchers.remove(matcher);
+ }
+ }
+
+ public List> getJobListenerMatchers(String listenerName) {
+ synchronized (globalJobListeners) {
+ List> matchers = globalJobListenersMatchers.get(listenerName);
+ if(matchers == null)
+ return null;
+ return Collections.unmodifiableList(matchers);
+ }
+ }
+
+ public boolean setJobListenerMatchers(String listenerName, List> matchers) {
+ if(matchers == null)
+ throw new IllegalArgumentException("Non-null value not acceptable.");
+
+ synchronized (globalJobListeners) {
+ List> oldMatchers = globalJobListenersMatchers.get(listenerName);
+ if(oldMatchers == null)
+ return false;
+ globalJobListenersMatchers.put(listenerName, matchers);
+ return true;
+ }
+ }
+
+
+ public boolean removeJobListener(String name) {
+ synchronized (globalJobListeners) {
+ return (globalJobListeners.remove(name) != null);
+ }
+ }
+
+ public List getJobListeners() {
+ synchronized (globalJobListeners) {
+ return java.util.Collections.unmodifiableList(new LinkedList(globalJobListeners.values()));
+ }
+ }
+
+ public JobListener getJobListener(String name) {
+ synchronized (globalJobListeners) {
+ return globalJobListeners.get(name);
+ }
+ }
+
+ public void addTriggerListener(TriggerListener triggerListener, Matcher ... matchers) {
+ addTriggerListener(triggerListener, Arrays.asList(matchers));
+ }
+
+ public void addTriggerListener(TriggerListener triggerListener, List> matchers) {
+ if (triggerListener.getName() == null
+ || triggerListener.getName().length() == 0) {
+ throw new IllegalArgumentException(
+ "TriggerListener name cannot be empty.");
+ }
+
+ synchronized (globalTriggerListeners) {
+ globalTriggerListeners.put(triggerListener.getName(), triggerListener);
+
+ LinkedList> matchersL = new LinkedList>();
+ if(matchers != null && matchers.size() > 0)
+ matchersL.addAll(matchers);
+ else
+ matchersL.add(EverythingMatcher.allTriggers());
+
+ globalTriggerListenersMatchers.put(triggerListener.getName(), matchersL);
+ }
+ }
+
+ public void addTriggerListener(TriggerListener triggerListener) {
+ addTriggerListener(triggerListener, EverythingMatcher.allTriggers());
+ }
+
+ public void addTriggerListener(TriggerListener triggerListener, Matcher matcher) {
+ if(matcher == null)
+ throw new IllegalArgumentException("Null value not acceptable for matcher.");
+
+ if (triggerListener.getName() == null
+ || triggerListener.getName().length() == 0) {
+ throw new IllegalArgumentException(
+ "TriggerListener name cannot be empty.");
+ }
+
+ synchronized (globalTriggerListeners) {
+ globalTriggerListeners.put(triggerListener.getName(), triggerListener);
+ List> matchers = new LinkedList>();
+ matchers.add(matcher);
+ globalTriggerListenersMatchers.put(triggerListener.getName(), matchers);
+ }
+ }
+
+ public boolean addTriggerListenerMatcher(String listenerName, Matcher matcher) {
+ if(matcher == null)
+ throw new IllegalArgumentException("Non-null value not acceptable.");
+
+ synchronized (globalTriggerListeners) {
+ List> matchers = globalTriggerListenersMatchers.get(listenerName);
+ if(matchers == null)
+ return false;
+ matchers.add(matcher);
+ return true;
+ }
+ }
+
+ public boolean removeTriggerListenerMatcher(String listenerName, Matcher matcher) {
+ if(matcher == null)
+ throw new IllegalArgumentException("Non-null value not acceptable.");
+
+ synchronized (globalTriggerListeners) {
+ List> matchers = globalTriggerListenersMatchers.get(listenerName);
+ if(matchers == null)
+ return false;
+ return matchers.remove(matcher);
+ }
+ }
+
+ public List> getTriggerListenerMatchers(String listenerName) {
+ synchronized (globalTriggerListeners) {
+ List> matchers = globalTriggerListenersMatchers.get(listenerName);
+ if(matchers == null)
+ return null;
+ return Collections.unmodifiableList(matchers);
+ }
+ }
+
+ public boolean setTriggerListenerMatchers(String listenerName, List> matchers) {
+ if(matchers == null)
+ throw new IllegalArgumentException("Non-null value not acceptable.");
+
+ synchronized (globalTriggerListeners) {
+ List> oldMatchers = globalTriggerListenersMatchers.get(listenerName);
+ if(oldMatchers == null)
+ return false;
+ globalTriggerListenersMatchers.put(listenerName, matchers);
+ return true;
+ }
+ }
+
+ public boolean removeTriggerListener(String name) {
+ synchronized (globalTriggerListeners) {
+ return (globalTriggerListeners.remove(name) != null);
+ }
+ }
+
+
+ public List getTriggerListeners() {
+ synchronized (globalTriggerListeners) {
+ return java.util.Collections.unmodifiableList(new LinkedList(globalTriggerListeners.values()));
+ }
+ }
+
+ public TriggerListener getTriggerListener(String name) {
+ synchronized (globalTriggerListeners) {
+ return globalTriggerListeners.get(name);
+ }
+ }
+
+
+ public void addSchedulerListener(SchedulerListener schedulerListener) {
+ synchronized (schedulerListeners) {
+ schedulerListeners.add(schedulerListener);
+ }
+ }
+
+ public boolean removeSchedulerListener(SchedulerListener schedulerListener) {
+ synchronized (schedulerListeners) {
+ return schedulerListeners.remove(schedulerListener);
+ }
+ }
+
+ public List getSchedulerListeners() {
+ synchronized (schedulerListeners) {
+ return java.util.Collections.unmodifiableList(new ArrayList(schedulerListeners));
+ }
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/core/NullSampledStatisticsImpl.java
===================================================================
diff -u
--- 3rdParty_sources/quartz/org/quartz/core/NullSampledStatisticsImpl.java (revision 0)
+++ 3rdParty_sources/quartz/org/quartz/core/NullSampledStatisticsImpl.java (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -0,0 +1,19 @@
+package org.quartz.core;
+
+public class NullSampledStatisticsImpl implements SampledStatistics {
+ public long getJobsCompletedMostRecentSample() {
+ return 0;
+ }
+
+ public long getJobsExecutingMostRecentSample() {
+ return 0;
+ }
+
+ public long getJobsScheduledMostRecentSample() {
+ return 0;
+ }
+
+ public void shutdown() {
+ // nothing to do
+ }
+}
Index: 3rdParty_sources/quartz/org/quartz/core/QuartzScheduler.java
===================================================================
diff -u -r2e3463e873227c6a3edcb3e02d55270219e553ff -rc208628989d52041b3765784f4c8cbfd6c80d47b
--- 3rdParty_sources/quartz/org/quartz/core/QuartzScheduler.java (.../QuartzScheduler.java) (revision 2e3463e873227c6a3edcb3e02d55270219e553ff)
+++ 3rdParty_sources/quartz/org/quartz/core/QuartzScheduler.java (.../QuartzScheduler.java) (revision c208628989d52041b3765784f4c8cbfd6c80d47b)
@@ -1,6 +1,6 @@
/*
- * Copyright 2004-2005 OpenSymphony
+ * Copyright 2001-2009 Terracotta, Inc.
*
* 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
@@ -16,58 +16,76 @@
*
*/
-/*
- * Previously Copyright (c) 2001-2004 James House
- */
package org.quartz.core;
-import java.io.IOException;
import java.io.InputStream;
+import java.lang.management.ManagementFactory;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
+import java.util.Timer;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
import org.quartz.Calendar;
import org.quartz.InterruptableJob;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
import org.quartz.JobListener;
-import org.quartz.JobPersistenceException;
+import org.quartz.ListenerManager;
+import org.quartz.Matcher;
import org.quartz.ObjectAlreadyExistsException;
import org.quartz.Scheduler;
import org.quartz.SchedulerContext;
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
+import org.quartz.SchedulerMetaData;
import org.quartz.Trigger;
+import static org.quartz.TriggerBuilder.*;
+import org.quartz.TriggerKey;
import org.quartz.TriggerListener;
import org.quartz.UnableToInterruptJobException;
+import org.quartz.Trigger.CompletedExecutionInstruction;
+import org.quartz.Trigger.TriggerState;
+import org.quartz.core.jmx.QuartzSchedulerMBean;
import org.quartz.impl.SchedulerRepository;
-import org.quartz.simpl.SimpleJobFactory;
+import org.quartz.impl.StdSchedulerFactory;
+import org.quartz.impl.matchers.GroupMatcher;
+import org.quartz.listeners.SchedulerListenerSupport;
+import org.quartz.simpl.PropertySettingJobFactory;
import org.quartz.spi.JobFactory;
+import org.quartz.spi.OperableTrigger;
import org.quartz.spi.SchedulerPlugin;
import org.quartz.spi.SchedulerSignaler;
+import org.quartz.spi.ThreadExecutor;
+import org.quartz.utils.UpdateChecker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*
* This is the heart of Quartz, an indirect implementation of the {@link org.quartz.Scheduler}
* interface, containing methods to schedule {@link org.quartz.Job}s,
* register {@link org.quartz.JobListener} instances, etc.
- *
// TODO: more docs...
+ *
*
* @see org.quartz.Scheduler
* @see org.quartz.core.QuartzSchedulerThread
@@ -92,17 +110,32 @@
static {
Properties props = new Properties();
+ InputStream is = null;
try {
- InputStream is =
- QuartzScheduler.class.getResourceAsStream("/build.properties");
+ is = QuartzScheduler.class.getResourceAsStream("quartz-build.properties");
if(is != null) {
props.load(is);
- VERSION_MAJOR = props.getProperty("version.major");
- VERSION_MINOR = props.getProperty("version.minor");
- VERSION_ITERATION = props.getProperty("version.iter");
+ String version = props.getProperty("version");
+ if (version != null) {
+ String[] versionComponents = version.split("\\.");
+ VERSION_MAJOR = versionComponents[0];
+ VERSION_MINOR = versionComponents[1];
+ if(versionComponents.length > 2)
+ VERSION_ITERATION = versionComponents[2];
+ else
+ VERSION_ITERATION = "0";
+ } else {
+ (LoggerFactory.getLogger(QuartzScheduler.class)).error(
+ "Can't parse Quartz version from quartz-build.properties");
+ }
}
- } catch (IOException e) {
- getLog().error("Error loading version info from build.properties.", e);
+ } catch (Exception e) {
+ (LoggerFactory.getLogger(QuartzScheduler.class)).error(
+ "Error loading version info from quartz-build.properties.", e);
+ } finally {
+ if(is != null) {
+ try { is.close(); } catch(Exception ignore) {}
+ }
}
}
@@ -123,19 +156,15 @@
private SchedulerContext context = new SchedulerContext();
- private HashMap jobListeners = new HashMap(10);
+ private ListenerManager listenerManager = new ListenerManagerImpl();
+
+ private HashMap internalJobListeners = new HashMap(10);
- private ArrayList globalJobListeners = new ArrayList(10);
+ private HashMap internalTriggerListeners = new HashMap(10);
- private HashMap triggerListeners = new HashMap(10);
+ private ArrayList internalSchedulerListeners = new ArrayList(10);
- private ArrayList globalTriggerListeners = new ArrayList(10);
-
- private ArrayList schedulerListeners = new ArrayList(10);
-
- private ArrayList schedulerPlugins = new ArrayList(10);
-
- private JobFactory jobFactory = new SimpleJobFactory();
+ private JobFactory jobFactory = new PropertySettingJobFactory();
ExecutingJobsManager jobMgr = null;
@@ -145,14 +174,27 @@
private Random random = new Random();
- private ArrayList holdToPreventGC = new ArrayList(5);
+ private ArrayList