|
17 | 17 | package org.springframework.scheduling.support; |
18 | 18 |
|
19 | 19 | import java.util.ArrayList; |
20 | | -import java.util.Arrays; |
21 | 20 | import java.util.BitSet; |
22 | 21 | import java.util.Calendar; |
23 | 22 | import java.util.Collections; |
|
50 | 49 | * |
51 | 50 | * @author Dave Syer |
52 | 51 | * @author Juergen Hoeller |
| 52 | + * @author Ruslan Sibgatullin |
53 | 53 | * @since 3.0 |
54 | 54 | * @see CronTrigger |
55 | 55 | */ |
@@ -96,6 +96,12 @@ public CronSequenceGenerator(String expression, TimeZone timeZone) { |
96 | 96 | parse(expression); |
97 | 97 | } |
98 | 98 |
|
| 99 | + private CronSequenceGenerator(String expression, String[] fields) { |
| 100 | + this.expression = expression; |
| 101 | + this.timeZone = null; |
| 102 | + doParse(fields); |
| 103 | + } |
| 104 | + |
99 | 105 |
|
100 | 106 | /** |
101 | 107 | * Return the cron pattern that this sequence generator has been built for. |
@@ -234,7 +240,7 @@ private int findNext(BitSet bits, int value, Calendar calendar, int field, int n |
234 | 240 | // roll over if needed |
235 | 241 | if (nextValue == -1) { |
236 | 242 | calendar.add(nextField, 1); |
237 | | - reset(calendar, Arrays.asList(field)); |
| 243 | + reset(calendar, Collections.singletonList(field)); |
238 | 244 | nextValue = bits.nextSetBit(0); |
239 | 245 | } |
240 | 246 | if (nextValue != value) { |
@@ -265,12 +271,17 @@ private void parse(String expression) throws IllegalArgumentException { |
265 | 271 | throw new IllegalArgumentException(String.format( |
266 | 272 | "Cron expression must consist of 6 fields (found %d in \"%s\")", fields.length, expression)); |
267 | 273 | } |
| 274 | + doParse(fields); |
| 275 | + } |
| 276 | + |
| 277 | + private void doParse(String[] fields) { |
268 | 278 | setNumberHits(this.seconds, fields[0], 0, 60); |
269 | 279 | setNumberHits(this.minutes, fields[1], 0, 60); |
270 | 280 | setNumberHits(this.hours, fields[2], 0, 24); |
271 | 281 | setDaysOfMonth(this.daysOfMonth, fields[3]); |
272 | 282 | setMonths(this.months, fields[4]); |
273 | 283 | setDays(this.daysOfWeek, replaceOrdinals(fields[5], "SUN,MON,TUE,WED,THU,FRI,SAT"), 8); |
| 284 | + |
274 | 285 | if (this.daysOfWeek.get(7)) { |
275 | 286 | // Sunday can be represented as 0 or 7 |
276 | 287 | this.daysOfWeek.set(0); |
@@ -388,15 +399,25 @@ private int[] getRange(String field, int min, int max) { |
388 | 399 |
|
389 | 400 | /** |
390 | 401 | * Determine whether the specified expression represents a valid cron pattern. |
391 | | - * <p>Specifically, this method verifies that the expression contains six |
392 | | - * fields separated by single spaces. |
393 | 402 | * @param expression the expression to evaluate |
394 | 403 | * @return {@code true} if the given expression is a valid cron expression |
395 | 404 | * @since 4.3 |
396 | 405 | */ |
397 | 406 | public static boolean isValidExpression(String expression) { |
| 407 | + if (expression == null) { |
| 408 | + return false; |
| 409 | + } |
398 | 410 | String[] fields = StringUtils.tokenizeToStringArray(expression, " "); |
399 | | - return areValidCronFields(fields); |
| 411 | + if (!areValidCronFields(fields)) { |
| 412 | + return false; |
| 413 | + } |
| 414 | + try { |
| 415 | + new CronSequenceGenerator(expression, fields); |
| 416 | + return true; |
| 417 | + } |
| 418 | + catch (IllegalArgumentException ex) { |
| 419 | + return false; |
| 420 | + } |
400 | 421 | } |
401 | 422 |
|
402 | 423 | private static boolean areValidCronFields(String[] fields) { |
|
0 commit comments