Package org.quartz

Source Code of org.quartz.DailyTimeIntervalScheduleBuilder

/*
* 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.
*
* <p>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.
* <p>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!
* <p>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
* <code>TriggerBuilder</code>, <code>JobBuilder</code>,
* <code>DateBuilder</code>, <code>JobKey</code>, <code>TriggerKey</code>
* and the various <code>ScheduleBuilder</code> implementations.</p>
*
* <p>Client code can then use the DSL to write code such as this:</p>
* <pre>
*         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);
* <pre>
*  
* @since 2.1.0
*
* @author James House
* @author Zemian Deng <saltnlight5@gmail.com>
*/
public class DailyTimeIntervalScheduleBuilder extends ScheduleBuilder<DailyTimeIntervalTrigger> {

    private int interval = 1;
    private IntervalUnit intervalUnit = IntervalUnit.MINUTE;
    private Set<Integer> 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<Integer> 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<Integer> 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<Integer> SATURDAY_AND_SUNDAY;
   
    static {
        Set<Integer> t = new HashSet<Integer>(7);
        for(int i=Calendar.SUNDAY; i <= Calendar.SATURDAY; i++)
            t.add(i);
        ALL_DAYS_OF_THE_WEEK = Collections.unmodifiableSet(t);
       
        t = new HashSet<Integer>(5);
        for(int i=Calendar.MONDAY; i <= Calendar.FRIDAY; i++)
            t.add(i);
        MONDAY_THROUGH_FRIDAY = Collections.unmodifiableSet(t);
       
        t = new HashSet<Integer>(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<Integer> 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<Integer> daysAsSet = new HashSet<Integer>(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.
     *
     * <p>Note: if you want total count = 1 (at start time) + repeatCount</p>
     *
     * @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.");
    }
}
TOP

Related Classes of org.quartz.DailyTimeIntervalScheduleBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.