cronexpression.java

来自「Quartz 是个开源的作业调度框架」· Java 代码 · 共 1,388 行 · 第 1/4 页

JAVA
1,388
字号
            if (seconds == null) seconds = new TreeSet();
            if (minutes == null) minutes = new TreeSet();
            if (hours == null) hours = new TreeSet();
            if (daysOfMonth == null) daysOfMonth = new TreeSet();
            if (months == null) months = new TreeSet();
            if (daysOfWeek == null) daysOfWeek = new TreeSet();
            if (years == null) years = new TreeSet();

            int exprOn = SECOND;

            StringTokenizer exprsTok = new StringTokenizer(expression, " \t",
                    false);

            while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {
                String expr = exprsTok.nextToken().trim();
                StringTokenizer vTok = new StringTokenizer(expr, ",");
                while (vTok.hasMoreTokens()) {
                    String v = vTok.nextToken();
                    storeExpressionVals(0, v, exprOn);
                }

                exprOn++;
            }

            if (exprOn <= DAY_OF_WEEK)
                    throw new ParseException("Unexpected end of expression.",
                            expression.length());

            if (exprOn <= YEAR) storeExpressionVals(0, "*", YEAR);

        } catch (ParseException pe) {
            throw pe;
        } catch (Exception e) {
            throw new ParseException("Illegal cron expression format ("
                    + e.toString() + ")", 0);
        }
    }

    protected int storeExpressionVals(int pos, String s, int type)
            throws ParseException {
        int incr = 0;
        int i = skipWhiteSpace(pos, s);
        if (i >= s.length()) return i;
        char c = s.charAt(i);
        if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW"))) {
            String sub = s.substring(i, i + 3);
            int sval = -1;
            int eval = -1;
            if (type == MONTH) {
                sval = getMonthNumber(sub) + 1;
                if (sval < 0)
                        throw new ParseException("Invalid Month value: '" + sub
                                + "'", i);
                if (s.length() > i + 3) {
                    c = s.charAt(i + 3);
                    if (c == '-') {
                        i += 4;
                        sub = s.substring(i, i + 3);
                        eval = getMonthNumber(sub) + 1;
                        if (eval < 0)
                                throw new ParseException(
                                        "Invalid Month value: '" + sub + "'", i);
                    }
                }
            } else if (type == DAY_OF_WEEK) {
                sval = getDayOfWeekNumber(sub);
                if (sval < 0)
                        throw new ParseException("Invalid Day-of-Week value: '"
                                + sub + "'", i);
                if (s.length() > i + 3) {
                    c = s.charAt(i + 3);
                    if (c == '-') {
                        i += 4;
                        sub = s.substring(i, i + 3);
                        eval = getDayOfWeekNumber(sub);
                        if (eval < 0)
                            throw new ParseException(
                                    "Invalid Day-of-Week value: '" + sub
                                        + "'", i);
                        if (sval > eval)
                            throw new ParseException(
                                    "Invalid Day-of-Week sequence: " + sval 
                                        + " > " + eval, i);
                        
                    } else if (c == '#') {
                        try {
                            i += 4;
                            nthdayOfWeek = Integer.parseInt(s.substring(i));
                            if (nthdayOfWeek < 1 || nthdayOfWeek > 5)
                                    throw new Exception();
                        } catch (Exception e) {
                            throw new ParseException(
                                    "A numeric value between 1 and 5 must follow the '#' option",
                                    i);
                        }
                    } else if (c == 'L') {
                        lastdayOfWeek = true;
                        i++;
                    }
                }

            } else {
                throw new ParseException(
                        "Illegal characters for this position: '" + sub + "'",
                        i);
            }
            if (eval != -1) incr = 1;
            addToSet(sval, eval, incr, type);
            return (i + 3);
        }

        if (c == '?') {
            i++;
            if ((i + 1) < s.length()
                    && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t'))
                    throw new ParseException("Illegal character after '?': "
                            + s.charAt(i), i);
            if (type != DAY_OF_WEEK && type != DAY_OF_MONTH)
                    throw new ParseException(
                            "'?' can only be specfied for Day-of-Month or Day-of-Week.",
                            i);
            if (type == DAY_OF_WEEK && !lastdayOfMonth) {
                int val = ((Integer) daysOfMonth.last()).intValue();
                if (val == NO_SPEC_INT)
                        throw new ParseException(
                                "'?' can only be specfied for Day-of-Month -OR- Day-of-Week.",
                                i);
            }

            addToSet(NO_SPEC_INT, -1, 0, type);
            return i;
        }

        if (c == '*' || c == '/') {
            if (c == '*' && (i + 1) >= s.length()) {
                addToSet(ALL_SPEC_INT, -1, incr, type);
                return i + 1;
            } else if (c == '/'
                    && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s
                            .charAt(i + 1) == '\t')) throw new ParseException(
                    "'/' must be followed by an integer.", i);
            else if (c == '*') i++;
            c = s.charAt(i);
            if (c == '/') { // is an increment specified?
                i++;
                if (i >= s.length())
                        throw new ParseException("Unexpected end of string.", i);

                incr = getNumericValue(s, i);

                i++;
                if (incr > 10) i++;
                if (incr > 59 && (type == SECOND || type == MINUTE)) throw new ParseException(
                        "Increment > 60 : " + incr, i);
                else if (incr > 23 && (type == HOUR)) throw new ParseException(
                        "Increment > 24 : " + incr, i);
                else if (incr > 31 && (type == DAY_OF_MONTH)) throw new ParseException(
                        "Increment > 31 : " + incr, i);
                else if (incr > 7 && (type == DAY_OF_WEEK)) throw new ParseException(
                        "Increment > 7 : " + incr, i);
                else if (incr > 12 && (type == MONTH))
                        throw new ParseException("Increment > 12 : " + incr, i);
            } else
                incr = 1;

            addToSet(ALL_SPEC_INT, -1, incr, type);
            return i;
        } else if (c == 'L') {
            i++;
            if (type == DAY_OF_MONTH) lastdayOfMonth = true;
            if (type == DAY_OF_WEEK) addToSet(7, 7, 0, type);
            if(type == DAY_OF_MONTH && s.length() > i) {
                c = s.charAt(i);
                if(c == 'W') {
                    nearestWeekday = true;
                    i++;
                }
            }
            return i;
        } else if (c >= '0' && c <= '9') {
            int val = Integer.parseInt(String.valueOf(c));
            i++;
            if (i >= s.length()) addToSet(val, -1, -1, type);
            else {
                c = s.charAt(i);
                if (c >= '0' && c <= '9') {
                    ValueSet vs = getValue(val, s, i);
                    val = vs.value;
                    i = vs.pos;
                }
                i = checkNext(i, s, val, type);
                return i;
            }
        } else
            throw new ParseException("Unexpected character: " + c, i);

        return i;
    }

    protected int checkNext(int pos, String s, int val, int type)
            throws ParseException {
        int end = -1;
        int i = pos;

        if (i >= s.length()) {
            addToSet(val, end, -1, type);
            return i;
        }

        char c = s.charAt(pos);

        if (c == 'L') {
            if (type == DAY_OF_WEEK) lastdayOfWeek = true;
            else
                throw new ParseException("'L' option is not valid here. (pos="
                        + i + ")", i);
            TreeSet set = getSet(type);
            set.add(new Integer(val));
            i++;
            return i;
        }
        
        if (c == 'W') {
            if(type == DAY_OF_MONTH) nearestWeekday = true;
            else
                throw new ParseException("'W' option is not valid here. (pos="
                        + i + ")", i);
            TreeSet set = getSet(type);
            set.add(new Integer(val));
            i++;
            return i;
        }

        if (c == '#') {
            if (type != DAY_OF_WEEK)
                    throw new ParseException(
                            "'#' option is not valid here. (pos=" + i + ")", i);
            i++;
            try {
                nthdayOfWeek = Integer.parseInt(s.substring(i));
                if (nthdayOfWeek < 1 || nthdayOfWeek > 5)
                        throw new Exception();
            } catch (Exception e) {
                throw new ParseException(
                        "A numeric value between 1 and 5 must follow the '#' option",
                        i);
            }

            TreeSet set = getSet(type);
            set.add(new Integer(val));
            i++;
            return i;
        }

        if (c == 'C') {
            if (type == DAY_OF_WEEK) calendardayOfWeek = true;
            else if (type == DAY_OF_MONTH) calendardayOfMonth = true;
            else
                throw new ParseException("'C' option is not valid here. (pos="
                        + i + ")", i);
            TreeSet set = getSet(type);
            set.add(new Integer(val));
            i++;
            return i;
        }

        if (c == '-') {
            i++;
            c = s.charAt(i);
            int v = Integer.parseInt(String.valueOf(c));
            end = v;
            i++;
            if (i >= s.length()) {
                addToSet(val, end, 1, type);
                return i;
            }
            c = s.charAt(i);
            if (c >= '0' && c <= '9') {
                ValueSet vs = getValue(v, s, i);
                int v1 = vs.value;
                end = v1;
                i = vs.pos;
            }
            if (i < s.length() && ((c = s.charAt(i)) == '/')) {
                i++;
                c = s.charAt(i);
                int v2 = Integer.parseInt(String.valueOf(c));
                i++;
                if (i >= s.length()) {
                    addToSet(val, end, v2, type);
                    return i;
                }
                c = s.charAt(i);
                if (c >= '0' && c <= '9') {
                    ValueSet vs = getValue(v2, s, i);
                    int v3 = vs.value;
                    addToSet(val, end, v3, type);
                    i = vs.pos;
                    return i;
                } else {
                    addToSet(val, end, v2, type);
                    return i;
                }
            } else {
                addToSet(val, end, 1, type);
                return i;
            }
        }

        if (c == '/') {
            i++;
            c = s.charAt(i);
            int v2 = Integer.parseInt(String.valueOf(c));
            i++;
            if (i >= s.length()) {
                addToSet(val, end, v2, type);
                return i;
            }
            c = s.charAt(i);
            if (c >= '0' && c <= '9') {
                ValueSet vs = getValue(v2, s, i);
                int v3 = vs.value;
                addToSet(val, end, v3, type);
                i = vs.pos;
                return i;
            } else
                throw new ParseException("Unexpected character '" + c
                        + "' after '/'", i);
        }

        addToSet(val, end, 0, type);
        i++;
        return i;
    }

    public String getCronExpression() {
    	return cronExpression;
    }
    
    public String getExpressionSummary() {
        StringBuffer buf = new StringBuffer();

        buf.append("seconds: ");
        buf.append(getExpressionSetSummary(seconds));
        buf.append("\n");
        buf.append("minutes: ");
        buf.append(getExpressionSetSummary(minutes));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?