/* Copyright 1999-2008 Acelet.org. All rights reserved. GPL v2 license */
/** @author Wei Jiang */
package com.acelet.s.task;
import java.io.*;
import java.util.*;
import com.acelet.lib.Common;
import com.acelet.lib.InvalidDataException;
import com.acelet.lib.Phrase;
import com.acelet.s.job.AbstractTask;
public abstract class TaskBase implements AbstractTask, TaskConstants {
public static final String DEFAULT_HOLIDAY_SET_NAME = " ";
static int runTimeTolerance = 10 * 1000;
long id;
/**
* <em>name</em> is the name of the task.
*/
public String name = "";
String job;
int jobType = NOT_SPECIFIED;
int repeating = NOT_SPECIFIED;
long startTime = NOT_SPECIFIED;
int minutelyPeriod = NOT_SPECIFIED;
int hourlyPeriod = NOT_SPECIFIED;
int dailyPeriod = NOT_SPECIFIED;
int weeklyPeriod = NOT_SPECIFIED;
int weeklyWeekDay = NOT_SPECIFIED;
int monthlyPeriod = NOT_SPECIFIED;
int monthlyTheDay = NOT_SPECIFIED;
int monthlyWhichWeek = NOT_SPECIFIED;
int monthlyWhichWeekWeekDay = NOT_SPECIFIED;
String specifiedTimes = null;
long wouldBe = NOT_SPECIFIED;
int holidayPolicy = HOLIDAY_POLICY_SAME;
String holidaySet = DEFAULT_HOLIDAY_SET_NAME;
long expiration = Long.MAX_VALUE;
/**
* <em>duration</em> is the expected duration of execute time.
*/
public long duration = NOT_SPECIFIED;
/**
* <em>killIfExceedsDuration</em> is a flag. If it is set (value 1) and the
* actual execution time exceeds expected duration, the running task will be killed.
* <br>Value 1: true; value 0: false.
*/
public int killIfExceedsDuration = 0;
/**
* <em>hostname</em> is the desired computer name to run this task. If it is
* not defined, any computer can run this job.
*/
public String hostname = "";
/**
* <em>club</em> is the group this job belongs to.
*/
public String club = "";
/**
* <em>description</em> is for human reading.
*/
public String description = "";
/**
* <em>comments</em> is for human reading.
*/
public String comments = "";
/**
* <em>status</em> is the status of this task.
*/
public int status = STATUS_ACTIVE;
long nextRunTime = NOT_SPECIFIED;
/**
* <em>lastRunTime</em> is the last time this task was running.
*/
public long lastRunTime = NOT_SPECIFIED;
String creator = System.getProperty("user.name");
/**
* <em>alarmEmail</em> is the email address for alarm.
*/
public String alarmEmail = "";
long modifiedAt = System.currentTimeMillis();
transient int year = NOT_SPECIFIED;
transient int month = NOT_SPECIFIED;
transient int day = NOT_SPECIFIED;
transient int hour = NOT_SPECIFIED;
transient int minute = NOT_SPECIFIED;
transient String minutesPartOfSpecifiedTimes;
transient String hoursPartOfSpecifiedTimes;
transient String monthdaysPartOfSpecifiedTimes;
transient String monthsPartOfSpecifiedTimes;
transient String weekdaysPartOfSpecifiedTimes;
public TaskBase() {
}
public static boolean contains(String subExpression, int number) {
if (subExpression.equals("*"))
return true;
String numberString = number + "";
StringTokenizer st = new StringTokenizer(subExpression, ",");
while (st.hasMoreTokens()) {
if (st.nextToken().equals(numberString))
return true;
}
return false;
}
static boolean containsMonthday(String subExpression, int day, int lastDayOfMonth) {
if (contains(subExpression, day))
return true;
if((day == lastDayOfMonth) && contains(subExpression, 32))
return true;
return false;
}
public void fromHashtable(Hashtable hashtable) {
Long idLong = (Long) hashtable.get("id");
if (idLong != null)
id = idLong.longValue();
name = (String) hashtable.get("name");
job = (String) hashtable.get("job");
Integer jobTypeInt = (Integer) hashtable.get("jobType");
if (jobTypeInt != null)
jobType = jobTypeInt.intValue();
Integer repeatingInt = (Integer) hashtable.get("repeating");
if (repeatingInt != null)
repeating = repeatingInt.intValue();
Long startTimeLong = (Long) hashtable.get("startTime");
if (startTimeLong != null)
startTime = startTimeLong.longValue();
Integer minutelyPeriodInt = (Integer) hashtable.get("minutelyPeriod");
if (minutelyPeriodInt != null)
minutelyPeriod = minutelyPeriodInt.intValue();
Integer hourlyPeriodInt = (Integer) hashtable.get("hourlyPeriod");
if (hourlyPeriodInt != null)
hourlyPeriod = hourlyPeriodInt.intValue();
Integer dailyPeriodInt = (Integer) hashtable.get("dailyPeriod");
if (dailyPeriodInt != null)
dailyPeriod = dailyPeriodInt.intValue();
Integer weeklyPeriodInt = (Integer) hashtable.get("weeklyPeriod");
if (weeklyPeriodInt != null)
weeklyPeriod = weeklyPeriodInt.intValue();
Integer weeklyWeekDayInt = (Integer) hashtable.get("weeklyWeekDay");
if (weeklyWeekDayInt != null)
weeklyWeekDay = weeklyWeekDayInt.intValue();
Integer monthlyPeriodInt = (Integer) hashtable.get("monthlyPeriod");
if (monthlyPeriodInt != null)
monthlyPeriod = monthlyPeriodInt.intValue();
Integer monthlyTheDayInt = (Integer) hashtable.get("monthlyTheDay");
if (monthlyTheDayInt != null)
monthlyTheDay = monthlyTheDayInt.intValue();
Integer monthlyWhichWeekInt = (Integer) hashtable.get("monthlyWhichWeek");
if (monthlyWhichWeekInt != null)
monthlyWhichWeek = monthlyWhichWeekInt.intValue();
Integer monthlyWhichWeekWeekDayInt =
(Integer) hashtable.get("monthlyWhichWeekWeekDay");
if (monthlyWhichWeekWeekDayInt != null)
monthlyWhichWeekWeekDay = monthlyWhichWeekWeekDayInt.intValue();
specifiedTimes = (String) hashtable.get("specifiedTimes");
Long wouldBeLong = (Long) hashtable.get("wouldBe");
if (wouldBeLong != null)
wouldBe = wouldBeLong.longValue();
Integer holidayPolicyInt = (Integer) hashtable.get("holidayPolicy");
if (holidayPolicyInt != null)
holidayPolicy = holidayPolicyInt.intValue();
holidaySet = (String) hashtable.get("holidaySet");
Long expirationLong = (Long) hashtable.get("expiration");
if (expirationLong != null)
expiration = expirationLong.longValue();
Long durationLong = (Long) hashtable.get("duration");
if (durationLong != null)
duration = durationLong.longValue();
Integer killIfExceedsDurationInt = (Integer) hashtable.get("killIfExceedsDuration");
if (killIfExceedsDurationInt != null)
killIfExceedsDuration = killIfExceedsDurationInt.intValue();
hostname = (String) hashtable.get("hostname");
club = (String) hashtable.get("club");
description = (String) hashtable.get("description");
comments = (String) hashtable.get("comments");
Integer statusInt = (Integer) hashtable.get("status");
if (statusInt != null)
status = statusInt.intValue();
Long nextRunTimeLong = (Long) hashtable.get("nextRunTime");
if (nextRunTimeLong != null)
nextRunTime = nextRunTimeLong.longValue();
Long lastRunTimeLong = (Long) hashtable.get("lastRunTime");
if (lastRunTimeLong != null)
lastRunTime = lastRunTimeLong.longValue();
creator = (String) hashtable.get("creator");
alarmEmail = (String) hashtable.get("alarmEmail");
Long modifiedAtLong = (Long) hashtable.get("modifiedAt");
if (modifiedAtLong != null)
modifiedAt = modifiedAtLong.longValue();
setStartTimeYMDHM();
parseSpecifiedTimes();
}
GregorianCalendar getCalculationCalendar(){
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setLenient(true);
if (wouldBe == NOT_SPECIFIED) {
gregorianCalendar.setTime(new Date(startTime));
gregorianCalendar.set(Calendar.HOUR_OF_DAY, hour);
gregorianCalendar.set(Calendar.MINUTE, minute);
gregorianCalendar.set(Calendar.SECOND, 0);
gregorianCalendar.set(Calendar.MILLISECOND, 0);
} else {
gregorianCalendar.setTime(new Date(wouldBe));
}
return gregorianCalendar;
}
GregorianCalendar getCalculationCalendarForSpecifiedTimes(){
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setLenient(true);
if (wouldBe == NOT_SPECIFIED) {
gregorianCalendar.setTime(new Date(startTime));
gregorianCalendar.set(Calendar.SECOND, 0);
gregorianCalendar.set(Calendar.MILLISECOND, 0);
} else {
gregorianCalendar.setTime(new Date(wouldBe));
}
return gregorianCalendar;
}
int getFirstEligibleHourForSpecifiedTime() {
int theHour = 0;
if (hoursPartOfSpecifiedTimes.equals("*"))
theHour = 0;
else {
StringTokenizer st = new StringTokenizer(hoursPartOfSpecifiedTimes, ",");
String hourText = st.nextToken();
theHour = Integer.parseInt(hourText.trim());
}
return theHour;
}
int getFirstEligibleMinuteForSpecifiedTime() {
int theMinute = 0;
if (minutesPartOfSpecifiedTimes.equals("*"))
theMinute = 0;
else {
StringTokenizer st = new StringTokenizer(minutesPartOfSpecifiedTimes, ",");
String minuteText = st.nextToken();
theMinute = Integer.parseInt(minuteText.trim());
}
return theMinute;
}
public int getLastDayInMonth(Calendar calendar) {
Calendar clone = (Calendar) calendar.clone();
clone.setLenient(true);
clone.add(Calendar.MONTH, 1);
clone.set(Calendar.DAY_OF_MONTH, 1);
clone.add(Calendar.DAY_OF_MONTH, -1);
return clone.get(Calendar.DAY_OF_MONTH);
}
int getLastDayOfMonth(int year, int month) {
GregorianCalendar cal = new GregorianCalendar(year, month, 1);
return getLastDayInMonth(cal);
}
GregorianCalendar getNextRunTimeCalendar() {
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setLenient(true);
gregorianCalendar.setTime(new Date(nextRunTime));
return gregorianCalendar;
}
int getWeekday(int year, int month, int day) {
GregorianCalendar cal = new GregorianCalendar(year, month, day);
return cal.get(Calendar.DAY_OF_WEEK);
}
public long getWouldBe() {
return wouldBe;
}
boolean isAdjustedNextRunTimeValid() throws Exception {
if (repeating == REPEATING_SUPER_SCHEDULER_STARTUP ||
repeating == REPEATING_IMMEDIATELY_ONCE ||
repeating == REPEATING_ONCALL ||
repeating == REPEATING_STANDBY)
return true;
if (nextRunTime == NOT_SPECIFIED)
return false;
else
return true;
}
public boolean isFutureRunnable() {
if (repeating == REPEATING_SUPER_SCHEDULER_STARTUP ||
repeating == REPEATING_IMMEDIATELY_ONCE ||
repeating == REPEATING_ONCALL ||
repeating == REPEATING_STANDBY)
return false;
if (status != STATUS_ACTIVE)
return false;
return true;
}
public boolean isMissed() {
if (status != STATUS_ACTIVE)
return false;
if (repeating == REPEATING_SUPER_SCHEDULER_STARTUP ||
repeating == REPEATING_IMMEDIATELY_ONCE ||
repeating == REPEATING_STANDBY ||
repeating == REPEATING_ONCALL)
return false;
long thisMoment = System.currentTimeMillis();
long lateRunTime = nextRunTime + runTimeTolerance;
if ((thisMoment - lateRunTime) > 0) {
return true;
} else
return false;
}
boolean isTheDayEligible(int aYear, int aMonth, int aDay) {
int lastDayOfMonth = getLastDayOfMonth(aYear, aMonth);
int aWeekday = getWeekday(aYear, aMonth, aDay);
if (monthdaysPartOfSpecifiedTimes.equals("*") &&
monthsPartOfSpecifiedTimes.equals("*") &&
weekdaysPartOfSpecifiedTimes.equals("*"))
return true;
if ((!monthdaysPartOfSpecifiedTimes.equals("*") || !monthsPartOfSpecifiedTimes.equals("*")) &&
weekdaysPartOfSpecifiedTimes.equals("*")) {
if (containsMonthday(monthdaysPartOfSpecifiedTimes, aDay, lastDayOfMonth))
return true;
}
if ((monthdaysPartOfSpecifiedTimes.equals("*") && monthsPartOfSpecifiedTimes.equals("*")) &&
(!weekdaysPartOfSpecifiedTimes.equals("*"))) {
if (contains(weekdaysPartOfSpecifiedTimes, aWeekday - 1)) {
return true;
}
}
if ((!monthdaysPartOfSpecifiedTimes.equals("*") || !monthsPartOfSpecifiedTimes.equals("*")) &&
(!weekdaysPartOfSpecifiedTimes.equals("*"))) {
if ((contains(monthsPartOfSpecifiedTimes, aMonth + 1) &&
containsMonthday(monthdaysPartOfSpecifiedTimes, aDay, lastDayOfMonth)) ||
contains(weekdaysPartOfSpecifiedTimes, aWeekday - 1)) {
return true;
}
}
return false;
}
long nextBusinessDayTime(long aTime) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date(aTime));
int anHour = cal.get(Calendar.HOUR_OF_DAY);
int aMinute = cal.get(Calendar.MINUTE);
GregorianCalendar nextBusinessDayCal =
new BusinessCalendar().getNextBusinessDay(aTime, holidaySet);
nextBusinessDayCal.set(Calendar.HOUR_OF_DAY, anHour);
nextBusinessDayCal.set(Calendar.MINUTE, aMinute);
return nextBusinessDayCal.getTime().getTime();
}
void parseSpecifiedTimes() {
if (specifiedTimes == null)
return;
StringTokenizer st = new StringTokenizer(specifiedTimes, " ");
minutesPartOfSpecifiedTimes = st.nextToken();
hoursPartOfSpecifiedTimes = st.nextToken();
monthdaysPartOfSpecifiedTimes = st.nextToken();
monthsPartOfSpecifiedTimes = st.nextToken();
weekdaysPartOfSpecifiedTimes = st.nextToken();
}
void printCalendar(GregorianCalendar calendar) {
System.out.println(
calendar.get(Calendar.YEAR) + ", " +
(calendar.get(Calendar.MONTH) + 1 ) + ", " +
calendar.get(Calendar.DAY_OF_MONTH) + ", " +
calendar.get(Calendar.HOUR_OF_DAY) + ", " +
calendar.get(Calendar.MINUTE) + ", " +
calendar.get(Calendar.SECOND) + ", " +
calendar.get(Calendar.MILLISECOND));
}
String printTime(long time) {
return new Date(time).toString();
}
void resetNotUsedTerm() {
if (repeating == REPEATING_ONCE) {
restPartOfTerm();
} else if (repeating == REPEATING_MINUTELY) {
int _minutelyPeriod = minutelyPeriod;
restPartOfTerm();
minutelyPeriod = _minutelyPeriod;
} else if (repeating == REPEATING_HOURLY) {
int _hourlyPeriod = hourlyPeriod;
restPartOfTerm();
hourlyPeriod = _hourlyPeriod;
} else if (repeating == REPEATING_DAILY) {
int _dailyPeriod = dailyPeriod;
restPartOfTerm();
dailyPeriod = _dailyPeriod;
} else if (repeating == REPEATING_WEEKLY) {
int _weeklyPeriod = weeklyPeriod;
int _weeklyWeekDay = weeklyWeekDay;
restPartOfTerm();
weeklyPeriod = _weeklyPeriod;
weeklyWeekDay = _weeklyWeekDay;
} else if (repeating == REPEATING_MONTHLY) {
int _monthlyPeriod = monthlyPeriod;
int _monthlyTheDay = monthlyTheDay;
restPartOfTerm();
monthlyPeriod = _monthlyPeriod;
monthlyTheDay = _monthlyTheDay;
} else if (repeating == REPEATING_WEEK_DAY_MONTHLY) {
int _monthlyPeriod = monthlyPeriod;
int _monthlyWhichWeek = monthlyWhichWeek;
int _monthlyWhichWeekWeekDay = monthlyWhichWeekWeekDay;
restPartOfTerm();
monthlyPeriod = _monthlyPeriod;
monthlyWhichWeek = _monthlyWhichWeek;
monthlyWhichWeekWeekDay = _monthlyWhichWeekWeekDay;
} else if (repeating == REPEATING_AT_SPECIFIED_TIMES) {
String _specifiedTimes = specifiedTimes;
restPartOfTerm();
specifiedTimes = _specifiedTimes;
} else if (repeating == REPEATING_SUPER_SCHEDULER_STARTUP) {
restPartOfTerm();
} else if (repeating == REPEATING_IMMEDIATELY_ONCE) {
restPartOfTerm();
} else if (repeating == REPEATING_STANDBY) {
restPartOfTerm();
}
}
void restPartOfTerm() {
minutelyPeriod = NOT_SPECIFIED;
hourlyPeriod = NOT_SPECIFIED;
dailyPeriod = NOT_SPECIFIED;
weeklyPeriod = NOT_SPECIFIED;
weeklyWeekDay = NOT_SPECIFIED;
monthlyPeriod = NOT_SPECIFIED;
monthlyTheDay = NOT_SPECIFIED;
monthlyWhichWeek = NOT_SPECIFIED;
monthlyWhichWeekWeekDay = NOT_SPECIFIED;
specifiedTimes = null;
}
public boolean setAdjustedNextRunTime() throws Exception {
long now = System.currentTimeMillis();
if (now == wouldBe) {
now += 1;
}
if (wouldBe == NOT_SPECIFIED && startTime > now)
setAdjustedNextRunTime(startTime);
else
setAdjustedNextRunTime(now);
return isAdjustedNextRunTimeValid();
}
public boolean setAdjustedNextRunTime(long baseTime) throws Exception {
if (repeating == REPEATING_SUPER_SCHEDULER_STARTUP ||
repeating == REPEATING_STANDBY){
nextRunTime = NOT_SPECIFIED;
return isAdjustedNextRunTimeValid();
}
if (repeating == REPEATING_ONCE) {
setNextRunTime(baseTime);
return isAdjustedNextRunTimeValid();
}
if (status != STATUS_ACTIVE) {
nextRunTime = NOT_SPECIFIED;
return isAdjustedNextRunTimeValid();
}
if (baseTime > startTime)
setNextRunTime(baseTime);
else {
setNextRunTime(startTime - 10000);
}
if (nextRunTime < startTime || nextRunTime > expiration) {
nextRunTime = NOT_SPECIFIED;
status = STATUS_INACTIVE;
} else
status = STATUS_ACTIVE;
if (new BusinessCalendar().isBusinessDay(nextRunTime, holidaySet))
return isAdjustedNextRunTimeValid();
if (holidayPolicy == HOLIDAY_POLICY_SAME)
return isAdjustedNextRunTimeValid();
if (holidayPolicy == HOLIDAY_POLICY_PREVIOUS) {
long targetTime = nextRunTime;
GregorianCalendar previousBusinessDayCal =
new BusinessCalendar().getPreviousBusinessDay(nextRunTime, holidaySet);
previousBusinessDayCal.set(Calendar.HOUR_OF_DAY, hour);
previousBusinessDayCal.set(Calendar.MINUTE, minute);
long previousBusinessDayTime = previousBusinessDayCal.getTime().getTime();
if (previousBusinessDayTime > baseTime) {
nextRunTime = previousBusinessDayTime;
} else {
do {
targetTime += 40000;
setNextRunTime(targetTime);
previousBusinessDayCal =
new BusinessCalendar().getPreviousBusinessDay(nextRunTime, holidaySet);
previousBusinessDayCal.set(Calendar.HOUR_OF_DAY, hour);
previousBusinessDayCal.set(Calendar.MINUTE, minute);
nextRunTime = previousBusinessDayCal.getTime().getTime();
} while (nextRunTime < baseTime);
}
} else if (holidayPolicy == HOLIDAY_POLICY_NEXT) {
GregorianCalendar nextBusinessDayCal =
new BusinessCalendar().getNextBusinessDay(nextRunTime, holidaySet);
nextBusinessDayCal.set(Calendar.HOUR_OF_DAY, hour);
nextBusinessDayCal.set(Calendar.MINUTE, minute);
long nextBusinessDayTime = nextBusinessDayCal.getTime().getTime();
nextRunTime = nextBusinessDayTime;
} else if (holidayPolicy == HOLIDAY_POLICY_SKIP) {
int skipTimes = 0;
do {
setNextRunTime(nextRunTime + 40000);
if (skipTimes++ > 7200)
throw new InvalidDataException(Phrase.get("ER_CONFLICT_BETWEEN_DATA_AND_WEEKEND_POLICY"));
} while (! new BusinessCalendar().isBusinessDay(nextRunTime, holidaySet));
}
if (baseTime > nextRunTime) {
nextRunTime = NOT_SPECIFIED;
status = STATUS_INACTIVE;
} else
status = STATUS_ACTIVE;
if (nextRunTime < startTime || nextRunTime > expiration) {
nextRunTime = NOT_SPECIFIED;
status = STATUS_INACTIVE;
} else {
status = STATUS_ACTIVE;
}
return isAdjustedNextRunTimeValid();
}
void setNextRunTime(long baseTime) throws Exception {
if (repeating == NOT_SPECIFIED) {
throw new InvalidDataException(Phrase.get("TX_REPEATING"));
} if (repeating == REPEATING_ONCE) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (startTime >= System.currentTimeMillis())
nextRunTime = startTime;
else
status = STATUS_INACTIVE;
} else if (repeating == REPEATING_MINUTELY) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (minutelyPeriod <= 0)
throw new InvalidDataException(Phrase.get("TX_MINUTELY_PERIOD") + ": " +
minutelyPeriod);
setNextRunTimeForMinutely(baseTime, minutelyPeriod);
} else if (repeating == REPEATING_HOURLY) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (hourlyPeriod <= 0)
throw new InvalidDataException(Phrase.get("TX_HOURLY_PERIOD") + ": " +
hourlyPeriod);
setNextRunTimeForMinutely(baseTime, hourlyPeriod * 60);
} else if (repeating == REPEATING_DAILY) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (dailyPeriod <= 0)
throw new InvalidDataException(Phrase.get("TX_DAILY_PERIOD") + ": " +
dailyPeriod);
setNextRunTimeForDaily(baseTime, dailyPeriod);
} else if (repeating == REPEATING_WEEKLY) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (weeklyPeriod <= 0)
throw new InvalidDataException(Phrase.get("TX_WEEKLY_PERIOD") + ": " + weeklyPeriod);
if (weeklyWeekDay <= 0)
throw new InvalidDataException(Phrase.get("TX_WEEKDAY") + ": " + weeklyWeekDay);
if ((holidayPolicy != HOLIDAY_POLICY_SAME) &&
(weeklyWeekDay == Calendar.SATURDAY || weeklyWeekDay == Calendar.SUNDAY))
throw new InvalidDataException(Phrase.get("ER_CONFLICT_BETWEEN_DATA_AND_WEEKEND_POLICY"));
setNextRunTimeForWeekly(baseTime);
} else if (repeating == REPEATING_MONTHLY) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (monthlyTheDay <= 0)
throw new InvalidDataException(Phrase.get("TX_MONTHLY_THE_DAY") + ": " + monthlyTheDay);
if (monthlyPeriod <= 0)
throw new InvalidDataException(Phrase.get("TX_MONTHLY_PERIOD") + ": " + monthlyTheDay);
setNextRunTimeForMonthly(baseTime);
} else if (repeating == REPEATING_WEEK_DAY_MONTHLY) {
if (startTime == NOT_SPECIFIED)
throw new InvalidDataException(Phrase.get("TX_START_TIME"));
if (monthlyPeriod <= 0)
throw new InvalidDataException(Phrase.get("TX_MONTHLY_PERIOD") + ": " + monthlyTheDay);
if ((holidayPolicy != HOLIDAY_POLICY_SAME) &&
(monthlyWhichWeekWeekDay == Calendar.SATURDAY ||
monthlyWhichWeekWeekDay == Calendar.SUNDAY))
throw new InvalidDataException(Phrase.get("ER_CONFLICT_BETWEEN_DATA_AND_WEEKEND_POLICY"));
setNextRunTimeForWeekDayMonthly(baseTime);
} else if (repeating == REPEATING_AT_SPECIFIED_TIMES) {
setNextRunTimeForSpecifiedTimes(baseTime);
} else if (repeating == REPEATING_SUPER_SCHEDULER_STARTUP) {
nextRunTime = NOT_SPECIFIED;
} else if (repeating == REPEATING_IMMEDIATELY_ONCE) {
nextRunTime = NOT_SPECIFIED;
} else if (repeating == REPEATING_ONCALL) {
nextRunTime = NOT_SPECIFIED;
} else if (repeating == REPEATING_STANDBY) {
nextRunTime = NOT_SPECIFIED;
} else {
throw new Exception("0311291030 " + repeating);
}
wouldBe = nextRunTime;
}
void setNextRunTimeForDaily(long baseTime, int minutes) {
GregorianCalendar baseTimeCalendar = new GregorianCalendar();
baseTimeCalendar.setLenient(true);
baseTimeCalendar.setTime(new Date(baseTime));
GregorianCalendar calculationCalendar = getCalculationCalendar();
while (baseTimeCalendar.after(calculationCalendar)) {
calculationCalendar.add(Calendar.DATE, dailyPeriod);
}
nextRunTime = calculationCalendar.getTime().getTime();
}
void setNextRunTimeForMinutely(long baseTime, int minutes) {
GregorianCalendar baseTimeCalendar = new GregorianCalendar();
baseTimeCalendar.setLenient(true);
baseTimeCalendar.setTime(new Date(baseTime));
GregorianCalendar calculationCalendar = getCalculationCalendar();
while (baseTimeCalendar.after(calculationCalendar)) {
calculationCalendar.add(Calendar.MINUTE, minutes);
}
nextRunTime = calculationCalendar.getTime().getTime();
}
void setNextRunTimeForMonthly(long baseTime) {
GregorianCalendar baseTimeCalendar = new GregorianCalendar();
baseTimeCalendar.setLenient(true);
baseTimeCalendar.setTime(new Date(baseTime));
GregorianCalendar calendar = getCalculationCalendar();
int jumpPeriod = monthlyPeriod;
do {
int lastDay = getLastDayInMonth(calendar);
if (monthlyTheDay >= LAST_DAY) {
calendar.set(Calendar.DAY_OF_MONTH, lastDay);
} else if (monthlyTheDay > lastDay) {
do {
calendar.add(Calendar.MONTH, jumpPeriod);
lastDay = getLastDayInMonth(calendar);
} while (monthlyTheDay > lastDay);
calendar.set(Calendar.DAY_OF_MONTH, monthlyTheDay);
} else {
calendar.set(Calendar.DAY_OF_MONTH, monthlyTheDay);
}
if (baseTimeCalendar.after(calendar)) {
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MONTH, jumpPeriod);
} else
break;
} while (true);
nextRunTime = calendar.getTime().getTime();
}
void setNextRunTimeForSpecifiedTimes(long baseTime) throws Exception {
GregorianCalendar calendar = getCalculationCalendarForSpecifiedTimes();
parseSpecifiedTimes();
if (holidayPolicy != HOLIDAY_POLICY_SAME && specifiedTimesContainWeekendsOnly())
throw new InvalidDataException(Phrase.get("ER_CONFLICT_BETWEEN_DATA_AND_WEEKEND_POLICY"));
int firstEligibleHour = getFirstEligibleHourForSpecifiedTime();
int firstEligibleMinute = getFirstEligibleMinuteForSpecifiedTime();
int startMonth = calendar.get(Calendar.MONTH);
int startDay = calendar.get(Calendar.DAY_OF_MONTH);
int startHour = firstEligibleHour;
int startMinute = firstEligibleMinute;
for (int aYear = calendar.get(Calendar.YEAR); ; aYear++) {
for (int aMonth = startMonth; aMonth < 12; aMonth++) {
int lastDayOfMonth = getLastDayOfMonth(aYear, aMonth);
for (int aDay = startDay; aDay <= lastDayOfMonth; aDay++) {
if (isTheDayEligible(aYear, aMonth, aDay) == false)
continue;
GregorianCalendar thatCal = new GregorianCalendar(aYear, aMonth, aDay);
long thatTime = thatCal.getTime().getTime();
BusinessCalendar businessCalendar = new BusinessCalendar();
if (! businessCalendar.isBusinessDay(Common.getDateString(thatTime), holidaySet)) {
if (holidayPolicy == HOLIDAY_POLICY_NEXT) {
GregorianCalendar nextBusinessDayCal =
businessCalendar.getNextBusinessDay(thatTime, holidaySet);
int thatYear = nextBusinessDayCal.get(Calendar.YEAR);
int thatMonth = nextBusinessDayCal.get(Calendar.MONTH);
int thatDay = nextBusinessDayCal.get(Calendar.DATE);
if (isTheDayEligible(thatYear, thatMonth, thatDay)) {
startMinute = firstEligibleMinute;
startHour = firstEligibleHour;
continue;
}
}
}
for (int anHour = startHour; anHour < 24; anHour++) {
if (contains(hoursPartOfSpecifiedTimes, anHour)) {
for (int aMinute = startMinute; aMinute < 59; aMinute++) {
if (contains(minutesPartOfSpecifiedTimes, aMinute)) {
GregorianCalendar theNextRunTimeCal =
new GregorianCalendar(aYear, aMonth, aDay, anHour, aMinute, 0);
long aNextRunTime = theNextRunTimeCal.getTime().getTime();
if (aNextRunTime > baseTime) {
nextRunTime = aNextRunTime;
hour = anHour;
minute = aMinute;
return;
} else if (holidayPolicy == HOLIDAY_POLICY_NEXT &&
nextBusinessDayTime(aNextRunTime) > baseTime) {
nextRunTime = aNextRunTime;
hour = anHour;
minute = aMinute;
return;
}
}
}
startMinute = firstEligibleMinute;
}
startMinute = firstEligibleMinute;
}
startMinute = firstEligibleMinute;
startHour = firstEligibleHour;
}
startMinute = firstEligibleMinute;
startHour = firstEligibleHour;
startDay = 1;
}
startMinute = firstEligibleMinute;
startHour = firstEligibleHour;
startDay = 1;
startMonth = 0;
}
}
void setNextRunTimeForWeekDayMonthly(long baseTime) {
GregorianCalendar baseTimeCalendar = new GregorianCalendar();
baseTimeCalendar.setLenient(true);
baseTimeCalendar.setTime(new Date(baseTime));
GregorianCalendar calendar = getCalculationCalendar();
calendar.set(Calendar.DAY_OF_MONTH, 1);
int jumpPeriod = monthlyPeriod;
if (monthlyWhichWeek == LAST_WEEK) {
do {
calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.DAY_OF_MONTH, -1);
int weekDayOnLastDayOfMonth = calendar.get(Calendar.DAY_OF_WEEK);
int diff = weekDayOnLastDayOfMonth - monthlyWhichWeekWeekDay;
if (diff < 0)
diff = diff + 7;
calendar.add(Calendar.DAY_OF_MONTH, -diff);
if (calendar.after(baseTimeCalendar))
break;
else {
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MONTH, jumpPeriod);
}
} while (true);
} else {
do {
int weekDayOnFirstDayOfMonth = calendar.get(Calendar.DAY_OF_WEEK);
int diff = monthlyWhichWeekWeekDay - weekDayOnFirstDayOfMonth;
if (diff < 0)
diff = diff + 7;
diff += 7 * (monthlyWhichWeek - 1);
calendar.add(Calendar.DAY_OF_MONTH, diff);
if (calendar.after(baseTimeCalendar))
break;
else {
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MONTH, jumpPeriod);
}
} while (true);
}
nextRunTime = calendar.getTime().getTime();
}
void setNextRunTimeForWeekly(long baseTime) {
GregorianCalendar baseTimeCalendar = new GregorianCalendar();
baseTimeCalendar.setLenient(true);
baseTimeCalendar.setTime(new Date(baseTime));
GregorianCalendar calendar = getCalculationCalendar();
calendar.set(Calendar.DAY_OF_WEEK, weeklyWeekDay);
int jumpPeriod = weeklyPeriod;
while (baseTimeCalendar.after(calendar)) {
calendar.add(Calendar.DAY_OF_WEEK, 7 * jumpPeriod);
}
nextRunTime = calendar.getTime().getTime();
}
public boolean setSpecifiedTimes(String specifiedTimes) throws Exception {
String _specifiedTimes = specifiedTimes;
long _wouldBe = wouldBe;
try {
this.specifiedTimes = specifiedTimes;
wouldBe = NOT_SPECIFIED;
setAdjustedNextRunTime();
} catch (Exception ex) {
specifiedTimes = _specifiedTimes;
wouldBe = _wouldBe;
throw ex;
}
return isAdjustedNextRunTimeValid();
}
void setStartTimeYMDHM() {
if (startTime == NOT_SPECIFIED)
return;
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(new Date(startTime));
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DATE);
hour = calendar.get(Calendar.HOUR_OF_DAY);
minute = calendar.get(Calendar.MINUTE);
}
public boolean specifiedTimesContainWeekendsOnly() {
parseSpecifiedTimes();
if (weekdaysPartOfSpecifiedTimes == null)
return false;
if (weekdaysPartOfSpecifiedTimes.equals("*"))
return false;
if (contains(weekdaysPartOfSpecifiedTimes, 0) ||
contains(weekdaysPartOfSpecifiedTimes, 6)) {
if (weekdaysPartOfSpecifiedTimes.length() <= 4)
return true;
}
return false;
}
public Hashtable toHashtable() {
Hashtable hashtable = new Hashtable();
hashtable.put("id", new Long(id));
hashtable.put("name", name);
hashtable.put("job", job);
hashtable.put("jobType", new Integer(jobType));
hashtable.put("repeating", new Integer(repeating));
hashtable.put("startTime", new Long(startTime));
hashtable.put("minutelyPeriod", new Integer(minutelyPeriod));
hashtable.put("hourlyPeriod", new Integer(hourlyPeriod));
hashtable.put("dailyPeriod", new Integer(dailyPeriod));
hashtable.put("weeklyPeriod", new Integer(weeklyPeriod));
hashtable.put("weeklyWeekDay", new Integer(weeklyWeekDay));
hashtable.put("monthlyPeriod", new Integer(monthlyPeriod));
hashtable.put("monthlyTheDay", new Integer(monthlyTheDay));
hashtable.put("monthlyWhichWeek", new Integer(monthlyWhichWeek));
hashtable.put("monthlyWhichWeekWeekDay", new Integer(monthlyWhichWeekWeekDay));
if (specifiedTimes != null)
hashtable.put("specifiedTimes", specifiedTimes);
hashtable.put("wouldBe", new Long(wouldBe));
hashtable.put("holidayPolicy", new Integer(holidayPolicy));
hashtable.put("holidaySet", holidaySet);
hashtable.put("expiration", new Long(expiration));
hashtable.put("duration", new Long(duration));
hashtable.put("killIfExceedsDuration", new Integer(killIfExceedsDuration));
hashtable.put("hostname", hostname);
hashtable.put("club", club);
hashtable.put("description", description);
hashtable.put("comments", comments);
hashtable.put("status", new Integer(status));
hashtable.put("nextRunTime", new Long(nextRunTime));
hashtable.put("lastRunTime", new Long(lastRunTime));
hashtable.put("creator", creator);
hashtable.put("alarmEmail", alarmEmail);
hashtable.put("modifiedAt", new Long(modifiedAt));
return hashtable;
}
}