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

io.logspace.agent.shaded.quartz.impl.triggers.DailyTimeIntervalTriggerImpl Maven / Gradle / Ivy

There is a newer version: 0.3.2
Show newest version
/* 
 * 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.
 * 
 */
package io.logspace.agent.shaded.quartz.impl.triggers;

import java.util.Calendar;
import java.util.Date;
import java.util.Set;

import io.logspace.agent.shaded.quartz.DailyTimeIntervalScheduleBuilder;
import io.logspace.agent.shaded.quartz.DailyTimeIntervalTrigger;
import io.logspace.agent.shaded.quartz.DateBuilder;
import io.logspace.agent.shaded.quartz.JobExecutionContext;
import io.logspace.agent.shaded.quartz.JobExecutionException;
import io.logspace.agent.shaded.quartz.ScheduleBuilder;
import io.logspace.agent.shaded.quartz.Scheduler;
import io.logspace.agent.shaded.quartz.SchedulerException;
import io.logspace.agent.shaded.quartz.TimeOfDay;
import io.logspace.agent.shaded.quartz.Trigger;
import io.logspace.agent.shaded.quartz.DateBuilder.IntervalUnit;

/**
 * A concrete implementation of DailyTimeIntervalTrigger that is used to fire a {@link io.logspace.agent.shaded.quartz.JobDetail}
 * based upon daily repeating time intervals.
 * 
 * 

The trigger will fire every N (see {@link #setRepeatInterval(int)} ) seconds, minutes or hours * (see {@link #setRepeatIntervalUnit(io.logspace.agent.shaded.quartz.DateBuilder.IntervalUnit)}) 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. Again, * remember this trigger will reset fire time each day with startTimeOfDay, regardless of your interval or endTimeOfDay!

* *

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 startTimeOfDay will be used and startTime has no affect other than to specify * the first day of firing. Else if startTime is * after startTimeOfDay, then the first fire time for that day will be the next interval after the startTime. For example, if * you set startingTimeOfDay=9am, endingTimeOfDay=11am, interval=15 mins, and startTime=9:33am, then the next fire time will * be 9:45pm. Note also that if you do not set startTime value, the trigger builder will default to current time, and current time * maybe before or after the startTimeOfDay! So be aware how you set your startTime.

* *

This trigger also supports "repeatCount" feature to end the trigger fire time after * a certain number of count is reached. Just as the SimpleTrigger, setting repeatCount=0 * means trigger will fire once only! Setting any positive count then the trigger will repeat * count + 1 times. Unlike SimpleTrigger, the default value of repeatCount of this trigger * is set to REPEAT_INDEFINITELY instead of 0 though. * * @see DailyTimeIntervalTrigger * @see DailyTimeIntervalScheduleBuilder * * @since 2.1.0 * * @author James House * @author Zemian Deng */ public class DailyTimeIntervalTriggerImpl extends AbstractTrigger implements DailyTimeIntervalTrigger, CoreTrigger { private static final long serialVersionUID = -632667786771388749L; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constants. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ private static final int YEAR_TO_GIVEUP_SCHEDULING_AT = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR) + 100; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Data members. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ private Date startTime = null; private Date endTime = null; private Date nextFireTime = null; private Date previousFireTime = null; private int repeatCount = REPEAT_INDEFINITELY; private int repeatInterval = 1; private IntervalUnit repeatIntervalUnit = IntervalUnit.MINUTE; private Set daysOfWeek; private TimeOfDay startTimeOfDay; private TimeOfDay endTimeOfDay; private int timesTriggered = 0; private boolean complete = false; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constructors. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Create a DailyTimeIntervalTrigger with no settings. *

