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

org.quartz.UICronTrigger Maven / Gradle / Ivy

Go to download

SDK for dev_appserver (local development) with some of the dependencies shaded (repackaged)

There is a newer version: 2.0.31
Show newest version

/* 
 * 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 
 * under the License.
 * 
 */

/*
 * Previously Copyright (c) 2001-2004 James House
 */
package org.quartz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.CronTrigger;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeSet;
import java.text.ParseException;

/**
 * 

* A concrete {@link Trigger} that is used to fire a {@link Job} * at given moments in time, defined with Unix 'cron-like' definitions. *

* *

* What you should know about this particular trigger is that it is based on * org.quartz.CronTrigger, but the the functionality to build the sets from a * string are unused. Whereas CronTrigger would essentially deserialize by * rebuilding the TreeSets from the cronExpression, this class does not have a * cronExpression, and de/serializes the TreeSets in their entirety. This is * because the TreeSets map directly to the Struts user interface for set * selection, and no effort is made to write an interpreter to map them back * and forth between legacy UN*X cron expressions that CronTrigger uses. *

* *

* The method I use with this trigger is to instantiate it, then put it in the * ActionForm of a Struts bean, then let Struts manipulate it directly through * BeanUtils. You are by no means required to do that, but to fully understand * the concepts here, at least until there is better documentation, you should * understand how it works within that context first so you can write the * appropriate code that Struts does for you for free. I'll try to explain that * here. *

* *

* Struts JSP tags allow the user to use Apache BeanUtils to reference * components of beans by path. This is to say that a bean Foo * that has an accessor method Bar getBar() and given * Bar * has a primitive type String as a field named splat, * one can set the field to "new string value" as follows: *

* * // create a new Foo with contained reference to a new Bar * Foo fooBean = new Foo(); * fooBean.setBar(new Bar()); * // set the splat string in the Bar bean from Foo * BeanUtils.setProperty(fooBean, "bar.splat", "new string value"); * *

* In turn, Struts JSP tags use the bean addressing provided by BeanUtils to * address accessor methods within the bean graph that is rooted with the * ActionForm that is put into the Action context. *

*

* Finally, having all this allows you to put direct selection lists on the * screen of the UI, then map them directly into the UICronTrigger bean. Given * a ActionForm bean that was set up to contain a UICronTrigger * in a field called trigger, the following HTML code will * completely create your UI in Struts: *

* * * * Date * * * * * * * * * * * * * * * * * Time * * * * * * * * * * *

* So if you don't want to use Struts, what you have to do is take the * information that was submitted on the form in the HTML select ranges, * iterate each of them, and add the values to the appropriate sets in the * fields of this class. Make sense? *

* * Note that this is not as versatile as the standard CronTrigger. There are * tricks with "last day of month" and repeating sets that need to be manually * selected, and sets that can happen for date ranges much longer than we can * reasonably map with direct selection in a UI. * * @see org.quartz.CronTrigger * @see Trigger * @see SimpleTrigger * * @author Brian Topping * @author based on code by Sharada Jambula, James House, Mads Henderson * @deprecated */ public class UICronTrigger extends Trigger { /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constants. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Instructs the {@link Scheduler} that upon a mis-fire * situation, the {@link org.quartz.CronTrigger} 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 org.quartz.CronTrigger} wants to * have it's next-fire-time updated to the next time in the schedule after * the current time, but it does not to be fired now. *

