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

org.kie.kogito.timer.impl.CronTrigger Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.kie.kogito.timer.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.kie.kogito.timer.Calendars;
import org.kie.kogito.timer.Trigger;

public class CronTrigger
        implements
        Trigger {

    protected static final int YEAR_TO_GIVEUP_SCHEDULING_AT = 2299;
    private static final long serialVersionUID = -332085070627193383L;

    private CronExpression cronEx = null;
    private Date startTime = null;
    private Date endTime = null;
    private int repeatLimit;
    private int repeatCount;
    private Date nextFireTime = null;
    private Date previousFireTime = null;
    private transient TimeZone timeZone = null;
    private String[] calendarNames;
    private Calendars calendars;

    public CronTrigger() {

    }

    public CronTrigger(long timestamp,
            Date startTime,
            Date endTime,
            int repeatLimit,
            String cronExpression,
            String[] calendarNames,
            Calendars calendars) {
        this(timestamp,
                startTime,
                endTime,
                repeatLimit,
                determineCronExpression(cronExpression),
                calendarNames,
                calendars);
    }

    public CronTrigger(long timestamp,
            Date startTime,
            Date endTime,
            int repeatLimit,
            CronExpression cronExpression,
            String[] calendarNames,
            Calendars calendars) {
        setCronExpression(cronExpression);

        this.repeatLimit = repeatLimit;

        if (startTime == null) {
            startTime = new Date(timestamp);
        }
        setStartTime(startTime);

        if (endTime != null) {
            setEndTime(endTime);
        }
        setTimeZone(TimeZone.getDefault());

        // Set the first FireTime, this is sensitive to StartTime
        this.nextFireTime = new Date(timestamp);
        setFirstFireTimeAfter();

        this.calendarNames = calendarNames;
        this.calendars = calendars;

        // Update to next include time, if we have calendars
        updateToNextIncludeDate();
    }

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

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

*/ public Date getNextFireTime() { return this.nextFireTime; } /** *

* Returns the previous time at which the CronTrigger * fired. 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 CronTrigger 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 (this.cronEx != null) { return this.cronEx.getTimeZone(); } if (this.timeZone == null) { this.timeZone = TimeZone.getDefault(); } return this.timeZone; } /** *

* Sets the time zone for which the cronExpression of this * CronTrigger will be resolved. *

* *

* If {@link #setCronExpression(CronExpression)} is called after this * method, the TimeZon setting on the CronExpression will "win". However * if {@link #setCronExpression(String)} is called after this method, the * time zone applied by this method will remain in effect, since the * String cron expression does not carry a time zone! */ public void setTimeZone(TimeZone timeZone) { if (this.cronEx != null) { this.cronEx.setTimeZone(timeZone); } this.timeZone = timeZone; } public void setCronExpression(String cronExpression) { setCronExpression(determineCronExpression(cronExpression)); } public void setCronExpression(CronExpression cronExpression) { TimeZone origTz = getTimeZone(); this.cronEx = cronExpression; this.cronEx.setTimeZone(origTz); } public CronExpression getCronEx() { return cronEx; } public void setCronEx(CronExpression cronEx) { this.cronEx = cronEx; } public int getRepeatLimit() { return repeatLimit; } public void setRepeatLimit(int repeatLimit) { this.repeatLimit = repeatLimit; } public int getRepeatCount() { return repeatCount; } public void setRepeatCount(int repeatCount) { this.repeatCount = repeatCount; } public String[] getCalendarNames() { return calendarNames; } public void setCalendarNames(String[] calendarNames) { this.calendarNames = calendarNames; } public Calendars getCalendars() { return calendars; } public void setCalendars(Calendars calendars) { this.calendars = calendars; } public static CronExpression determineCronExpression(String cronExpression) { try { return new CronExpression(cronExpression); } catch (Exception e) { throw new RuntimeException("Unable to parse cron expression '" + cronExpression + "'", e); } } public Date hasNextFireTime() { return this.nextFireTime; } public synchronized Date nextFireTime() { if (this.nextFireTime == null) { return null; } Date date = new Date(this.nextFireTime.getTime() - 1000L); this.nextFireTime = getTimeAfter(this.nextFireTime); updateToNextIncludeDate(); if (this.endTime != null && this.nextFireTime.after(this.endTime)) { this.nextFireTime = null; } else if (repeatLimit != -1 && repeatCount >= repeatLimit) { this.nextFireTime = null; } return date; } /** *

* 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 void setFirstFireTimeAfter() { if (getStartTime().after(this.nextFireTime)) { this.nextFireTime = new Date(getStartTime().getTime() - 1000l); } if (getEndTime() != null && (this.nextFireTime.compareTo(getEndTime()) >= 0)) { this.nextFireTime = null; } Date pot = getTimeAfter(this.nextFireTime); if (getEndTime() != null && pot != null && pot.after(getEndTime())) { this.nextFireTime = null; } else { this.nextFireTime = pot; } } protected Date getTimeAfter(Date afterTime) { this.repeatCount++; return (this.cronEx == null) ? null : this.cronEx.getTimeAfter(afterTime); } public void updateToNextIncludeDate() { if (this.calendars == null || calendarNames == null || calendarNames.length == 0) { // There are no assigned calendars return; } // If we have calendars, check we can fire, or get next time until we can fire. while (this.nextFireTime != null && (this.endTime == null || this.nextFireTime.before(this.endTime))) { // this will loop forever if the trigger repeats forever and // included calendar position cannot be found boolean included = true; for (String calName : this.calendarNames) { // all calendars must not block, as soon as one blocks break, so we can check next time slot org.kie.kogito.timer.Calendar cal = this.calendars.get(calName); if (cal != null && !cal.isTimeIncluded(this.nextFireTime.getTime())) { included = false; break; } } if (included) { // if no calendars blocked, break break; } else { // otherwise increase the time and try again this.nextFireTime = getTimeAfter(this.nextFireTime); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy