|
|
|
@ -17,7 +17,6 @@
@@ -17,7 +17,6 @@
|
|
|
|
|
package org.springframework.scheduling.support; |
|
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.Arrays; |
|
|
|
|
import java.util.BitSet; |
|
|
|
|
import java.util.Calendar; |
|
|
|
|
import java.util.Collections; |
|
|
|
@ -26,6 +25,7 @@ import java.util.GregorianCalendar;
@@ -26,6 +25,7 @@ import java.util.GregorianCalendar;
|
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.TimeZone; |
|
|
|
|
|
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -50,6 +50,7 @@ import org.springframework.util.StringUtils;
@@ -50,6 +50,7 @@ import org.springframework.util.StringUtils;
|
|
|
|
|
* |
|
|
|
|
* @author Dave Syer |
|
|
|
|
* @author Juergen Hoeller |
|
|
|
|
* @author Ruslan Sibgatullin |
|
|
|
|
* @since 3.0 |
|
|
|
|
* @see CronTrigger |
|
|
|
|
*/ |
|
|
|
@ -57,6 +58,7 @@ public class CronSequenceGenerator {
@@ -57,6 +58,7 @@ public class CronSequenceGenerator {
|
|
|
|
|
|
|
|
|
|
private final String expression; |
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
private final TimeZone timeZone; |
|
|
|
|
|
|
|
|
|
private final BitSet months = new BitSet(12); |
|
|
|
@ -96,6 +98,12 @@ public class CronSequenceGenerator {
@@ -96,6 +98,12 @@ public class CronSequenceGenerator {
|
|
|
|
|
parse(expression); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private CronSequenceGenerator(String expression, String[] fields) { |
|
|
|
|
this.expression = expression; |
|
|
|
|
this.timeZone = null; |
|
|
|
|
doParse(fields); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Return the cron pattern that this sequence generator has been built for. |
|
|
|
@ -234,7 +242,7 @@ public class CronSequenceGenerator {
@@ -234,7 +242,7 @@ public class CronSequenceGenerator {
|
|
|
|
|
// roll over if needed
|
|
|
|
|
if (nextValue == -1) { |
|
|
|
|
calendar.add(nextField, 1); |
|
|
|
|
reset(calendar, Arrays.asList(field)); |
|
|
|
|
reset(calendar, Collections.singletonList(field)); |
|
|
|
|
nextValue = bits.nextSetBit(0); |
|
|
|
|
} |
|
|
|
|
if (nextValue != value) { |
|
|
|
@ -265,12 +273,17 @@ public class CronSequenceGenerator {
@@ -265,12 +273,17 @@ public class CronSequenceGenerator {
|
|
|
|
|
throw new IllegalArgumentException(String.format( |
|
|
|
|
"Cron expression must consist of 6 fields (found %d in \"%s\")", fields.length, expression)); |
|
|
|
|
} |
|
|
|
|
doParse(fields); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void doParse(String[] fields) { |
|
|
|
|
setNumberHits(this.seconds, fields[0], 0, 60); |
|
|
|
|
setNumberHits(this.minutes, fields[1], 0, 60); |
|
|
|
|
setNumberHits(this.hours, fields[2], 0, 24); |
|
|
|
|
setDaysOfMonth(this.daysOfMonth, fields[3]); |
|
|
|
|
setMonths(this.months, fields[4]); |
|
|
|
|
setDays(this.daysOfWeek, replaceOrdinals(fields[5], "SUN,MON,TUE,WED,THU,FRI,SAT"), 8); |
|
|
|
|
|
|
|
|
|
if (this.daysOfWeek.get(7)) { |
|
|
|
|
// Sunday can be represented as 0 or 7
|
|
|
|
|
this.daysOfWeek.set(0); |
|
|
|
@ -388,19 +401,29 @@ public class CronSequenceGenerator {
@@ -388,19 +401,29 @@ public class CronSequenceGenerator {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Determine whether the specified expression represents a valid cron pattern. |
|
|
|
|
* <p>Specifically, this method verifies that the expression contains six |
|
|
|
|
* fields separated by single spaces. |
|
|
|
|
* @param expression the expression to evaluate |
|
|
|
|
* @return {@code true} if the given expression is a valid cron expression |
|
|
|
|
* @since 4.3 |
|
|
|
|
*/ |
|
|
|
|
public static boolean isValidExpression(String expression) { |
|
|
|
|
public static boolean isValidExpression(@Nullable String expression) { |
|
|
|
|
if (expression == null) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
String[] fields = StringUtils.tokenizeToStringArray(expression, " "); |
|
|
|
|
return areValidCronFields(fields); |
|
|
|
|
if (!areValidCronFields(fields)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
try { |
|
|
|
|
new CronSequenceGenerator(expression, fields); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
catch (IllegalArgumentException ex) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static boolean areValidCronFields(String[] fields) { |
|
|
|
|
return (fields.length == 6); |
|
|
|
|
private static boolean areValidCronFields(@Nullable String[] fields) { |
|
|
|
|
return (fields != null && fields.length == 6); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|