*/ public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Data members. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ private static final int ALL_SPEC_INT = 99; // '*' private static final int NO_SPEC_INT = 98; // '?' private static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT); private static final Integer NO_SPEC = new Integer(NO_SPEC_INT); private static Map monthMap = new HashMap(20); private static 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)); 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)); } private Date startTime = null; private Date endTime = null; private Date nextFireTime = null; private TimeZone timeZone = null; private Date previousFireTime = null; private TreeSet seconds = null; private TreeSet minutes = null; private TreeSet hours = null; private TreeSet daysOfMonth = null; private TreeSet months = null; private TreeSet daysOfWeek = null; private TreeSet years = null; private transient boolean lastdayOfWeek = false; private transient int nthdayOfWeek = 0; private transient boolean lastdayOfMonth = false; private transient boolean calendardayOfWeek = false; private transient boolean calendardayOfMonth = false; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constructors. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ public void reset() { seconds = new TreeSet(); minutes = new TreeSet(); hours = new TreeSet(); daysOfMonth = new TreeSet(); months = new TreeSet(); daysOfWeek = new TreeSet(); years = new TreeSet(); // we always fire on the minute seconds.add(new Integer(0)); minutes.add(ALL_SPEC); for (int i = 0; i < 60; i++) minutes.add(new Integer(i)); hours.add(ALL_SPEC); for (int i = 0; i < 24; i++) hours.add(new Integer(i)); daysOfMonth.add(ALL_SPEC); for (int i = 1; i <= 31; i++) daysOfMonth.add(new Integer(i)); months.add(ALL_SPEC); for (int i = 1; i <= 12; i++) months.add(new Integer(i)); daysOfWeek.add(NO_SPEC); years.add(ALL_SPEC); for (int i = 1970; i <= 2099; i++) years.add(new Integer(i)); startTime = new Date(); setStartTime(startTime); setTimeZone(TimeZone.getDefault()); } /** *

* Create a CronTrigger with no settings. *