*/ public DailyTimeIntervalTriggerImpl() { super(); } /** *

* Create a DailyTimeIntervalTrigger that will occur immediately, and * repeat at the the given interval. *

* * @param startTimeOfDay * The TimeOfDay that the repeating should begin occurring. * @param endTimeOfDay * The TimeOfDay that the repeating should stop occurring. * @param intervalUnit The repeat interval unit. The only intervals that are valid for this type of trigger are * {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}. * @throws IllegalArgumentException if an invalid IntervalUnit is given, or the repeat interval is zero or less. */ public DailyTimeIntervalTriggerImpl(String name, TimeOfDay startTimeOfDay, TimeOfDay endTimeOfDay, IntervalUnit intervalUnit, int repeatInterval) { this(name, null, startTimeOfDay, endTimeOfDay, intervalUnit, repeatInterval); } /** *

* Create a DailyTimeIntervalTrigger that will occur immediately, and * repeat at the the given interval. *

* * @param startTimeOfDay * The TimeOfDay that the repeating should begin occurring. * @param endTimeOfDay * The TimeOfDay that the repeating should stop occurring. * @param intervalUnit The repeat interval unit. The only intervals that are valid for this type of trigger are * {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}. * @throws IllegalArgumentException if an invalid IntervalUnit is given, or the repeat interval is zero or less. */ public DailyTimeIntervalTriggerImpl(String name, String group, TimeOfDay startTimeOfDay, TimeOfDay endTimeOfDay, IntervalUnit intervalUnit, int repeatInterval) { this(name, group, new Date(), null, startTimeOfDay, endTimeOfDay, intervalUnit, repeatInterval); } /** *

* Create a DailyTimeIntervalTrigger that will occur at the given time, * and repeat at the the given interval 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 startTimeOfDay * The TimeOfDay that the repeating should begin occurring. * @param endTimeOfDay * The TimeOfDay that the repeating should stop occurring. * @param intervalUnit The repeat interval unit. The only intervals that are valid for this type of trigger are * {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}. * @param repeatInterval * The number of milliseconds to pause between the repeat firing. * @throws IllegalArgumentException if an invalid IntervalUnit is given, or the repeat interval is zero or less. */ public DailyTimeIntervalTriggerImpl(String name, Date startTime, Date endTime, TimeOfDay startTimeOfDay, TimeOfDay endTimeOfDay, IntervalUnit intervalUnit, int repeatInterval) { this(name, null, startTime, endTime, startTimeOfDay, endTimeOfDay, intervalUnit, repeatInterval); } /** *

* Create a DailyTimeIntervalTrigger that will occur at the given time, * and repeat at the the given interval 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 startTimeOfDay * The TimeOfDay that the repeating should begin occurring. * @param endTimeOfDay * The TimeOfDay that the repeating should stop occurring. * @param intervalUnit The repeat interval unit. The only intervals that are valid for this type of trigger are * {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}. * @param repeatInterval * The number of milliseconds to pause between the repeat firing. * @throws IllegalArgumentException if an invalid IntervalUnit is given, or the repeat interval is zero or less. */ public DailyTimeIntervalTriggerImpl(String name, String group, Date startTime, Date endTime, TimeOfDay startTimeOfDay, TimeOfDay endTimeOfDay, IntervalUnit intervalUnit, int repeatInterval) { super(name, group); setStartTime(startTime); setEndTime(endTime); setRepeatIntervalUnit(intervalUnit); setRepeatInterval(repeatInterval); setStartTimeOfDay(startTimeOfDay); setEndTimeOfDay(endTimeOfDay); } /** *

* Create a DailyTimeIntervalTrigger that will occur at the given time, * fire the identified Job and repeat at the the given * interval 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 startTimeOfDay * The TimeOfDay that the repeating should begin occurring. * @param endTimeOfDay * The TimeOfDay that the repeating should stop occurring. * @param intervalUnit The repeat interval unit. The only intervals that are valid for this type of trigger are * {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}. * @param repeatInterval * The number of milliseconds to pause between the repeat firing. * @throws IllegalArgumentException if an invalid IntervalUnit is given, or the repeat interval is zero or less. */ public DailyTimeIntervalTriggerImpl(String name, String group, String jobName, String jobGroup, Date startTime, Date endTime, TimeOfDay startTimeOfDay, TimeOfDay endTimeOfDay, IntervalUnit intervalUnit, int repeatInterval) { super(name, group, jobName, jobGroup); setStartTime(startTime); setEndTime(endTime); setRepeatIntervalUnit(intervalUnit); setRepeatInterval(repeatInterval); setStartTimeOfDay(startTimeOfDay); setEndTimeOfDay(endTimeOfDay); } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Get the time at which the DailyTimeIntervalTrigger should occur. It defaults to * the getStartTimeOfDay of current day. *

