Support macros in CronExpression

This commit introduces supports for macros like "@yearly", "@monthly",
etc. in CronExpression.

Closes gh-25471
This commit is contained in:
Arjen Poutsma
2020-07-24 11:29:49 +02:00
parent ea52627c38
commit 1a8906bdc3
2 changed files with 153 additions and 0 deletions

View File

@@ -41,6 +41,16 @@ public final class CronExpression {
static final int MAX_ATTEMPTS = 366;
private static final String[] MACROS = new String[] {
"@yearly", "0 0 0 1 1 *",
"@annually", "0 0 0 1 1 *",
"@monthly", "0 0 0 1 * *",
"@weekly", "0 0 0 * * 0",
"@daily", "0 0 0 * * *",
"@midnight", "0 0 0 * * *",
"@hourly", "0 0 * * * *"
};
private final CronField[] fields;
@@ -111,6 +121,15 @@ public final class CronExpression {
* <li>{@code "0 0 0 25 12 ?"} = every Christmas Day at midnight</li>
* </ul>
*
* <p>The following macros are also supported:
* <ul>
* <li>{@code "@yearly"} (or {@code "@annually"}) to run un once a year, i.e. {@code "0 0 0 1 1 *"},</li>
* <li>{@code "@monthly"} to run once a month, i.e. {@code "0 0 0 1 * *"},</li>
* <li>{@code "@weekly"} to run once a week, i.e. {@code "0 0 0 * * 0"},</li>
* <li>{@code "@daily"} (or {@code "@midnight"}) to run once a day, i.e. {@code "0 0 0 * * *"},</li>
* <li>{@code "@hourly"} to run once an hour, i.e. {@code "0 0 * * * *"}.</li>
* </ul>
*
* @param expression the expression string to parse
* @return the parsed {@code CronExpression} object
* @throws IllegalArgumentException in the expression does not conform to
@@ -119,6 +138,8 @@ public final class CronExpression {
public static CronExpression parse(String expression) {
Assert.hasLength(expression, "Expression string must not be empty");
expression = resolveMacros(expression);
String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
if (fields.length != 6) {
throw new IllegalArgumentException(String.format(
@@ -141,6 +162,17 @@ public final class CronExpression {
}
private static String resolveMacros(String expression) {
expression = expression.trim();
for (int i = 0; i < MACROS.length; i = i + 2) {
if (MACROS[i].equalsIgnoreCase(expression)) {
return MACROS[i + 1];
}
}
return expression;
}
/**
* Calculate the next {@link Temporal} that matches this expression.
* @param temporal the seed value