*/ public UICronTrigger() { super(); reset(); } /** *

* Create a CronTrigger with the given name and group. *

*/ public UICronTrigger(String name, String group) { super(name, group); reset(); } /** *

* Create a CronTrigger with the given name and group, and * associated with the identified {@link Job}. *

*/ public UICronTrigger(String name, String group, String jobName, String jobGroup) { super(name, group, jobName, jobGroup); reset(); } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* 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; } public void updateAfterMisfire(org.quartz.Calendar cal) { int instr = getMisfireInstruction(); if (instr == MISFIRE_INSTRUCTION_SMART_POLICY) instr = MISFIRE_INSTRUCTION_DO_NOTHING; 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()); } } public Date getPreviousFireTime() { return this.previousFireTime; } /** *

* 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; } /** *

* Sets the next time at which the CronTrigger will fire. If * the trigger will not fire again, null will be returned. *

*/ public void setNextFireTime(Date nextFireTime) { this.nextFireTime = nextFireTime; } /** *

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

*/ public TimeZone getTimeZone() { return this.timeZone; } /** *

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

*/ public void setTimeZone(TimeZone timeZone) { this.timeZone = timeZone; } /** *

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

*/ public void updateAfterMisfire() { int instr = getMisfireInstruction(); if (instr == MISFIRE_INSTRUCTION_SMART_POLICY) instr = MISFIRE_INSTRUCTION_DO_NOTHING; if (instr == MISFIRE_INSTRUCTION_DO_NOTHING) { setNextFireTime(getFireTimeAfter(new Date())); } else if (instr == MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) { setNextFireTime(new Date()); } } /** *

* Determines whether the date & time of the given java.util.Calendar * instance falls on a scheduled fire-time of this trigger. *

* *

* Note that the date returned is NOT validated against the related * org.quartz.Calendar (if any) *

*/ public boolean willFireOn(Calendar test) { Integer second = new Integer(test.get(Calendar.SECOND)); Integer minute = new Integer(test.get(Calendar.MINUTE)); Integer hour = new Integer(test.get(Calendar.HOUR_OF_DAY)); Integer day = new Integer(test.get(Calendar.DAY_OF_MONTH)); Integer month = new Integer(test.get(Calendar.MONTH)); if ((seconds.contains(second) || seconds.contains(ALL_SPEC)) && (minutes.contains(minute) || minutes.contains(ALL_SPEC)) && (hours.contains(hour) || hours.contains(ALL_SPEC)) && (daysOfMonth.contains(day) || daysOfMonth.contains(ALL_SPEC)) && (months.contains(month) || months.contains(ALL_SPEC))) { return true; } return false; } /** *

* Called after the {@link Scheduler} has executed the * {@link Job} 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 Trigger.INSTRUCTION_RE_EXECUTE_JOB; 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() { StringBuffer buf = new StringBuffer(); buf.append("seconds: "); buf.append(getExpressionSetSummary(seconds)); buf.append("\n"); buf.append("minutes: "); buf.append(getExpressionSetSummary(minutes)); buf.append("\n"); buf.append("hours: "); buf.append(getExpressionSetSummary(hours)); buf.append("\n"); buf.append("daysOfMonth: "); buf.append(getExpressionSetSummary(daysOfMonth)); buf.append("\n"); buf.append("months: "); buf.append(getExpressionSetSummary(months)); buf.append("\n"); buf.append("daysOfWeek: "); buf.append(getExpressionSetSummary(daysOfWeek)); buf.append("\n"); buf.append("lastdayOfWeek: "); buf.append(lastdayOfWeek); buf.append("\n"); 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(); } private String getExpressionSetSummary(Set set) { if (set.contains(NO_SPEC)) return "?"; if (set.contains(ALL_SPEC)) return "*"; StringBuffer buf = new StringBuffer(); Iterator itr = set.iterator(); boolean first = true; while (itr.hasNext()) { Integer iVal = (Integer) itr.next(); String val = iVal.toString(); if (!first) buf.append(","); buf.append(val); first = false; } return buf.toString(); } //////////////////////////////////////////////////////////////////////////// // // Computation Functions // //////////////////////////////////////////////////////////////////////////// private Date getTimeAfter(Date afterTime) { Calendar cl = Calendar.getInstance(timeZone); // move ahead one second, since we're computing the time *after* the // given time afterTime = new Date(afterTime.getTime() + 1000); // CronTrigger does not deal with milliseconds cl.setTime(afterTime); cl.set(Calendar.MILLISECOND, 0); boolean gotOne = false; // loop until we've computed the next time, or we've past the endTime while (!gotOne) { if (endTime != null && cl.getTime().after(endTime)) return 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)); if (st != null && st.size() != 0) { sec = ((Integer) st.first()).intValue(); } else { sec = ((Integer) seconds.first()).intValue(); min++; cl.set(Calendar.MINUTE, min); } cl.set(Calendar.SECOND, sec); min = cl.get(Calendar.MINUTE); int hr = cl.get(Calendar.HOUR_OF_DAY); t = -1; // get minute................................................. st = minutes.tailSet(new Integer(min)); if (st != null && st.size() != 0) { t = min; min = ((Integer) st.first()).intValue(); } else { min = ((Integer) minutes.first()).intValue(); hr++; } if (min != t) { cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, min); cl.set(Calendar.HOUR_OF_DAY, hr); continue; } cl.set(Calendar.MINUTE, min); hr = cl.get(Calendar.HOUR_OF_DAY); int day = cl.get(Calendar.DAY_OF_MONTH); t = -1; // get hour................................................... st = hours.tailSet(new Integer(hr)); if (st != null && st.size() != 0) { t = hr; hr = ((Integer) st.first()).intValue(); } else { hr = ((Integer) hours.first()).intValue(); day++; } if (hr != t) { cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, hr); cl.set(Calendar.DAY_OF_MONTH, day); continue; } cl.set(Calendar.HOUR_OF_DAY, hr); day = cl.get(Calendar.DAY_OF_MONTH); int mon = cl.get(Calendar.MONTH) + 1; // '+ 1' because calendar is // 0-based for this field, // and we are 1-based t = -1; // get day................................................... boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC); boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC); if (dayOfMSpec && !dayOfWSpec) { // get day only by day of month // rule st = daysOfMonth.tailSet(new Integer(day)); if (lastdayOfMonth) { t = day; day = getLastDayOfMonth(mon); } else if (st != null && st.size() != 0) { t = day; day = ((Integer) st.first()).intValue(); } else { day = ((Integer) daysOfMonth.first()).intValue(); mon++; } if (day != t) { cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, day); cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar // is 0-based for this // field, and we are // 1-based continue; } } else if (dayOfWSpec && !dayOfMSpec) { // get day only 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 // 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); int lDay = getLastDayOfMonth(mon); if (day + daysToAdd > lDay) { // did we already miss the // last one? cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, 1); cl.set(Calendar.MONTH, mon); // no '- 1' here because // we are promoting the // month continue; } // find date of last occurance of this day in this month... while ((day + daysToAdd + 7) <= lDay) daysToAdd += 7; day += daysToAdd; } else if (nthdayOfWeek != 0) { // are we looking for the Nth // XXX day in the month? int dow = ((Integer) daysOfWeek.first()).intValue(); // 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); day += daysToAdd; int weekOfMonth = day / 7; if (day % 7 > 0) weekOfMonth++; daysToAdd = (nthdayOfWeek - weekOfMonth) * 7; day += daysToAdd; if (daysToAdd < 0 || day > getLastDayOfMonth(mon)) { cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, 1); cl.set(Calendar.MONTH, mon); // no '- 1' here because // we are promoting the // month continue; } } else { int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w int dow = ((Integer) daysOfWeek.first()).intValue(); // desired // d-o-w st = daysOfWeek.tailSet(new Integer(cDow)); if (st != null && st.size() > 0) { dow = ((Integer) st.first()).intValue(); } int daysToAdd = 0; if (cDow < dow) daysToAdd = dow - cDow; if (cDow > dow) daysToAdd = dow + (7 - cDow); int lDay = getLastDayOfMonth(mon); if (day + daysToAdd > lDay) { // will we pass the end of // the month? cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, 1); cl.set(Calendar.MONTH, mon); // no '- 1' here because // we are promoting the // month continue; } else if (daysToAdd > 0) { // are we swithing days? cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd); cl.set(Calendar.MONTH, mon - 1); // '- 1' because // calendar is 0-based // for this field, and // we are 1-based continue; } } } 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); mon = cl.get(Calendar.MONTH) + 1; // '+ 1' because calendar is // 0-based for this field, and we // are 1-based int year = cl.get(Calendar.YEAR); t = -1; // get month................................................... st = months.tailSet(new Integer(mon)); if (st != null && st.size() != 0) { t = mon; mon = ((Integer) st.first()).intValue(); } else { mon = ((Integer) months.first()).intValue(); year++; } if (mon != t) { cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, 1); cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is // 0-based for this field, and // we are 1-based cl.set(Calendar.YEAR, year); continue; } cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is // 0-based for this field, and we // are 1-based year = cl.get(Calendar.YEAR); t = -1; // get year................................................... st = years.tailSet(new Integer(year)); if (st != null && st.size() != 0) { t = year; year = ((Integer) st.first()).intValue(); } else return null; // ran out of years... if (year != t) { cl.set(Calendar.SECOND, 0); cl.set(Calendar.MINUTE, 0); cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.DAY_OF_MONTH, 1); cl.set(Calendar.MONTH, mon - 1); // '- 1' because calendar is // 0-based for this field, and // we are 1-based cl.set(Calendar.YEAR, year); continue; } cl.set(Calendar.YEAR, year); gotOne = true; } // while( !done ) return cl.getTime(); } private Date getTimeBefore(Date endTime) // TODO: implement { return null; } public boolean isLeapYear() { Calendar cl = Calendar.getInstance(timeZone); int year = cl.get(Calendar.YEAR); if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return true; else return false; } public int getLastDayOfMonth(int monthNum) { switch (monthNum) { case 1: return 31; case 2: return (isLeapYear()) ? 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); } } public Integer[] getSecondsValues() { Integer list[] = new Integer[60]; for (int i = 0; i < 60; i++) { list[i] = new Integer(i); } return list; } public Integer[] getSecondsLabels() { return getSecondsValues(); } public Integer[] getSeconds() { Integer list[] = new Integer[seconds.size()]; if (seconds != null) { int i = 0; for (Iterator it = seconds.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setSeconds(Integer[] val) { if (seconds != null) seconds.clear(); else seconds = new TreeSet(); for (int i = 0; i < val.length; i++) { seconds.add(val[i]); } } public Integer[] getMinutesValues() { Integer list[] = new Integer[60]; for (int i = 0; i < 60; i++) { list[i] = new Integer(i); } return list; } public Integer[] getMinutesLabels() { return getMinutesValues(); } public Integer[] getMinutes() { Integer list[] = new Integer[minutes.size()]; if (minutes != null) { int i = 0; for (Iterator it = minutes.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setMinutes(Integer[] val) { if (minutes != null) minutes.clear(); else minutes = new TreeSet(); for (int i = 0; i < val.length; i++) { minutes.add(val[i]); } } public Integer[] getHoursValues() { Integer list[] = new Integer[24]; for (int i = 0; i < 24; i++) { list[i] = new Integer(i); } return list; } public String[] getHoursLabels() { String vals[] = {"12AM (Midnight)", "1AM", "2AM", "3AM", "4AM", "5AM", "6AM", "7AM", "8AM", "9AM", "10AM", "11AM", "12PM (Noon)", "1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM", "10PM", "11PM"}; return vals; } public Integer[] getHours() { Integer list[] = new Integer[hours.size()]; if (hours != null) { int i = 0; for (Iterator it = hours.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setHours(Integer[] val) { if (hours != null) hours.clear(); else hours = new TreeSet(); for (int i = 0; i < val.length; i++) { hours.add(val[i]); } } public Integer[] getDaysOfMonthValues() { Integer list[] = new Integer[31]; for (int i = 0; i < 31; i++) { list[i] = new Integer(i + 1); } return list; } public Integer[] getDaysOfMonthLabels() { return getDaysOfMonthValues(); } public Integer[] getDaysOfMonth() { Integer list[] = new Integer[daysOfMonth.size()]; if (daysOfMonth != null) { int i = 0; for (Iterator it = daysOfMonth.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setDaysOfMonth(Integer[] val) { if (daysOfMonth != null) daysOfMonth.clear(); else daysOfMonth = new TreeSet(); for (int i = 0; i < val.length; i++) { daysOfMonth.add(val[i]); } daysOfWeek.clear(); daysOfWeek.add(NO_SPEC); } public Integer[] getMonthsValues() { Integer list[] = new Integer[12]; for (int i = 0; i < 12; i++) { list[i] = new Integer(i + 1); } return list; } public String[] getMonthsLabels() { String vals[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; return vals; } public Integer[] getMonths() { Integer list[] = new Integer[months.size()]; if (months != null) { int i = 0; for (Iterator it = months.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setMonths(Integer[] val) { if (months != null) months.clear(); else months = new TreeSet(); for (int i = 0; i < val.length; i++) { months.add(val[i]); } } public String[] getDaysOfWeekLabels() { String list[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; return list; } public Integer[] getDaysOfWeekValues() { Integer list[] = new Integer[7]; for (int i = 0; i < 7; i++) list[i] = new Integer(i + 1); return list; } public Integer[] getDaysOfWeek() { Integer list[] = new Integer[daysOfWeek.size()]; if (daysOfWeek != null) { int i = 0; for (Iterator it = daysOfWeek.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setDaysOfWeek(Integer[] val) { if (daysOfWeek != null) daysOfWeek.clear(); else daysOfWeek = new TreeSet(); for (int i = 0; i < val.length; i++) { daysOfWeek.add(val[i]); } daysOfMonth.clear(); daysOfMonth.add(NO_SPEC); } public Integer[] getYearsValues() { Integer list[] = new Integer[20]; Calendar now = Calendar.getInstance(); int year = now.get(Calendar.YEAR); for (int i = 0; i < 20; i++) { list[i] = new Integer(i + year); } return list; } public Integer[] getYearsLabels() { return getYearsValues(); } public Integer[] getYears() { Integer list[] = new Integer[years.size()]; if (years != null) { int i = 0; for (Iterator it = years.iterator(); it.hasNext(); i++) { list[i] = (Integer) it.next(); } } return list; } public void setYears(Integer[] val) { if (years != null) years.clear(); else years = new TreeSet(); for (int i = 0; i < val.length; i++) { years.add(val[i]); } } public static void main(String[] argv) { CronTrigger ct = new CronTrigger("a", "a"); try { ct.setCronExpression("0 * * * * ? *"); } catch (ParseException e) { // log.error("caught an exception", e); } ct.setStartTime(new Date()); ct.setTimeZone(TimeZone.getDefault()); System.out.println(ct.getExpressionSummary()); ct.computeFirstFireTime(null); UICronTrigger uict = new UICronTrigger("a", "a"); Integer set[] = new Integer[1]; set[0] = new Integer(1); uict.setSeconds(set); System.out.println(ct.getExpressionSummary()); uict.computeFirstFireTime(null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy