/** * Create a trigger for the given cron expression. * See {@link CronSequenceGenerator}. */ public CronTrigger(String expression) throws IllegalArgumentException { this.cronSequenceGenerator = new CronSequenceGenerator(expression); }
@Override public boolean equals(Object other) { if (other == null || !(other instanceof CronTrigger)) { return false; } return this.cronSequenceGenerator.equals( ((CronTrigger) other).cronSequenceGenerator); }
@Override public int hashCode() { return this.cronSequenceGenerator.hashCode(); }
/** * @param expression */ private void parse(String expression) throws IllegalArgumentException { String[] fields = StringUtils.tokenizeToStringArray(expression, " "); if (fields.length != 6) { throw new IllegalArgumentException(String.format("" + "cron expression must consist of 6 fields (found %d in %s)", fields.length, expression)); } setNumberHits(seconds, fields[0], 60); setNumberHits(minutes, fields[1], 60); setNumberHits(hours, fields[2], 24); setDaysOfMonth(daysOfMonth, fields[3], 31); setNumberHits(months, replaceOrdinals(fields[4], "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC"), 12); setDays(daysOfWeek, replaceOrdinals(fields[5], "SUN,MON,TUE,WED,THU,FRI,SAT"), 8); if (daysOfWeek.get(7)) { // Sunday can be represented as 0 or 7 daysOfWeek.set(0); daysOfWeek.clear(7); } }
int updateSecond = findNext(seconds, second, 60, calendar, Calendar.SECOND, emptyList); if (second == updateSecond) { resets.add(Calendar.SECOND); int updateMinute = findNext(minutes, minute, 60, calendar, Calendar.MINUTE, resets); if (minute == updateMinute) { resets.add(Calendar.MINUTE); doNext(calendar); int updateHour = findNext(hours, hour, 24, calendar, Calendar.HOUR_OF_DAY, resets); if (hour == updateHour) { resets.add(Calendar.HOUR_OF_DAY); doNext(calendar); int updateDayOfMonth = findNextDay(calendar, daysOfMonth, dayOfMonth, daysOfWeek, dayOfWeek, 366, resets); if (dayOfMonth == updateDayOfMonth) { resets.add(Calendar.DAY_OF_MONTH); doNext(calendar); int updateMonth = findNext(this.months, month, 12, calendar, Calendar.MONTH, resets); if (month != updateMonth) { doNext(calendar);
/** * Construct a {@link CronSequenceGenerator} from the pattern provided. * * @param pattern a space separated list of time fields * * @throws IllegalArgumentException if the pattern cannot be parsed */ public CronSequenceGenerator(String pattern) throws IllegalArgumentException { this.pattern = pattern; parse(pattern); }
/** * Return the next time a task should run. Determined by consulting this * trigger's cron expression compared with the lastCompleteTime. If the * lastCompleteTime is <code>null</code>, the current time is used. */ public Date getNextRunTime(Date lastScheduledRunTime, Date lastCompleteTime) { Date date = (lastCompleteTime != null) ? lastCompleteTime : new Date(); return this.cronSequenceGenerator.next(date); }
/** * Get the next {@link Date} in the sequence matching the Cron pattern and * after the value provided. The return value will have a whole number of * seconds, and will be after the input value. * * @param date a seed value * @return the next value matching the pattern */ public Date next(Date date) { /* The plan: 1 Round up to the next whole second 2 If seconds match move on, otherwise find the next match: 2.1 If next match is in the next minute then roll forwards 3 If minute matches move on, otherwise find the next match 3.1 If next match is in the next hour then roll forwards 3.2 Reset the seconds and go to 2 4 If hour matches move on, otherwise find the next match 4.1 If next match is in the next day then roll forwards, 4.2 Reset the minutes and seconds and go to 2 ... */ Calendar calendar = new GregorianCalendar(); calendar.setTime(date); // Truncate to the next whole second calendar.add(Calendar.SECOND, 1); calendar.set(Calendar.MILLISECOND, 0); doNext(calendar); return calendar.getTime(); }
/** * @param bits * @param value * @param max * @return */ private void setNumberHits(BitSet bits, String value, int max) { String[] fields = StringUtils.delimitedListToStringArray(value, ","); for (String field : fields) { if (!field.contains("/")) { // Not an incrementer so it must be a range (possibly empty) int[] range = getRange(field, max); bits.set(range[0], range[1] + 1); } else { String[] split = StringUtils.delimitedListToStringArray(field, "/"); if (split.length > 2) { throw new IllegalArgumentException("Incrementer has more than two fields: " + field); } int[] range = getRange(split[0], max); if (!split[0].contains("-")) { range[1] = max - 1; } int delta = Integer.valueOf(split[1]); for (int i = range[0]; i <= range[1]; i += delta) { bits.set(i); } } } }