*/ @Override public Date getStartTime() { if(startTime == null) { startTime = new Date(); } return startTime; } /** *

* Set the time at which the DailyTimeIntervalTrigger should occur. *

* * @exception IllegalArgumentException * if startTime is null. */ @Override public void setStartTime(Date startTime) { if (startTime == null) { throw new IllegalArgumentException("Start time cannot be null"); } Date eTime = getEndTime(); if (eTime != null && eTime.before(startTime)) { throw new IllegalArgumentException( "End time cannot be before start time"); } this.startTime = startTime; } /** *

* Get the time at which the DailyTimeIntervalTrigger should quit * repeating. *

* * @see #getFinalFireTime() */ @Override public Date getEndTime() { return endTime; } /** *

* Set the time at which the DailyTimeIntervalTrigger should quit * repeating (and be automatically deleted). *

* * @exception IllegalArgumentException * if endTime is before start time. */ @Override 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; } /* (non-Javadoc) * @see io.logspace.agent.shaded.quartz.DailyTimeIntervalTriggerI#getRepeatIntervalUnit() */ public IntervalUnit getRepeatIntervalUnit() { return repeatIntervalUnit; } /** *

Set the interval unit - the time unit on with the interval applies.

* * @param intervalUnit The repeat interval unit. The only intervals that are valid for this type of trigger are * {@link IntervalUnit#SECOND}, {@link IntervalUnit#MINUTE}, and {@link IntervalUnit#HOUR}. */ public void setRepeatIntervalUnit(IntervalUnit intervalUnit) { if (repeatIntervalUnit == null || !((repeatIntervalUnit.equals(IntervalUnit.SECOND) || repeatIntervalUnit.equals(IntervalUnit.MINUTE) || repeatIntervalUnit.equals(IntervalUnit.HOUR)))) throw new IllegalArgumentException("Invalid repeat IntervalUnit (must be SECOND, MINUTE or HOUR)."); this.repeatIntervalUnit = intervalUnit; } /* (non-Javadoc) * @see io.logspace.agent.shaded.quartz.DailyTimeIntervalTriggerI#getRepeatInterval() */ public int getRepeatInterval() { return repeatInterval; } /** *

* set the the time interval that will be added to the DailyTimeIntervalTrigger's * fire time (in the set repeat interval unit) in order to calculate the time of the * next trigger repeat. *

* * @exception IllegalArgumentException * if repeatInterval is < 1 */ public void setRepeatInterval( int repeatInterval) { if (repeatInterval < 0) { throw new IllegalArgumentException( "Repeat interval must be >= 1"); } this.repeatInterval = repeatInterval; } /* (non-Javadoc) * @see io.logspace.agent.shaded.quartz.DailyTimeIntervalTriggerI#getTimesTriggered() */ public int getTimesTriggered() { return timesTriggered; } /** *

* Set the number of times the DailyTimeIntervalTrigger has already * fired. *

*/ public void setTimesTriggered(int timesTriggered) { this.timesTriggered = timesTriggered; } @Override protected boolean validateMisfireInstruction(int misfireInstruction) { return misfireInstruction >= MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY && misfireInstruction <= MISFIRE_INSTRUCTION_DO_NOTHING; } /** *

* Updates the DailyTimeIntervalTrigger's state based on the * MISFIRE_INSTRUCTION_XXX that was selected when the DailyTimeIntervalTrigger * 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 *
*

*/ @Override public void updateAfterMisfire(io.logspace.agent.shaded.quartz.Calendar cal) { int instr = getMisfireInstruction(); if(instr == Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY) return; 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) { // fire once now... setNextFireTime(new Date()); // the new fire time afterward will magically preserve the original // time of day for firing for day/week/month interval triggers, // because of the way getFireTimeAfter() works - in its always restarting // computation from the start time. } } /** *

* 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) */ @Override public void triggered(io.logspace.agent.shaded.quartz.Calendar calendar) { timesTriggered++; previousFireTime = nextFireTime; nextFireTime = getFireTimeAfter(nextFireTime); while (nextFireTime != null && calendar != null && !calendar.isTimeIncluded(nextFireTime.getTime())) { nextFireTime = getFireTimeAfter(nextFireTime); if(nextFireTime == null) break; //avoid infinite loop java.util.Calendar c = java.util.Calendar.getInstance(); c.setTime(nextFireTime); if (c.get(java.util.Calendar.YEAR) > YEAR_TO_GIVEUP_SCHEDULING_AT) { nextFireTime = null; } } if (nextFireTime == null) { complete = true; } } /** * @see io.logspace.agent.shaded.quartz.impl.triggers.AbstractTrigger#updateWithNewCalendar(io.logspace.agent.shaded.quartz.Calendar, long) */ @Override public void updateWithNewCalendar(io.logspace.agent.shaded.quartz.Calendar calendar, long misfireThreshold) { nextFireTime = getFireTimeAfter(previousFireTime); if (nextFireTime == null || calendar == null) { return; } Date now = new Date(); while (nextFireTime != null && !calendar.isTimeIncluded(nextFireTime.getTime())) { nextFireTime = getFireTimeAfter(nextFireTime); if(nextFireTime == null) break; //avoid infinite loop java.util.Calendar c = java.util.Calendar.getInstance(); c.setTime(nextFireTime); if (c.get(java.util.Calendar.YEAR) > YEAR_TO_GIVEUP_SCHEDULING_AT) { nextFireTime = null; } if(nextFireTime != null && nextFireTime.before(now)) { long diff = now.getTime() - nextFireTime.getTime(); if(diff >= misfireThreshold) { nextFireTime = getFireTimeAfter(nextFireTime); } } } } /** *

* 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). *

*/ @Override public Date computeFirstFireTime(io.logspace.agent.shaded.quartz.Calendar calendar) { Date sTime = getStartTime(); Date startTimeOfDayDate = getStartTimeOfDay().getTimeOfDayForDate(sTime); if(DateBuilder.evenSecondDate(startTime).equals(startTimeOfDayDate)) { return startTime; } else if (sTime.after(startTimeOfDayDate)) { // If startTime is after the timeOfDay, then look for the next time nextFireTime = getFireTimeAfter(sTime); } else { // If startTime is before the timeOfDay then advance to timeOfDay (and if necessary dayOfWeek) nextFireTime = advanceToNextDayOfWeekIfNecessary(startTimeOfDayDate, false); } // Check calendar for date-time exclusion while (nextFireTime != null && calendar != null && !calendar.isTimeIncluded(nextFireTime.getTime())) { nextFireTime = getFireTimeAfter(nextFireTime); if(nextFireTime == null) break; //avoid infinite loop java.util.Calendar c = java.util.Calendar.getInstance(); c.setTime(nextFireTime); if (c.get(java.util.Calendar.YEAR) > YEAR_TO_GIVEUP_SCHEDULING_AT) { return null; } } return nextFireTime; } private Calendar createCalendarTime(Date dateTime) { Calendar cal = Calendar.getInstance(); cal.setTime(dateTime); return cal; } /** *

* 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. *

*/ @Override public Date getNextFireTime() { return nextFireTime; } /** *

* Returns the previous time at which the DailyTimeIntervalTrigger * fired. If the trigger has not yet fired, null will be * returned. */ @Override public Date getPreviousFireTime() { return previousFireTime; } /** *

* Set the next time at which the DailyTimeIntervalTrigger 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 DailyTimeIntervalTrigger 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 DailyTimeIntervalTrigger will * fire, after the given time. If the trigger will not fire after the given * time, null will be returned. *

*/ @Override public Date getFireTimeAfter(Date afterTime) { // Check if trigger has completed or not. if (complete) { return null; } // Check repeatCount limit if (repeatCount != REPEAT_INDEFINITELY && timesTriggered > repeatCount) { return null; } // a. Increment afterTime by a second, so that we are comparing against a time after it! if (afterTime == null) { afterTime = new Date(System.currentTimeMillis() + 1000L); } else { afterTime = new Date(afterTime.getTime() + 1000L); } // make sure afterTime is at least startTime if(afterTime.before(startTime)) afterTime = startTime; // b.Check to see if afterTime is after endTimeOfDay or not. If yes, then we need to advance to next day as well. boolean afterTimePastEndTimeOfDay = false; if (endTimeOfDay != null) { afterTimePastEndTimeOfDay = afterTime.getTime() > endTimeOfDay.getTimeOfDayForDate(afterTime).getTime(); } // c. now we need to move move to the next valid day of week if either: // the given time is past the end time of day, or given time is not on a valid day of week Date fireTime = advanceToNextDayOfWeekIfNecessary(afterTime, afterTimePastEndTimeOfDay); if (fireTime == null) return null; // d. Calculate and save fireTimeEndDate variable for later use Date fireTimeEndDate = null; if (endTimeOfDay == null) fireTimeEndDate = new TimeOfDay(23, 59, 59).getTimeOfDayForDate(fireTime); else fireTimeEndDate = endTimeOfDay.getTimeOfDayForDate(fireTime); // e. Check fireTime against startTime or startTimeOfDay to see which go first. Date fireTimeStartDate = startTimeOfDay.getTimeOfDayForDate(fireTime); if (fireTime.before(fireTimeStartDate)) { return fireTimeStartDate; } // f. Continue to calculate the fireTime by incremental unit of intervals. // recall that if fireTime was less that fireTimeStartDate, we didn't get this far long fireMillis = fireTime.getTime(); long startMillis = fireTimeStartDate.getTime(); long secondsAfterStart = (fireMillis - startMillis) / 1000L; long repeatLong = getRepeatInterval(); Calendar sTime = createCalendarTime(fireTimeStartDate); IntervalUnit repeatUnit = getRepeatIntervalUnit(); if(repeatUnit.equals(IntervalUnit.SECOND)) { long jumpCount = secondsAfterStart / repeatLong; if(secondsAfterStart % repeatLong != 0) jumpCount++; sTime.add(Calendar.SECOND, getRepeatInterval() * (int)jumpCount); fireTime = sTime.getTime(); } else if(repeatUnit.equals(IntervalUnit.MINUTE)) { long jumpCount = secondsAfterStart / (repeatLong * 60L); if(secondsAfterStart % (repeatLong * 60L) != 0) jumpCount++; sTime.add(Calendar.MINUTE, getRepeatInterval() * (int)jumpCount); fireTime = sTime.getTime(); } else if(repeatUnit.equals(IntervalUnit.HOUR)) { long jumpCount = secondsAfterStart / (repeatLong * 60L * 60L); if(secondsAfterStart % (repeatLong * 60L * 60L) != 0) jumpCount++; sTime.add(Calendar.HOUR_OF_DAY, getRepeatInterval() * (int)jumpCount); fireTime = sTime.getTime(); } // g. Ensure this new fireTime is within the day, or else we need to advance to next day. if (fireTime.after(fireTimeEndDate)) { fireTime = advanceToNextDayOfWeekIfNecessary(fireTime, isSameDay(fireTime, fireTimeEndDate)); // make sure we hit the startTimeOfDay on the new day fireTime = startTimeOfDay.getTimeOfDayForDate(fireTime); } // i. Return calculated fireTime. return fireTime; } private boolean isSameDay(Date d1, Date d2) { Calendar c1 = createCalendarTime(d1); Calendar c2 = createCalendarTime(d2); return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) && c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR); } /** * Given fireTime time determine if it is on a valid day of week. If so, simply return it unaltered, * if not, advance to the next valid week day, and set the time of day to the start time of day * * @param fireTime - given next fireTime. * @param forceToAdvanceNextDay - flag to whether to advance day without check existing week day. This scenario * can happen when a caller determine fireTime has passed the endTimeOfDay that fireTime should move to next day anyway. * @return a next day fireTime. */ private Date advanceToNextDayOfWeekIfNecessary(Date fireTime, boolean forceToAdvanceNextDay) { // a. Advance or adjust to next dayOfWeek if need to first, starting next day with startTimeOfDay. TimeOfDay sTimeOfDay = getStartTimeOfDay(); Date fireTimeStartDate = sTimeOfDay.getTimeOfDayForDate(fireTime); Calendar fireTimeStartDateCal = createCalendarTime(fireTimeStartDate); int dayOfWeekOfFireTime = fireTimeStartDateCal.get(Calendar.DAY_OF_WEEK); // b2. We need to advance to another day if isAfterTimePassEndTimeOfDay is true, or dayOfWeek is not set. Set daysOfWeekToFire = getDaysOfWeek(); if (forceToAdvanceNextDay || !daysOfWeekToFire.contains(dayOfWeekOfFireTime)) { // Advance one day at a time until next available date. for(int i=1; i <= 7; i++) { fireTimeStartDateCal.add(Calendar.DATE, 1); dayOfWeekOfFireTime = fireTimeStartDateCal.get(Calendar.DAY_OF_WEEK); if (daysOfWeekToFire.contains(dayOfWeekOfFireTime)) { fireTime = fireTimeStartDateCal.getTime(); break; } } } // Check fireTime not pass the endTime Date eTime = getEndTime(); if (eTime != null && fireTime.getTime() > eTime.getTime()) { return null; } return fireTime; } /** *

* Returns the final time at which the DailyTimeIntervalTrigger will * fire, if there is no end time set, null will be returned. *

* *

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

*/ @Override public Date getFinalFireTime() { if (complete || getEndTime() == null) { return null; } // We have an endTime, we still need to check to see if there is a endTimeOfDay if that's applicable. Date eTime = getEndTime(); if (endTimeOfDay != null) { Date endTimeOfDayDate = endTimeOfDay.getTimeOfDayForDate(eTime); if (eTime.getTime() < endTimeOfDayDate.getTime()) { eTime = endTimeOfDayDate; } } return eTime; } /** *

* Determines whether or not the DailyTimeIntervalTrigger will occur * again. *

*/ @Override 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. */ @Override public void validate() throws SchedulerException { super.validate(); if (repeatIntervalUnit == null || !(repeatIntervalUnit.equals(IntervalUnit.SECOND) || repeatIntervalUnit.equals(IntervalUnit.MINUTE) ||repeatIntervalUnit.equals(IntervalUnit.HOUR))) throw new SchedulerException("Invalid repeat IntervalUnit (must be SECOND, MINUTE or HOUR)."); if (repeatInterval < 1) { throw new SchedulerException("Repeat Interval cannot be zero."); } // Ensure interval does not exceed 24 hours long secondsInHour = 24 * 60 * 60L; if (repeatIntervalUnit == IntervalUnit.SECOND && repeatInterval > secondsInHour) { throw new SchedulerException("repeatInterval can not exceed 24 hours (" + secondsInHour + " seconds). Given " + repeatInterval); } if (repeatIntervalUnit == IntervalUnit.MINUTE && repeatInterval > secondsInHour / 60L) { throw new SchedulerException("repeatInterval can not exceed 24 hours (" + secondsInHour / 60L + " minutes). Given " + repeatInterval); } if (repeatIntervalUnit == IntervalUnit.HOUR && repeatInterval > 24 ) { throw new SchedulerException("repeatInterval can not exceed 24 hours. Given " + repeatInterval + " hours."); } // Ensure timeOfDay is in order. if (getEndTimeOfDay() != null && !getStartTimeOfDay().before(getEndTimeOfDay())) { throw new SchedulerException("StartTimeOfDay " + startTimeOfDay + " should not come after endTimeOfDay " + endTimeOfDay); } } /** * {@inheritDoc} */ public Set getDaysOfWeek() { if (daysOfWeek == null) { daysOfWeek = DailyTimeIntervalScheduleBuilder.ALL_DAYS_OF_THE_WEEK; } return daysOfWeek; } public void setDaysOfWeek(Set daysOfWeek) { if(daysOfWeek == null || daysOfWeek.size() == 0) throw new IllegalArgumentException("DaysOfWeek set must be a set that contains at least one day."); else if(daysOfWeek.size() == 0) throw new IllegalArgumentException("DaysOfWeek set must contain at least one day."); this.daysOfWeek = daysOfWeek; } /** * {@inheritDoc} */ public TimeOfDay getStartTimeOfDay() { if (startTimeOfDay == null) { startTimeOfDay = new TimeOfDay(0, 0, 0); } return startTimeOfDay; } public void setStartTimeOfDay(TimeOfDay startTimeOfDay) { if (startTimeOfDay == null) { throw new IllegalArgumentException("Start time of day cannot be null"); } TimeOfDay eTime = getEndTimeOfDay(); if (eTime != null && eTime.before(startTimeOfDay)) { throw new IllegalArgumentException( "End time of day cannot be before start time of day"); } this.startTimeOfDay = startTimeOfDay; } /** * {@inheritDoc} */ public TimeOfDay getEndTimeOfDay() { return endTimeOfDay; } public void setEndTimeOfDay(TimeOfDay endTimeOfDay) { if (endTimeOfDay == null) throw new IllegalArgumentException("End time of day cannot be null"); TimeOfDay sTime = getStartTimeOfDay(); if (sTime != null && endTimeOfDay.before(endTimeOfDay)) { throw new IllegalArgumentException( "End time of day cannot be before start time of day"); } this.endTimeOfDay = endTimeOfDay; } /** * Get a {@link ScheduleBuilder} that is configured to produce a * schedule identical to this trigger's schedule. * * @see #getTriggerBuilder() */ @Override public ScheduleBuilder getScheduleBuilder() { DailyTimeIntervalScheduleBuilder cb = DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule() .withInterval(getRepeatInterval(), getRepeatIntervalUnit()) .onDaysOfTheWeek(getDaysOfWeek()).startingDailyAt(getStartTimeOfDay()).endingDailyAt(getEndTimeOfDay()); switch(getMisfireInstruction()) { case MISFIRE_INSTRUCTION_DO_NOTHING : cb.withMisfireHandlingInstructionDoNothing(); break; case MISFIRE_INSTRUCTION_FIRE_ONCE_NOW : cb.withMisfireHandlingInstructionFireAndProceed(); break; } return cb; } /** This trigger has no additional properties besides what's defined in this class. */ public boolean hasAdditionalProperties() { return false; } public int getRepeatCount() { return repeatCount; } 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; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy