mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add methods
This commit is contained in:
parent
4fbda4565a
commit
8718e6dfe1
@ -13,6 +13,7 @@
|
||||
* 【core 】 【可能兼容问题】Base58分离编码和解码
|
||||
* 【core 】 【可能兼容问题】Base62分离编码和解码,增加inverted模式支持
|
||||
* 【core 】 【兼容问题 】PunyCode参数由String改为Charsequence
|
||||
* 【cron 】 【可能兼容问题】SimpleValueParser改名为AbsValueParser,改为abstract
|
||||
|
||||
### 🐣新特性
|
||||
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@Gitee)
|
||||
|
@ -1,51 +1,109 @@
|
||||
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,并限定最大值和最小值<br>
|
||||
* 此类同时识别{@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理定时任务表达式每个时间字段<br>
|
||||
* 多个时间使用逗号分隔
|
||||
*
|
||||
* @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<Integer> values = parseArray(value, parser);
|
||||
List<Integer> 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}<br>
|
||||
* 默认为{@link BoolArrayValueMatcher},如果有特殊实现,子类须重写此方法
|
||||
*
|
||||
* @param values 数字值列表
|
||||
* @return {@link ValueMatcher}
|
||||
*/
|
||||
protected ValueMatcher buildValueMatcher(List<Integer> values){
|
||||
return new BoolArrayValueMatcher(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,15 +114,14 @@ public class ValueMatcherBuilder {
|
||||
* <li><strong>a,b,c,d</strong></li>
|
||||
* </ul>
|
||||
* @param value 子表达式值
|
||||
* @param parser 针对这个字段的解析器
|
||||
* @return 值列表
|
||||
*/
|
||||
private static List<Integer> parseArray(String value, ValueParser parser){
|
||||
private List<Integer> parseArray(String value){
|
||||
final List<Integer> values = new ArrayList<>();
|
||||
|
||||
final List<String> parts = StrUtil.split(value, StrUtil.C_COMMA);
|
||||
for (String part : parts) {
|
||||
CollUtil.addAllIfNotContains(values, parseStep(part, parser));
|
||||
CollUtil.addAllIfNotContains(values, parseStep(part));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -79,22 +136,21 @@ public class ValueMatcherBuilder {
|
||||
* </ul>
|
||||
*
|
||||
* @param value 表达式值
|
||||
* @param parser 针对这个时间字段的解析器
|
||||
* @return List
|
||||
*/
|
||||
private static List<Integer> parseStep(String value, ValueParser parser) {
|
||||
private List<Integer> parseStep(String value) {
|
||||
final List<String> parts = StrUtil.split(value, StrUtil.C_SLASH);
|
||||
int size = parts.size();
|
||||
|
||||
List<Integer> 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);
|
||||
}
|
||||
@ -113,18 +169,17 @@ public class ValueMatcherBuilder {
|
||||
*
|
||||
* @param value 范围表达式
|
||||
* @param step 步进
|
||||
* @param parser 针对这个时间字段的解析器
|
||||
* @return List
|
||||
*/
|
||||
private static List<Integer> parseRange(String value, int step, ValueParser parser) {
|
||||
private List<Integer> parseRange(String value, int step) {
|
||||
final List<Integer> 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<String> 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,10 +222,10 @@ 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);
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 每月的几号值处理<br>
|
||||
@ -9,8 +14,11 @@ import cn.hutool.cron.CronException;
|
||||
* @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<Integer> values) {
|
||||
//考虑每月的天数不同,且存在闰年情况,日匹配单独使用
|
||||
return new DayOfMonthValueMatcher(values);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.CronException;
|
||||
import cn.hutool.cron.pattern.matcher.MatcherTable;
|
||||
|
||||
/**
|
||||
* 星期值处理<br>
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析别名
|
||||
*
|
||||
|
@ -1,15 +1,26 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.CronException;
|
||||
import cn.hutool.cron.pattern.matcher.MatcherTable;
|
||||
|
||||
/**
|
||||
* 小时值处理<br>
|
||||
* 小时被限定在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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,29 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.CronException;
|
||||
import cn.hutool.cron.pattern.matcher.MatcherTable;
|
||||
|
||||
/**
|
||||
* 分钟值处理<br>
|
||||
* 限定于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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.CronException;
|
||||
import cn.hutool.cron.pattern.matcher.MatcherTable;
|
||||
|
||||
/**
|
||||
* 月份值处理<br>
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析别名
|
||||
*
|
||||
|
@ -1,5 +1,8 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.CronException;
|
||||
import cn.hutool.cron.pattern.matcher.MatcherTable;
|
||||
|
||||
/**
|
||||
* 秒值处理<br>
|
||||
* 限定于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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.CronException;
|
||||
|
||||
/**
|
||||
* 简易值转换器。将给定String值转为int,并限定最大值和最小值<br>
|
||||
* 此类同时识别{@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;
|
||||
}
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package cn.hutool.cron.pattern.parser;
|
||||
|
||||
import cn.hutool.cron.pattern.matcher.MatcherTable;
|
||||
import cn.hutool.cron.pattern.matcher.ValueMatcher;
|
||||
|
||||
/**
|
||||
* 值处理接口<br>
|
||||
* 值处理用于限定表达式中相应位置的值范围,并转换表达式值为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},支持的表达式包括:
|
||||
* <ul>
|
||||
* <li>单值或通配符形式,如 <strong>a</strong> 或 <strong>*</strong></li>
|
||||
* <li>数组形式,如 <strong>1,2,3</strong></li>
|
||||
* <li>间隔形式,如 <strong>a/b</strong> 或 <strong>*/b</strong></li>
|
||||
* <li>范围形式,如 <strong>3-8</strong></li>
|
||||
* </ul>
|
||||
*
|
||||
* @param pattern 对应时间部分的表达式
|
||||
* @return {@link ValueMatcher}
|
||||
*/
|
||||
ValueMatcher parseAsValueMatcher(String pattern);
|
||||
|
||||
/**
|
||||
* 处理String值并转为int<br>
|
||||
* 转换包括:
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* 年值处理<br>
|
||||
* 年的限定在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<Integer> values) {
|
||||
//考虑年数字太大,不适合boolean数组,单独使用列表遍历匹配
|
||||
return new YearValueMatcher(values);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user