diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf4f4ca78..24a0d664b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
* 【core 】 【可能兼容问题】Base58分离编码和解码
* 【core 】 【可能兼容问题】Base62分离编码和解码,增加inverted模式支持
* 【core 】 【兼容问题 】PunyCode参数由String改为Charsequence
+* 【cron 】 【可能兼容问题】SimpleValueParser改名为AbsValueParser,改为abstract
### 🐣新特性
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@Gitee)
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/ValueMatcherBuilder.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/AbsValueParser.java
similarity index 58%
rename from hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/ValueMatcherBuilder.java
rename to hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/AbsValueParser.java
index 4cc06ccb0..a436e78de 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/ValueMatcherBuilder.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/AbsValueParser.java
@@ -1,53 +1,111 @@
-package cn.hutool.cron.pattern.matcher;
+package cn.hutool.cron.pattern.parser;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronException;
-import cn.hutool.cron.pattern.parser.DayOfMonthValueParser;
-import cn.hutool.cron.pattern.parser.ValueParser;
-import cn.hutool.cron.pattern.parser.YearValueParser;
+import cn.hutool.cron.pattern.matcher.AlwaysTrueValueMatcher;
+import cn.hutool.cron.pattern.matcher.BoolArrayValueMatcher;
+import cn.hutool.cron.pattern.matcher.ValueMatcher;
import java.util.ArrayList;
import java.util.List;
/**
- * {@link ValueMatcher} 构建器,用于构建表达式中每一项的匹配器
- * @author Looly
+ * 简易值转换器。将给定String值转为int,并限定最大值和最小值
+ * 此类同时识别{@code L} 为最大值。
*
+ * @author Looly
*/
-public class ValueMatcherBuilder {
-
+public abstract class AbsValueParser implements ValueParser {
+
+ /**
+ * 最小值(包括)
+ */
+ protected int min;
+ /**
+ * 最大值(包括)
+ */
+ protected int max;
+
+ /**
+ * 构造
+ *
+ * @param min 最小值(包括)
+ * @param max 最大值(包括)
+ */
+ public AbsValueParser(int min, int max) {
+ if (min > max) {
+ this.min = max;
+ this.max = min;
+ } else {
+ this.min = min;
+ this.max = max;
+ }
+ }
+
+ @Override
+ public int parse(String value) throws CronException {
+ if ("L".equalsIgnoreCase(value)) {
+ // L表示最大值
+ return max;
+ }
+
+ int i;
+ try {
+ i = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new CronException(e, "Invalid integer value: '{}'", value);
+ }
+ if (i < min || i > max) {
+ throw new CronException("Value {} out of range: [{} , {}]", i, min, max);
+ }
+ return i;
+ }
+
+ @Override
+ public int getMin() {
+ return this.min;
+ }
+
+ @Override
+ public int getMax() {
+ return this.max;
+ }
+
/**
* 处理定时任务表达式每个时间字段
* 多个时间使用逗号分隔
- *
+ *
* @param value 某个时间字段
- * @param parser 针对这个时间字段的解析器
* @return List
*/
- public static ValueMatcher build(String value, ValueParser parser) {
+ @Override
+ public ValueMatcher parseAsValueMatcher(String value) {
if (isMatchAllStr(value)) {
//兼容Quartz的"?"表达式,不会出现互斥情况,与"*"作用相同
return new AlwaysTrueValueMatcher();
}
- List values = parseArray(value, parser);
+ List values = parseArray(value);
if (values.size() == 0) {
throw new CronException("Invalid field: [{}]", value);
}
- if (parser instanceof DayOfMonthValueParser) {
- //考虑每月的天数不同,且存在闰年情况,日匹配单独使用
- return new DayOfMonthValueMatcher(values);
- }else if(parser instanceof YearValueParser){
- //考虑年数字太大,不适合boolean数组,单独使用列表遍历匹配
- return new YearValueMatcher(values);
- }else {
- return new BoolArrayValueMatcher(values);
- }
+ return buildValueMatcher(values);
}
-
+
+ /**
+ * 根据解析的数字值列表构建{@link ValueMatcher}
+ * 默认为{@link BoolArrayValueMatcher},如果有特殊实现,子类须重写此方法
+ *
+ * @param values 数字值列表
+ * @return {@link ValueMatcher}
+ */
+ protected ValueMatcher buildValueMatcher(List values){
+ return new BoolArrayValueMatcher(values);
+ }
+
/**
* 处理数组形式表达式
* 处理的形式包括:
@@ -56,15 +114,14 @@ public class ValueMatcherBuilder {
* a,b,c,d
*
* @param value 子表达式值
- * @param parser 针对这个字段的解析器
* @return 值列表
*/
- private static List parseArray(String value, ValueParser parser){
+ private List parseArray(String value){
final List values = new ArrayList<>();
-
+
final List parts = StrUtil.split(value, StrUtil.C_COMMA);
for (String part : parts) {
- CollUtil.addAllIfNotContains(values, parseStep(part, parser));
+ CollUtil.addAllIfNotContains(values, parseStep(part));
}
return values;
}
@@ -77,24 +134,23 @@ public class ValueMatcherBuilder {
* a/b 或 */b
* a-b/2
*
- *
+ *
* @param value 表达式值
- * @param parser 针对这个时间字段的解析器
* @return List
*/
- private static List parseStep(String value, ValueParser parser) {
+ private List parseStep(String value) {
final List parts = StrUtil.split(value, StrUtil.C_SLASH);
int size = parts.size();
-
+
List results;
if (size == 1) {// 普通形式
- results = parseRange(value, -1, parser);
+ results = parseRange(value, -1);
} else if (size == 2) {// 间隔形式
- final int step = parser.parse(parts.get(1));
+ final int step = parse(parts.get(1));
if (step < 1) {
throw new CronException("Non positive divisor for field: [{}]", value);
}
- results = parseRange(parts.get(0), step, parser);
+ results = parseRange(parts.get(0), step);
} else {
throw new CronException("Invalid syntax of field: [{}]", value);
}
@@ -110,21 +166,20 @@ public class ValueMatcherBuilder {
* 8-3
* 3-3
*
- *
+ *
* @param value 范围表达式
* @param step 步进
- * @param parser 针对这个时间字段的解析器
* @return List
*/
- private static List parseRange(String value, int step, ValueParser parser) {
+ private List parseRange(String value, int step) {
final List results = new ArrayList<>();
-
+
// 全部匹配形式
if (value.length() <= 2) {
//根据步进的第一个数字确定起始时间,类似于 12/3则从12(秒、分等)开始
- int minValue = parser.getMin();
+ int minValue = getMin();
if(false == isMatchAllStr(value)) {
- minValue = Math.max(minValue, parser.parse(value));
+ minValue = Math.max(minValue, parse(value));
}else {
//在全匹配模式下,如果步进不存在,表示步进为1
if(step < 1) {
@@ -132,7 +187,7 @@ public class ValueMatcherBuilder {
}
}
if(step > 0) {
- final int maxValue = parser.getMax();
+ final int maxValue = getMax();
if(minValue > maxValue) {
throw new CronException("Invalid value {} > {}", minValue, maxValue);
}
@@ -151,15 +206,15 @@ public class ValueMatcherBuilder {
List parts = StrUtil.split(value, '-');
int size = parts.size();
if (size == 1) {// 普通值
- final int v1 = parser.parse(value);
+ final int v1 = parse(value);
if(step > 0) {//类似 20/2的形式
- NumberUtil.appendRange(v1, parser.getMax(), step, results);
+ NumberUtil.appendRange(v1, getMax(), step, results);
}else {
results.add(v1);
}
} else if (size == 2) {// range值
- final int v1 = parser.parse(parts.get(0));
- final int v2 = parser.parse(parts.get(1));
+ final int v1 = parse(parts.get(0));
+ final int v2 = parse(parts.get(1));
if(step < 1) {
//在range模式下,如果步进不存在,表示步进为1
step = 1;
@@ -167,21 +222,21 @@ public class ValueMatcherBuilder {
if (v1 < v2) {// 正常范围,例如:2-5
NumberUtil.appendRange(v1, v2, step, results);
} else if (v1 > v2) {// 逆向范围,反选模式,例如:5-2
- NumberUtil.appendRange(v1, parser.getMax(), step, results);
- NumberUtil.appendRange(parser.getMin(), v2, step, results);
+ NumberUtil.appendRange(v1, getMax(), step, results);
+ NumberUtil.appendRange(getMin(), v2, step, results);
} else {// v1 == v2,此时与单值模式一致
- NumberUtil.appendRange(v1, parser.getMax(), step, results);
+ NumberUtil.appendRange(v1, getMax(), step, results);
}
} else {
throw new CronException("Invalid syntax of field: [{}]", value);
}
return results;
}
-
+
/**
* 是否为全匹配符
* 全匹配符指 * 或者 ?
- *
+ *
* @param value 被检查的值
* @return 是否为全匹配符
* @since 4.1.18
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/CronPatternParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/CronPatternParser.java
index e85e20dee..052fb42cf 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/CronPatternParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/CronPatternParser.java
@@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronException;
import cn.hutool.cron.pattern.matcher.AlwaysTrueValueMatcher;
import cn.hutool.cron.pattern.matcher.MatcherTable;
-import cn.hutool.cron.pattern.matcher.ValueMatcherBuilder;
import java.util.List;
@@ -78,55 +77,40 @@ public class CronPatternParser {
throw new CronException("Pattern [{}] is invalid, it must be 5-7 parts!", pattern);
}
- // 秒
- if (1 == offset) {// 支持秒的表达式
- try {
- matcherTable.secondMatchers.add(ValueMatcherBuilder.build(parts[0], SECOND_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'second' field error!", pattern);
- }
- } else {// 不支持秒的表达式,则第一位按照表达式生成时间的秒数赋值,表示整分匹配
- matcherTable.secondMatchers.add(ValueMatcherBuilder.build(String.valueOf(DateUtil.date().second()), SECOND_VALUE_PARSER));
- }
+ // 秒,如果不支持秒的表达式,则第一位按照表达式生成时间的秒数赋值,表示整分匹配
+ final String secondPart = (1 == offset) ? parts[0] : String.valueOf(DateUtil.date().second());
+ parseToTable(SECOND_VALUE_PARSER, secondPart);
+
// 分
- try {
- matcherTable.minuteMatchers.add(ValueMatcherBuilder.build(parts[offset], MINUTE_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'minute' field error!", pattern);
- }
- // 小时
- try {
- matcherTable.hourMatchers.add(ValueMatcherBuilder.build(parts[1 + offset], HOUR_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'hour' field error!", pattern);
- }
- // 每月第几天
- try {
- matcherTable.dayOfMonthMatchers.add(ValueMatcherBuilder.build(parts[2 + offset], DAY_OF_MONTH_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'day of month' field error!", pattern);
- }
+ parseToTable(MINUTE_VALUE_PARSER, parts[offset]);
+
+ // 时
+ parseToTable(HOUR_VALUE_PARSER, parts[1 + offset]);
+
+ // 天
+ parseToTable(DAY_OF_MONTH_VALUE_PARSER, parts[2 + offset]);
+
// 月
- try {
- matcherTable.monthMatchers.add(ValueMatcherBuilder.build(parts[3 + offset], MONTH_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'month' field error!", pattern);
- }
- // 星期几
- try {
- matcherTable.dayOfWeekMatchers.add(ValueMatcherBuilder.build(parts[4 + offset], DAY_OF_WEEK_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'day of week' field error!", pattern);
- }
+ parseToTable(MONTH_VALUE_PARSER, parts[3 + offset]);
+
+ // 周
+ parseToTable(DAY_OF_WEEK_VALUE_PARSER, parts[4 + offset]);
+
// 年
if (parts.length == 7) {// 支持年的表达式
- try {
- matcherTable.yearMatchers.add(ValueMatcherBuilder.build(parts[6], YEAR_VALUE_PARSER));
- } catch (Exception e) {
- throw new CronException(e, "Invalid pattern [{}], parsing 'year' field error!", pattern);
- }
+ parseToTable(YEAR_VALUE_PARSER, parts[6]);
} else {// 不支持年的表达式,全部匹配
matcherTable.yearMatchers.add(new AlwaysTrueValueMatcher());
}
}
+
+ /**
+ * 将表达式解析后加入到{@link #matcherTable}中
+ *
+ * @param valueParser 表达式解析器
+ * @param patternPart 表达式部分
+ */
+ private void parseToTable(ValueParser valueParser, String patternPart) {
+ valueParser.parseTo(this.matcherTable, patternPart);
+ }
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfMonthValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfMonthValueParser.java
index 2cac2a8b5..e3ddea83e 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfMonthValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfMonthValueParser.java
@@ -1,16 +1,24 @@
package cn.hutool.cron.pattern.parser;
import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.DayOfMonthValueMatcher;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
+import cn.hutool.cron.pattern.matcher.ValueMatcher;
+
+import java.util.List;
/**
* 每月的几号值处理
* 每月最多31天,32和“L”都表示最后一天
- *
+ *
* @author Looly
*
*/
-public class DayOfMonthValueParser extends SimpleValueParser {
+public class DayOfMonthValueParser extends AbsValueParser {
+ /**
+ * 构造
+ */
public DayOfMonthValueParser() {
super(1, 31);
}
@@ -23,4 +31,19 @@ public class DayOfMonthValueParser extends SimpleValueParser {
return super.parse(value);
}
}
+
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.dayOfMonthMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'day of month' field error!", pattern);
+ }
+ }
+
+ @Override
+ protected ValueMatcher buildValueMatcher(List values) {
+ //考虑每月的天数不同,且存在闰年情况,日匹配单独使用
+ return new DayOfMonthValueMatcher(values);
+ }
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfWeekValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfWeekValueParser.java
index bf486c31c..8b608db44 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfWeekValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/DayOfWeekValueParser.java
@@ -1,6 +1,7 @@
package cn.hutool.cron.pattern.parser;
import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
/**
* 星期值处理
@@ -9,7 +10,7 @@ import cn.hutool.cron.CronException;
*
* @author Looly
*/
-public class DayOfWeekValueParser extends SimpleValueParser {
+public class DayOfWeekValueParser extends AbsValueParser {
/**
* Weeks aliases.
@@ -33,6 +34,15 @@ public class DayOfWeekValueParser extends SimpleValueParser {
}
}
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.dayOfWeekMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'day of week' field error!", pattern);
+ }
+ }
+
/**
* 解析别名
*
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/HourValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/HourValueParser.java
index ad3c530cb..bc7b5159c 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/HourValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/HourValueParser.java
@@ -1,15 +1,26 @@
package cn.hutool.cron.pattern.parser;
+import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
+
/**
* 小时值处理
* 小时被限定在0-23
*
* @author Looly
*/
-public class HourValueParser extends SimpleValueParser {
+public class HourValueParser extends AbsValueParser {
public HourValueParser() {
super(0, 23);
}
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.hourMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'hour' field error!", pattern);
+ }
+ }
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MinuteValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MinuteValueParser.java
index 28fda7468..f2f76768a 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MinuteValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MinuteValueParser.java
@@ -1,15 +1,29 @@
package cn.hutool.cron.pattern.parser;
+import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
+
/**
* 分钟值处理
* 限定于0-59
*
* @author Looly
*/
-public class MinuteValueParser extends SimpleValueParser {
+public class MinuteValueParser extends AbsValueParser {
+ /**
+ * 构造
+ */
public MinuteValueParser() {
super(0, 59);
}
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.minuteMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'minute' field error!", pattern);
+ }
+ }
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MonthValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MonthValueParser.java
index 3a85d72e0..e58a62bb9 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MonthValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/MonthValueParser.java
@@ -1,6 +1,7 @@
package cn.hutool.cron.pattern.parser;
import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
/**
* 月份值处理
@@ -8,7 +9,7 @@ import cn.hutool.cron.CronException;
*
* @author Looly
*/
-public class MonthValueParser extends SimpleValueParser {
+public class MonthValueParser extends AbsValueParser {
/**
* Months aliases.
@@ -28,6 +29,15 @@ public class MonthValueParser extends SimpleValueParser {
}
}
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.monthMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'month' field error!", pattern);
+ }
+ }
+
/**
* 解析别名
*
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SecondValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SecondValueParser.java
index ae0839c49..084157a81 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SecondValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SecondValueParser.java
@@ -1,5 +1,8 @@
package cn.hutool.cron.pattern.parser;
+import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
+
/**
* 秒值处理
* 限定于0-59
@@ -7,4 +10,13 @@ package cn.hutool.cron.pattern.parser;
* @author Looly
*/
public class SecondValueParser extends MinuteValueParser {
+
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.secondMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'second' field error!", pattern);
+ }
+ }
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SimpleValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SimpleValueParser.java
deleted file mode 100644
index 7a3d139e9..000000000
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/SimpleValueParser.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package cn.hutool.cron.pattern.parser;
-
-import cn.hutool.cron.CronException;
-
-/**
- * 简易值转换器。将给定String值转为int,并限定最大值和最小值
- * 此类同时识别{@code L} 为最大值。
- *
- * @author Looly
- */
-public class SimpleValueParser implements ValueParser {
-
- /**
- * 最小值(包括)
- */
- protected int min;
- /**
- * 最大值(包括)
- */
- protected int max;
-
- /**
- * 构造
- *
- * @param min 最小值(包括)
- * @param max 最大值(包括)
- */
- public SimpleValueParser(int min, int max) {
- if (min > max) {
- this.min = max;
- this.max = min;
- } else {
- this.min = min;
- this.max = max;
- }
- }
-
- @Override
- public int parse(String value) throws CronException {
- if ("L".equalsIgnoreCase(value)) {
- // L表示最大值
- return max;
- }
-
- int i;
- try {
- i = Integer.parseInt(value);
- } catch (NumberFormatException e) {
- throw new CronException(e, "Invalid integer value: '{}'", value);
- }
- if (i < min || i > max) {
- throw new CronException("Value {} out of range: [{} , {}]", i, min, max);
- }
- return i;
- }
-
- @Override
- public int getMin() {
- return this.min;
- }
-
- @Override
- public int getMax() {
- return this.max;
- }
-}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/ValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/ValueParser.java
index 97c62fbf1..2e49f624f 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/ValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/ValueParser.java
@@ -1,5 +1,8 @@
package cn.hutool.cron.pattern.parser;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
+import cn.hutool.cron.pattern.matcher.ValueMatcher;
+
/**
* 值处理接口
* 值处理用于限定表达式中相应位置的值范围,并转换表达式值为int值
@@ -8,6 +11,28 @@ package cn.hutool.cron.pattern.parser;
*/
public interface ValueParser {
+ /**
+ * 解析表达式后,加入到{@link MatcherTable}的对应列表中
+ *
+ * @param matcherTable {@link MatcherTable}
+ * @param pattern 对应时间部分的表达式
+ */
+ void parseTo(MatcherTable matcherTable, String pattern);
+
+ /**
+ * 解析表达式对应部分为{@link ValueMatcher},支持的表达式包括:
+ *
+ * - 单值或通配符形式,如 a 或 *
+ * - 数组形式,如 1,2,3
+ * - 间隔形式,如 a/b 或 */b
+ * - 范围形式,如 3-8
+ *
+ *
+ * @param pattern 对应时间部分的表达式
+ * @return {@link ValueMatcher}
+ */
+ ValueMatcher parseAsValueMatcher(String pattern);
+
/**
* 处理String值并转为int
* 转换包括:
@@ -15,7 +40,7 @@ public interface ValueParser {
* 数字字符串转为数字
* 别名转为对应的数字(如月份和星期)
*
- *
+ *
* @param value String值
* @return int
*/
@@ -23,14 +48,14 @@ public interface ValueParser {
/**
* 返回最小值
- *
+ *
* @return 最小值
*/
int getMin();
/**
* 返回最大值
- *
+ *
* @return 最大值
*/
int getMax();
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/YearValueParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/YearValueParser.java
index 858d020dd..484a1cf4b 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/YearValueParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/YearValueParser.java
@@ -1,15 +1,36 @@
package cn.hutool.cron.pattern.parser;
+import cn.hutool.cron.CronException;
+import cn.hutool.cron.pattern.matcher.MatcherTable;
+import cn.hutool.cron.pattern.matcher.ValueMatcher;
+import cn.hutool.cron.pattern.matcher.YearValueMatcher;
+
+import java.util.List;
+
/**
* 年值处理
* 年的限定在1970-2099年
*
* @author Looly
*/
-public class YearValueParser extends SimpleValueParser {
+public class YearValueParser extends AbsValueParser {
public YearValueParser() {
super(1970, 2099);
}
+ @Override
+ public void parseTo(MatcherTable matcherTable, String pattern) {
+ try {
+ matcherTable.yearMatchers.add(parseAsValueMatcher(pattern));
+ } catch (Exception e) {
+ throw new CronException(e, "Invalid pattern [{}], parsing 'year' field error!", pattern);
+ }
+ }
+
+ @Override
+ protected ValueMatcher buildValueMatcher(List values) {
+ //考虑年数字太大,不适合boolean数组,单独使用列表遍历匹配
+ return new YearValueMatcher(values);
+ }
}