📄 uicrontrigger.java
字号:
/** * <p> * Returns the time zone for which the <code>cronExpression</code> of * this <code>CronTrigger</code> will be resolved. * </p> */ public TimeZone getTimeZone() { return this.timeZone; } /** * <p> * Sets the time zone for which the <code>cronExpression</code> of this * <code>CronTrigger</code> will be resolved. * </p> */ public void setTimeZone(TimeZone timeZone) { this.timeZone = timeZone; } /** * <p> * Returns the next time at which the <code>CronTrigger</code> will fire, * after the given time. If the trigger will not fire after the given time, * <code>null</code> will be returned. * </p> * * <p> * Note that the date returned is NOT validated against the related * org.quartz.Calendar (if any) * </p> */ 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; } /** * <p> * Returns the final time at which the <code>CronTrigger</code> will * fire. * </p> * * <p> * Note that the return time *may* be in the past. and the date returned is * not validated against org.quartz.calendar * </p> */ public Date getFinalFireTime() { if (this.endTime != null) return getTimeBefore(this.endTime); else return null; } /** * <p> * Determines whether or not the <code>CronTrigger</code> will occur * again. * </p> */ 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; } /** * <p> * Updates the <code>CronTrigger</code>'s state based on the * MISFIRE_INSTRUCTION_XXX that was selected when the <code>SimpleTrigger</code> * was created. * </p> * * <p> * If the misfire instruction is set to MISFIRE_INSTRUCTION_SMART_POLICY, * then the following scheme will be used: <br> * <ul> * <li>The instruction will be interpreted as <code>MISFIRE_INSTRUCTION_DO_NOTHING</code> * </ul> * </p> */ 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()); } } /** * <p> * Determines whether the date & time of the given java.util.Calendar * instance falls on a scheduled fire-time of this trigger. * </p> * * <p> * Note that the date returned is NOT validated against the related * org.quartz.Calendar (if any) * </p> */ 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; } /** * <p> * Called after the <code>{@link Scheduler}</code> has executed the * <code>{@link Job}</code> associated with the <code>Trigger</code> in * order to get the final instruction code from the trigger. * </p> * * @param context * is the <code>JobExecutionContext</code> that was used by the * <code>Job</code>'s<code>execute(xx)</code> method. * @param result * is the <code>JobExecutionException</code> thrown by the * <code>Job</code>, 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; } /** * <p> * Called when the <code>{@link Scheduler}</code> has decided to 'fire' * the trigger (execute the associated <code>Job</code>), in order to * give the <code>Trigger</code> a chance to update itself for its next * triggering (if any). * </p> * * @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); } /** * <p> * Called by the scheduler at the time a <code>Trigger</code> is first * added to the scheduler, in order to have the <code>Trigger</code> * compute its first fire time, based on any associated calendar. * </p> * * <p> * After this method has been called, <code>getNextFireTime()</code> * should return a valid answer. * </p> * * @return the first time at which the <code>Trigger</code> will be fired * by the scheduler, which is also the same value <code>getNextFireTime()</code> * will return (until after the first firing of the <code>Trigger</code>). * </p> */ 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...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -