This commit is contained in:
Looly 2022-04-10 21:51:20 +08:00
parent eff60f0c86
commit ec1edde42c
5 changed files with 110 additions and 223 deletions

View File

@ -8,6 +8,7 @@
### ❌不兼容特性
* 【core 】 StreamProgress#progress方法参数变更为2个pr#594@Gitee
* 【core 】 SimpleCache的raw key使用Mutable
* 【core 】 ArrayUtil.join删除已经弃用的无用原始类型重载
### 🐣新特性
* 【core 】 CopyOptions支持以Lambda方式设置忽略属性列表pr#590@Gitee

View File

@ -1586,224 +1586,6 @@ public class PrimitiveArrayUtil {
return Arrays.copyOfRange(array, start, end);
}
// ------------------------------------------------------------------- join
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(int[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (int item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(long[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (long item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(short[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (short item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(char[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (char item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(byte[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (byte item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(boolean[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (boolean item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(float[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (float item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
/**
* conjunction 为分隔符将数组转换为字符串
*
* @param array 数组
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
*/
@Deprecated
public static String join(double[] array, CharSequence conjunction) {
if (null == array) {
return null;
}
final StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (double item : array) {
if (isFirst) {
isFirst = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
// ------------------------------------------------------------------- remove
/**

View File

@ -1,24 +1,84 @@
package cn.hutool.cron.pattern;
import cn.hutool.core.builder.Builder;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.StrJoiner;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
/**
* 定时任务表达式构建器
*
* @author looly
* @since 5.8.0
*/
public class CronPatternBuilder implements Builder<String> {
private static final long serialVersionUID = 1L;
final String[] parts = new String[7];
public static CronPatternBuilder of(){
/**
* 创建构建器
* @return CronPatternBuilder
*/
public static CronPatternBuilder of() {
return new CronPatternBuilder();
}
public CronPatternBuilder set(Part part, String value){
/**
* 设置值
*
* @param part 部分如秒时等
* @param values 时间值列表
* @return this
*/
public CronPatternBuilder setValues(Part part, int... values) {
for (int value : values) {
part.checkValue(value);
}
return set(part, ArrayUtil.join(values, ","));
}
/**
* 设置区间
*
* @param part 部分如秒时等
* @param begin 起始值
* @param end 结束值
* @return this
*/
public CronPatternBuilder setRange(Part part, int begin, int end) {
Assert.notNull(part );
part.checkValue(begin);
part.checkValue(end);
return set(part, StrUtil.format("{}-{}", begin, end));
}
/**
* 设置对应部分的定时任务值
*
* @param part 部分如秒时等
* @param value 表达式值"*""1,2""5-12"
* @return this
*/
public CronPatternBuilder set(Part part, String value) {
parts[part.ordinal()] = value;
return this;
}
@Override
public String build() {
return StrUtil.join(StrUtil.SPACE, (Object[]) parts);
for (int i = Part.MINUTE.ordinal(); i < Part.YEAR.ordinal(); i++) {
// 从分到周用户未设置使用默认值
// 秒和年如果不设置忽略之
if(StrUtil.isBlank(parts[i])){
parts[i] = "*";
}
}
return StrJoiner.of(StrUtil.SPACE)
.setNullMode(StrJoiner.NullMode.IGNORE)
.append(this.parts)
.toString();
}
}

View File

@ -50,7 +50,7 @@ public class PatternParser {
final List<String> patternList = StrUtil.splitTrim(groupPattern, '|');
final List<PatternMatcher> patternMatchers = new ArrayList<>(patternList.size());
for (String pattern : patternList) {
patternMatchers.add(parseSinglePattern(pattern));
patternMatchers.add(parseSingle(pattern));
}
return patternMatchers;
}
@ -61,7 +61,7 @@ public class PatternParser {
* @param pattern 表达式
* @return {@link PatternMatcher}
*/
private static PatternMatcher parseSinglePattern(String pattern) {
private static PatternMatcher parseSingle(String pattern) {
final String[] parts = pattern.split("\\s+");
Assert.checkBetween(parts.length, 5, 7,
() -> new CronException("Pattern [{}] is invalid, it must be 5-7 parts!", pattern));

View File

@ -0,0 +1,44 @@
package cn.hutool.cron.pattern;
import cn.hutool.cron.CronException;
import org.junit.Assert;
import org.junit.Test;
public class CronPatternBuilderTest {
@Test
public void buildMatchAllTest(){
String build = CronPatternBuilder.of().build();
Assert.assertEquals("* * * * *", build);
build = CronPatternBuilder.of()
.set(Part.SECOND, "*")
.build();
Assert.assertEquals("* * * * * *", build);
build = CronPatternBuilder.of()
.set(Part.SECOND, "*")
.set(Part.YEAR, "*")
.build();
Assert.assertEquals("* * * * * * *", build);
}
@Test
public void buildRangeTest(){
String build = CronPatternBuilder.of()
.set(Part.SECOND, "*")
.setRange(Part.HOUR, 2, 9)
.build();
Assert.assertEquals("* * 2-9 * * *", build);
}
@Test(expected = CronException.class)
public void buildRangeErrorTest(){
String build = CronPatternBuilder.of()
.set(Part.SECOND, "*")
// 55无效值
.setRange(Part.HOUR, 2, 55)
.build();
Assert.assertEquals("* * 2-9 * * *", build);
}
}