Merge remote-tracking branch 'origin/fix-bug-202303' into fix-bug-202303

This commit is contained in:
梁琦涛
2023-03-10 15:23:53 +08:00
7 changed files with 253 additions and 247 deletions
@@ -17,18 +17,11 @@
package com.xxl.job.admin.core.cron; package com.xxl.job.admin.core.cron;
import lombok.val;
import java.io.Serializable; import java.io.Serializable;
import java.text.ParseException; import java.text.ParseException;
import java.util.Calendar; import java.util.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.TreeSet;
/** /**
* Provides a parser and evaluator for unix-like cron expressions. Cron * Provides a parser and evaluator for unix-like cron expressions. Cron
@@ -191,13 +184,11 @@ import java.util.TreeSet;
* </ul> * </ul>
* </p> * </p>
* *
*
* @author Sharada Jambula, James House * @author Sharada Jambula, James House
* @author Contributions from Mads Henderson * @author Contributions from Mads Henderson
* @author Refactoring from CronTrigger to CronExpression by Aaron Craven * @author Refactoring from CronTrigger to CronExpression by Aaron Craven
* * <p>
* Borrowed from quartz v2.3.1 * Borrowed from quartz v2.3.1
*
*/ */
public final class CronExpression implements Serializable, Cloneable { public final class CronExpression implements Serializable, Cloneable {
@@ -215,8 +206,9 @@ public final class CronExpression implements Serializable, Cloneable {
protected static final Integer ALL_SPEC = ALL_SPEC_INT; protected static final Integer ALL_SPEC = ALL_SPEC_INT;
protected static final Integer NO_SPEC = NO_SPEC_INT; protected static final Integer NO_SPEC = NO_SPEC_INT;
protected static final Map<String, Integer> monthMap = new HashMap<String, Integer>(20); protected static final Map<String, Integer> monthMap = new HashMap<>(20);
protected static final Map<String, Integer> dayMap = new HashMap<String, Integer>(60); protected static final Map<String, Integer> dayMap = new HashMap<>(60);
static { static {
monthMap.put("JAN", 0); monthMap.put("JAN", 0);
monthMap.put("FEB", 1); monthMap.put("FEB", 1);
@@ -265,9 +257,8 @@ public final class CronExpression implements Serializable, Cloneable {
* *
* @param cronExpression String representation of the cron expression the * @param cronExpression String representation of the cron expression the
* new object should represent * new object should represent
* @throws java.text.ParseException * @throws java.text.ParseException if the string expression cannot be parsed into a valid
* if the string expression cannot be parsed into a valid * <CODE>CronExpression</CODE>
* <CODE>CronExpression</CODE>
*/ */
public CronExpression(String cronExpression) throws ParseException { public CronExpression(String cronExpression) throws ParseException {
if (cronExpression == null) { if (cronExpression == null) {
@@ -283,8 +274,7 @@ public final class CronExpression implements Serializable, Cloneable {
* Constructs a new {@code CronExpression} as a copy of an existing * Constructs a new {@code CronExpression} as a copy of an existing
* instance. * instance.
* *
* @param expression * @param expression The existing cron expression to be copied
* The existing cron expression to be copied
*/ */
public CronExpression(CronExpression expression) { public CronExpression(CronExpression expression) {
/* /*
@@ -310,7 +300,7 @@ public final class CronExpression implements Serializable, Cloneable {
* *
* @param date the date to evaluate * @param date the date to evaluate
* @return a boolean indicating whether the given date satisfies the cron * @return a boolean indicating whether the given date satisfies the cron
* expression * expression
*/ */
public boolean isSatisfiedBy(Date date) { public boolean isSatisfiedBy(Date date) {
Calendar testDateCal = Calendar.getInstance(getTimeZone()); Calendar testDateCal = Calendar.getInstance(getTimeZone());
@@ -363,8 +353,9 @@ public final class CronExpression implements Serializable, Cloneable {
// the second immediately following it. // the second immediately following it.
while (difference == 1000) { while (difference == 1000) {
newDate = getTimeAfter(lastDate); newDate = getTimeAfter(lastDate);
if(newDate == null) if (newDate == null) {
break; break;
}
difference = newDate.getTime() - lastDate.getTime(); difference = newDate.getTime() - lastDate.getTime();
@@ -412,7 +403,7 @@ public final class CronExpression implements Serializable, Cloneable {
* *
* @param cronExpression the expression to evaluate * @param cronExpression the expression to evaluate
* @return a boolean indicating whether the given expression is a valid cron * @return a boolean indicating whether the given expression is a valid cron
* expression * expression
*/ */
public static boolean isValidExpression(String cronExpression) { public static boolean isValidExpression(String cronExpression) {
@@ -443,25 +434,25 @@ public final class CronExpression implements Serializable, Cloneable {
try { try {
if (seconds == null) { if (seconds == null) {
seconds = new TreeSet<Integer>(); seconds = new TreeSet<>();
} }
if (minutes == null) { if (minutes == null) {
minutes = new TreeSet<Integer>(); minutes = new TreeSet<>();
} }
if (hours == null) { if (hours == null) {
hours = new TreeSet<Integer>(); hours = new TreeSet<>();
} }
if (daysOfMonth == null) { if (daysOfMonth == null) {
daysOfMonth = new TreeSet<Integer>(); daysOfMonth = new TreeSet<>();
} }
if (months == null) { if (months == null) {
months = new TreeSet<Integer>(); months = new TreeSet<>();
} }
if (daysOfWeek == null) { if (daysOfWeek == null) {
daysOfWeek = new TreeSet<Integer>(); daysOfWeek = new TreeSet<>();
} }
if (years == null) { if (years == null) {
years = new TreeSet<Integer>(); years = new TreeSet<>();
} }
int exprOn = SECOND; int exprOn = SECOND;
@@ -473,14 +464,14 @@ public final class CronExpression implements Serializable, Cloneable {
String expr = exprsTok.nextToken().trim(); String expr = exprsTok.nextToken().trim();
// throw an exception if L is used with other days of the month // throw an exception if L is used with other days of the month
if(exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) { if (exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
throw new ParseException("Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1); throw new ParseException("Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1);
} }
// throw an exception if L is used with other days of the week // throw an exception if L is used with other days of the week
if(exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) { if (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1); throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1);
} }
if(exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') +1) != -1) { if (exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') + 1) != -1) {
throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1); throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1);
} }
@@ -495,7 +486,7 @@ public final class CronExpression implements Serializable, Cloneable {
if (exprOn <= DAY_OF_WEEK) { if (exprOn <= DAY_OF_WEEK) {
throw new ParseException("Unexpected end of expression.", throw new ParseException("Unexpected end of expression.",
expression.length()); expression.length());
} }
if (exprOn <= YEAR) { if (exprOn <= YEAR) {
@@ -506,14 +497,12 @@ public final class CronExpression implements Serializable, Cloneable {
TreeSet<Integer> dom = getSet(DAY_OF_MONTH); TreeSet<Integer> dom = getSet(DAY_OF_MONTH);
// Copying the logic from the UnsupportedOperationException below // Copying the logic from the UnsupportedOperationException below
assert dom != null;
boolean dayOfMSpec = !dom.contains(NO_SPEC); boolean dayOfMSpec = !dom.contains(NO_SPEC);
boolean dayOfWSpec = !dow.contains(NO_SPEC); boolean dayOfWSpec = !dow.contains(NO_SPEC);
if ((!dayOfMSpec || dayOfWSpec) && (!dayOfWSpec || dayOfMSpec)) {
if (!dayOfMSpec || dayOfWSpec) { throw new ParseException(
if (!dayOfWSpec || dayOfMSpec) { "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0);
throw new ParseException(
"Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0);
}
} }
} catch (ParseException pe) { } catch (ParseException pe) {
throw pe; throw pe;
@@ -524,7 +513,7 @@ public final class CronExpression implements Serializable, Cloneable {
} }
protected int storeExpressionVals(int pos, String s, int type) protected int storeExpressionVals(int pos, String s, int type)
throws ParseException { throws ParseException {
int incr = 0; int incr = 0;
int i = skipWhiteSpace(pos, s); int i = skipWhiteSpace(pos, s);
@@ -532,7 +521,7 @@ public final class CronExpression implements Serializable, Cloneable {
return i; return i;
} }
char c = s.charAt(i); char c = s.charAt(i);
if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) { if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-\\d*W?"))) {
String sub = s.substring(i, i + 3); String sub = s.substring(i, i + 3);
int sval = -1; int sval = -1;
int eval = -1; int eval = -1;
@@ -556,7 +545,7 @@ public final class CronExpression implements Serializable, Cloneable {
sval = getDayOfWeekNumber(sub); sval = getDayOfWeekNumber(sub);
if (sval < 0) { if (sval < 0) {
throw new ParseException("Invalid Day-of-Week value: '" throw new ParseException("Invalid Day-of-Week value: '"
+ sub + "'", i); + sub + "'", i);
} }
if (s.length() > i + 3) { if (s.length() > i + 3) {
c = s.charAt(i + 3); c = s.charAt(i + 3);
@@ -567,7 +556,7 @@ public final class CronExpression implements Serializable, Cloneable {
if (eval < 0) { if (eval < 0) {
throw new ParseException( throw new ParseException(
"Invalid Day-of-Week value: '" + sub "Invalid Day-of-Week value: '" + sub
+ "'", i); + "'", i);
} }
} else if (c == '#') { } else if (c == '#') {
try { try {
@@ -604,19 +593,19 @@ public final class CronExpression implements Serializable, Cloneable {
if ((i + 1) < s.length() if ((i + 1) < s.length()
&& (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) { && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) {
throw new ParseException("Illegal character after '?': " throw new ParseException("Illegal character after '?': "
+ s.charAt(i), i); + s.charAt(i), i);
} }
if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) { if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {
throw new ParseException( throw new ParseException(
"'?' can only be specified for Day-of-Month or Day-of-Week.", "'?' can only be specified for Day-of-Month or Day-of-Week.",
i); i);
} }
if (type == DAY_OF_WEEK && !lastdayOfMonth) { if (type == DAY_OF_WEEK && !lastdayOfMonth) {
int val = daysOfMonth.last(); int val = daysOfMonth.last();
if (val == NO_SPEC_INT) { if (val == NO_SPEC_INT) {
throw new ParseException( throw new ParseException(
"'?' can only be specified for Day-of-Month -OR- Day-of-Week.", "'?' can only be specified for Day-of-Month -OR- Day-of-Week.",
i); i);
} }
} }
@@ -630,7 +619,7 @@ public final class CronExpression implements Serializable, Cloneable {
return i + 1; return i + 1;
} else if (c == '/' } else if (c == '/'
&& ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s
.charAt(i + 1) == '\t')) { .charAt(i + 1) == '\t')) {
throw new ParseException("'/' must be followed by an integer.", i); throw new ParseException("'/' must be followed by an integer.", i);
} else if (c == '*') { } else if (c == '*') {
i++; i++;
@@ -663,18 +652,19 @@ public final class CronExpression implements Serializable, Cloneable {
if (type == DAY_OF_WEEK) { if (type == DAY_OF_WEEK) {
addToSet(7, 7, 0, type); addToSet(7, 7, 0, type);
} }
if(type == DAY_OF_MONTH && s.length() > i) { if (type == DAY_OF_MONTH && s.length() > i) {
c = s.charAt(i); c = s.charAt(i);
if(c == '-') { if (c == '-') {
ValueSet vs = getValue(0, s, i+1); ValueSet vs = getValue(0, s, i + 1);
lastdayOffset = vs.value; lastdayOffset = vs.value;
if(lastdayOffset > 30) if (lastdayOffset > 30) {
throw new ParseException("Offset from last day must be <= 30", i+1); throw new ParseException("Offset from last day must be <= 30", i + 1);
}
i = vs.pos; i = vs.pos;
} }
if(s.length() > i) { if (s.length() > i) {
c = s.charAt(i); c = s.charAt(i);
if(c == 'W') { if (c == 'W') {
nearestWeekday = true; nearestWeekday = true;
i++; i++;
} }
@@ -718,7 +708,7 @@ public final class CronExpression implements Serializable, Cloneable {
} }
protected int checkNext(int pos, String s, int val, int type) protected int checkNext(int pos, String s, int val, int type)
throws ParseException { throws ParseException {
int end = -1; int end = -1;
int i = pos; int i = pos;
@@ -732,8 +722,9 @@ public final class CronExpression implements Serializable, Cloneable {
if (c == 'L') { if (c == 'L') {
if (type == DAY_OF_WEEK) { if (type == DAY_OF_WEEK) {
if(val < 1 || val > 7) if (val < 1 || val > 7) {
throw new ParseException("Day-of-Week values must be between 1 and 7", -1); throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
}
lastdayOfWeek = true; lastdayOfWeek = true;
} else { } else {
throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i); throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
@@ -750,8 +741,9 @@ public final class CronExpression implements Serializable, Cloneable {
} else { } else {
throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i); throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
} }
if(val > 31) if (val > 31) {
throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i); throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
}
TreeSet<Integer> set = getSet(type); TreeSet<Integer> set = getSet(type);
set.add(val); set.add(val);
i++; i++;
@@ -796,7 +788,7 @@ public final class CronExpression implements Serializable, Cloneable {
end = vs.value; end = vs.value;
i = vs.pos; i = vs.pos;
} }
if (i < s.length() && ((c = s.charAt(i)) == '/')) { if (i < s.length() && ((s.charAt(i)) == '/')) {
i++; i++;
c = s.charAt(i); c = s.charAt(i);
int v2 = Integer.parseInt(String.valueOf(c)); int v2 = Integer.parseInt(String.valueOf(c));
@@ -951,21 +943,26 @@ public final class CronExpression implements Serializable, Cloneable {
} }
protected int skipWhiteSpace(int i, String s) { protected int skipWhiteSpace(int i, String s) {
for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) { /*for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) {
}*/
while (i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t')){
i++;
} }
return i; return i;
} }
protected int findNextWhiteSpace(int i, String s) { protected int findNextWhiteSpace(int i, String s) {
for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) { /*for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) {
}*/
while (i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t')){
i++;
} }
return i; return i;
} }
protected void addToSet(int val, int end, int incr, int type) protected void addToSet(int val, int end, int incr, int type)
throws ParseException { throws ParseException {
TreeSet<Integer> set = getSet(type); TreeSet<Integer> set = getSet(type);
@@ -991,12 +988,9 @@ public final class CronExpression implements Serializable, Cloneable {
throw new ParseException( throw new ParseException(
"Month values must be between 1 and 12", -1); "Month values must be between 1 and 12", -1);
} }
} else if (type == DAY_OF_WEEK) { } else if ((type == DAY_OF_WEEK) && (val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT) && (val != NO_SPEC_INT)) {
if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT) throw new ParseException(
&& (val != NO_SPEC_INT)) { "Day-of-Week values must be between 1 and 7", -1);
throw new ParseException(
"Day-of-Week values must be between 1 and 7", -1);
}
} }
if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) { if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) {
@@ -1067,14 +1061,28 @@ public final class CronExpression implements Serializable, Cloneable {
int max = -1; int max = -1;
if (stopAt < startAt) { if (stopAt < startAt) {
switch (type) { switch (type) {
case SECOND : max = 60; break; case SECOND:
case MINUTE : max = 60; break; max = 60;
case HOUR : max = 24; break; break;
case MONTH : max = 12; break; case MINUTE:
case DAY_OF_WEEK : max = 7; break; max = 60;
case DAY_OF_MONTH : max = 31; break; break;
case YEAR : throw new IllegalArgumentException("Start year must be less than stop year"); case HOUR:
default : throw new IllegalArgumentException("Unexpected type encountered"); max = 24;
break;
case MONTH:
max = 12;
break;
case DAY_OF_WEEK:
max = 7;
break;
case DAY_OF_MONTH:
max = 31;
break;
case YEAR:
throw new IllegalArgumentException("Start year must be less than stop year");
default:
throw new IllegalArgumentException("Unexpected type encountered");
} }
stopAt += max; stopAt += max;
} }
@@ -1088,7 +1096,7 @@ public final class CronExpression implements Serializable, Cloneable {
int i2 = i % max; int i2 = i % max;
// 1-indexed ranges should not include 0, and should include their max // 1-indexed ranges should not include 0, and should include their max
if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH) ) { if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH)) {
i2 = max; i2 = max;
} }
@@ -1114,7 +1122,7 @@ public final class CronExpression implements Serializable, Cloneable {
case YEAR: case YEAR:
return years; return years;
default: default:
return null; return new TreeSet<>();
} }
} }
@@ -1185,7 +1193,7 @@ public final class CronExpression implements Serializable, Cloneable {
while (!gotOne) { while (!gotOne) {
//if (endTime != null && cl.getTime().after(endTime)) return null; //if (endTime != null && cl.getTime().after(endTime)) return null;
if(cl.get(Calendar.YEAR) > 2999) { // prevent endless loop... if (cl.get(Calendar.YEAR) > 2999) { // prevent endless loop...
return null; return null;
} }
@@ -1197,7 +1205,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get second................................................. // get second.................................................
st = seconds.tailSet(sec); st = seconds.tailSet(sec);
if (st != null && st.size() != 0) { if (st != null && !st.isEmpty()) {
sec = st.first(); sec = st.first();
} else { } else {
sec = seconds.first(); sec = seconds.first();
@@ -1212,7 +1220,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get minute................................................. // get minute.................................................
st = minutes.tailSet(min); st = minutes.tailSet(min);
if (st != null && st.size() != 0) { if (st != null && !st.isEmpty()) {
t = min; t = min;
min = st.first(); min = st.first();
} else { } else {
@@ -1233,7 +1241,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get hour................................................... // get hour...................................................
st = hours.tailSet(hr); st = hours.tailSet(hr);
if (st != null && st.size() != 0) { if (st != null && !st.isEmpty()) {
t = hr; t = hr;
hr = st.first(); hr = st.first();
} else { } else {
@@ -1262,13 +1270,13 @@ public final class CronExpression implements Serializable, Cloneable {
if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule
st = daysOfMonth.tailSet(day); st = daysOfMonth.tailSet(day);
if (lastdayOfMonth) { if (lastdayOfMonth) {
if(!nearestWeekday) { if (!nearestWeekday) {
t = day; t = day;
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
day -= lastdayOffset; day -= lastdayOffset;
if(t > day) { if (t > day) {
mon++; mon++;
if(mon > 12) { if (mon > 12) {
mon = 1; mon = 1;
tmon = 3333; // ensure test of mon != tmon further below fails tmon = 3333; // ensure test of mon != tmon further below fails
cl.add(Calendar.YEAR, 1); cl.add(Calendar.YEAR, 1);
@@ -1291,13 +1299,13 @@ public final class CronExpression implements Serializable, Cloneable {
int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
int dow = tcal.get(Calendar.DAY_OF_WEEK); int dow = tcal.get(Calendar.DAY_OF_WEEK);
if(dow == Calendar.SATURDAY && day == 1) { if (dow == Calendar.SATURDAY && day == 1) {
day += 2; day += 2;
} else if(dow == Calendar.SATURDAY) { } else if (dow == Calendar.SATURDAY) {
day -= 1; day -= 1;
} else if(dow == Calendar.SUNDAY && day == ldom) { } else if (dow == Calendar.SUNDAY && day == ldom) {
day -= 2; day -= 2;
} else if(dow == Calendar.SUNDAY) { } else if (dow == Calendar.SUNDAY) {
day += 1; day += 1;
} }
@@ -1307,12 +1315,12 @@ public final class CronExpression implements Serializable, Cloneable {
tcal.set(Calendar.DAY_OF_MONTH, day); tcal.set(Calendar.DAY_OF_MONTH, day);
tcal.set(Calendar.MONTH, mon - 1); tcal.set(Calendar.MONTH, mon - 1);
Date nTime = tcal.getTime(); Date nTime = tcal.getTime();
if(nTime.before(afterTime)) { if (nTime.before(afterTime)) {
day = 1; day = 1;
mon++; mon++;
} }
} }
} else if(nearestWeekday) { } else if (nearestWeekday) {
t = day; t = day;
day = daysOfMonth.first(); day = daysOfMonth.first();
@@ -1327,13 +1335,13 @@ public final class CronExpression implements Serializable, Cloneable {
int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
int dow = tcal.get(Calendar.DAY_OF_WEEK); int dow = tcal.get(Calendar.DAY_OF_WEEK);
if(dow == Calendar.SATURDAY && day == 1) { if (dow == Calendar.SATURDAY && day == 1) {
day += 2; day += 2;
} else if(dow == Calendar.SATURDAY) { } else if (dow == Calendar.SATURDAY) {
day -= 1; day -= 1;
} else if(dow == Calendar.SUNDAY && day == ldom) { } else if (dow == Calendar.SUNDAY && day == ldom) {
day -= 2; day -= 2;
} else if(dow == Calendar.SUNDAY) { } else if (dow == Calendar.SUNDAY) {
day += 1; day += 1;
} }
@@ -1344,11 +1352,11 @@ public final class CronExpression implements Serializable, Cloneable {
tcal.set(Calendar.DAY_OF_MONTH, day); tcal.set(Calendar.DAY_OF_MONTH, day);
tcal.set(Calendar.MONTH, mon - 1); tcal.set(Calendar.MONTH, mon - 1);
Date nTime = tcal.getTime(); Date nTime = tcal.getTime();
if(nTime.before(afterTime)) { if (nTime.before(afterTime)) {
day = daysOfMonth.first(); day = daysOfMonth.first();
mon++; mon++;
} }
} else if (st != null && st.size() != 0) { } else if (st != null && !st.isEmpty()) {
t = day; t = day;
day = st.first(); day = st.first();
// make sure we don't over-run a short month, such as february // make sure we don't over-run a short month, such as february
@@ -1443,7 +1451,7 @@ public final class CronExpression implements Serializable, Cloneable {
day += daysToAdd; day += daysToAdd;
if (daysToAdd < 0 if (daysToAdd < 0
|| day > getLastDayOfMonth(mon, cl || day > getLastDayOfMonth(mon, cl
.get(Calendar.YEAR))) { .get(Calendar.YEAR))) {
cl.set(Calendar.SECOND, 0); cl.set(Calendar.SECOND, 0);
cl.set(Calendar.MINUTE, 0); cl.set(Calendar.MINUTE, 0);
cl.set(Calendar.HOUR_OF_DAY, 0); cl.set(Calendar.HOUR_OF_DAY, 0);
@@ -1465,7 +1473,7 @@ public final class CronExpression implements Serializable, Cloneable {
int dow = daysOfWeek.first(); // desired int dow = daysOfWeek.first(); // desired
// d-o-w // d-o-w
st = daysOfWeek.tailSet(cDow); st = daysOfWeek.tailSet(cDow);
if (st != null && st.size() > 0) { if (st != null && !st.isEmpty()) {
dow = st.first(); dow = st.first();
} }
@@ -1519,7 +1527,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get month................................................... // get month...................................................
st = months.tailSet(mon); st = months.tailSet(mon);
if (st != null && st.size() != 0) { if (st != null && !st.isEmpty()) {
t = mon; t = mon;
mon = st.first(); mon = st.first();
} else { } else {
@@ -1546,7 +1554,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get year................................................... // get year...................................................
st = years.tailSet(year); st = years.tailSet(year);
if (st != null && st.size() != 0) { if (st != null && !st.isEmpty()) {
t = year; t = year;
year = st.first(); year = st.first();
} else { } else {
@@ -1576,7 +1584,7 @@ public final class CronExpression implements Serializable, Cloneable {
* Advance the calendar to the particular hour paying particular attention * Advance the calendar to the particular hour paying particular attention
* to daylight saving problems. * to daylight saving problems.
* *
* @param cal the calendar to operate on * @param cal the calendar to operate on
* @param hour the hour to set * @param hour the hour to set
*/ */
protected void setCalendarHour(Calendar cal, int hour) { protected void setCalendarHour(Calendar cal, int hour) {
@@ -1643,7 +1651,7 @@ public final class CronExpression implements Serializable, Cloneable {
private void readObject(java.io.ObjectInputStream stream) private void readObject(java.io.ObjectInputStream stream)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
stream.defaultReadObject(); stream.defaultReadObject();
try { try {
@@ -1652,6 +1660,10 @@ public final class CronExpression implements Serializable, Cloneable {
} // never happens } // never happens
} }
/**
* @deprecated
* @return
*/
@Override @Override
@Deprecated @Deprecated
public Object clone() { public Object clone() {
@@ -1660,7 +1672,7 @@ public final class CronExpression implements Serializable, Cloneable {
} }
class ValueSet { class ValueSet {
public int value; int value;
public int pos; int pos;
} }
@@ -19,7 +19,7 @@ public class XxlJobGroup {
private List<String> registryList; // 执行器地址列表(系统注册) private List<String> registryList; // 执行器地址列表(系统注册)
public List<String> getRegistryList() { public List<String> getRegistryList() {
if (addressList!=null && addressList.trim().length()>0) { if (addressList!=null && addressList.trim().length()>0) {
registryList = new ArrayList<String>(Arrays.asList(addressList.split(","))); registryList = new ArrayList<>(Arrays.asList(addressList.split(",")));
} }
return registryList; return registryList;
} }
@@ -17,7 +17,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
@Override @Override
public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) { public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
StringBuffer idleBeatResultSB = new StringBuffer(); StringBuilder idleBeatResultSB = new StringBuilder();
for (String address : addressList) { for (String address : addressList) {
// beat // beat
ReturnT<String> idleBeatResult = null; ReturnT<String> idleBeatResult = null;
@@ -26,7 +26,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
idleBeatResult = executorBiz.idleBeat(new IdleBeatParam(triggerParam.getJobId())); idleBeatResult = executorBiz.idleBeat(new IdleBeatParam(triggerParam.getJobId()));
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
idleBeatResult = new ReturnT<String>(ReturnT.FAIL_CODE, ""+e ); idleBeatResult = new ReturnT<>(ReturnT.FAIL_CODE, ""+e );
} }
idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"<br><br>":"") idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"<br><br>":"")
.append(I18nUtil.getString("jobconf_idleBeat") + "") .append(I18nUtil.getString("jobconf_idleBeat") + "")
@@ -42,7 +42,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
} }
} }
return new ReturnT<String>(ReturnT.FAIL_CODE, idleBeatResultSB.toString()); return new ReturnT<>(ReturnT.FAIL_CODE, idleBeatResultSB.toString());
} }
} }
@@ -4,7 +4,7 @@ import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.biz.model.TriggerParam; import com.xxl.job.core.biz.model.TriggerParam;
import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
@@ -19,7 +19,7 @@ import java.util.TreeMap;
*/ */
public class ExecutorRouteConsistentHash extends ExecutorRouter { public class ExecutorRouteConsistentHash extends ExecutorRouter {
private static int VIRTUAL_NODE_NUM = 100; private static final int VIRTUAL_NODE_NUM = 100;
/** /**
* get hash code on 2^32 ring (md5散列的方式计算hash值) * get hash code on 2^32 ring (md5散列的方式计算hash值)
@@ -37,12 +37,7 @@ public class ExecutorRouteConsistentHash extends ExecutorRouter {
} }
md5.reset(); md5.reset();
byte[] keyBytes = null; byte[] keyBytes = null;
try { keyBytes = key.getBytes(StandardCharsets.UTF_8);
keyBytes = key.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unknown string :" + key, e);
}
md5.update(keyBytes); md5.update(keyBytes);
byte[] digest = md5.digest(); byte[] digest = md5.digest();
@@ -52,15 +47,14 @@ public class ExecutorRouteConsistentHash extends ExecutorRouter {
| ((long) (digest[1] & 0xFF) << 8) | ((long) (digest[1] & 0xFF) << 8)
| (digest[0] & 0xFF); | (digest[0] & 0xFF);
long truncateHashCode = hashCode & 0xffffffffL; return hashCode & 0xffffffffL;
return truncateHashCode;
} }
public String hashJob(int jobId, List<String> addressList) { public String hashJob(int jobId, List<String> addressList) {
// ------A1------A2-------A3------ // ------A1------A2-------A3------
// -----------J1------------------ // -----------J1------------------
TreeMap<Long, String> addressRing = new TreeMap<Long, String>(); TreeMap<Long, String> addressRing = new TreeMap<>();
for (String address: addressList) { for (String address: addressList) {
for (int i = 0; i < VIRTUAL_NODE_NUM; i++) { for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
long addressHash = hash("SHARD-" + address + "-NODE-" + i); long addressHash = hash("SHARD-" + address + "-NODE-" + i);
@@ -79,7 +73,7 @@ public class ExecutorRouteConsistentHash extends ExecutorRouter {
@Override @Override
public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) { public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
String address = hashJob(triggerParam.getJobId(), addressList); String address = hashJob(triggerParam.getJobId(), addressList);
return new ReturnT<String>(address); return new ReturnT<>(address);
} }
} }
@@ -17,7 +17,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
@Override @Override
public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) { public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
StringBuffer beatResultSB = new StringBuffer(); StringBuilder beatResultSB = new StringBuilder();
for (String address : addressList) { for (String address : addressList) {
// beat // beat
ReturnT<String> beatResult = null; ReturnT<String> beatResult = null;
@@ -26,7 +26,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
beatResult = executorBiz.beat(); beatResult = executorBiz.beat();
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
beatResult = new ReturnT<String>(ReturnT.FAIL_CODE, ""+e ); beatResult = new ReturnT<>(ReturnT.FAIL_CODE, ""+e );
} }
beatResultSB.append( (beatResultSB.length()>0)?"<br><br>":"") beatResultSB.append( (beatResultSB.length()>0)?"<br><br>":"")
.append(I18nUtil.getString("jobconf_beat") + "") .append(I18nUtil.getString("jobconf_beat") + "")
@@ -42,7 +42,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
return beatResult; return beatResult;
} }
} }
return new ReturnT<String>(ReturnT.FAIL_CODE, beatResultSB.toString()); return new ReturnT<>(ReturnT.FAIL_CODE, beatResultSB.toString());
} }
} }
@@ -13,7 +13,7 @@ public class ExecutorRouteFirst extends ExecutorRouter {
@Override @Override
public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList){ public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList){
return new ReturnT<String>(addressList.get(0)); return new ReturnT<>(addressList.get(0));
} }
} }
@@ -13,7 +13,7 @@ public class ExecutorRouteLast extends ExecutorRouter {
@Override @Override
public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) { public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
return new ReturnT<String>(addressList.get(addressList.size()-1)); return new ReturnT<>(addressList.get(addressList.size()-1));
} }
} }