All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.kagkarlsson.shaded.cronutils.model.definition.CronDefinitionBuilder Maven / Gradle / Ivy

There is a newer version: 15.0.0
Show newest version
/*
 * Copyright 2014 jmrozanec
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.kagkarlsson.shaded.cronutils.model.definition;

import com.github.kagkarlsson.shaded.cronutils.model.CronType;
import com.github.kagkarlsson.shaded.cronutils.model.field.CronFieldName;
import com.github.kagkarlsson.shaded.cronutils.model.field.definition.*;

import java.util.*;

/**
 * Builder that allows to define and create CronDefinition instances.
 */
public class CronDefinitionBuilder {
    private final Map fields = new EnumMap<>(CronFieldName.class);
    private final Set cronConstraints = new HashSet<>();
    private final Set cronNicknames = new HashSet<>();
    private boolean matchDayOfWeekAndDayOfMonth;

    /**
     * Constructor.
     */
    private CronDefinitionBuilder() {/*NOP*/}

    /**
     * Creates a builder instance.
     *
     * @return new CronDefinitionBuilder instance
     */
    public static CronDefinitionBuilder defineCron() {
        return new CronDefinitionBuilder();
    }

    /**
     * Adds definition for seconds field.
     *
     * @return new FieldDefinitionBuilder instance
     */
    public FieldDefinitionBuilder withSeconds() {
        return new FieldDefinitionBuilder(this, CronFieldName.SECOND);
    }

    /**
     * Adds definition for minutes field.
     *
     * @return new FieldDefinitionBuilder instance
     */
    public FieldDefinitionBuilder withMinutes() {
        return new FieldDefinitionBuilder(this, CronFieldName.MINUTE);
    }

    /**
     * Adds definition for hours field.
     *
     * @return new FieldDefinitionBuilder instance
     */
    public FieldDefinitionBuilder withHours() {
        return new FieldDefinitionBuilder(this, CronFieldName.HOUR);
    }

    /**
     * Adds definition for day of month field.
     *
     * @return new FieldSpecialCharsDefinitionBuilder instance
     */
    public FieldSpecialCharsDefinitionBuilder withDayOfMonth() {
        return new FieldSpecialCharsDefinitionBuilder(this, CronFieldName.DAY_OF_MONTH);
    }

    /**
     * Adds definition for month field.
     *
     * @return new FieldDefinitionBuilder instance
     */
    public FieldDefinitionBuilder withMonth() {
        return new FieldDefinitionBuilder(this, CronFieldName.MONTH);
    }

    /**
     * Adds definition for day of week field.
     *
     * @return new FieldSpecialCharsDefinitionBuilder instance
     */
    public FieldDayOfWeekDefinitionBuilder withDayOfWeek() {
        return new FieldDayOfWeekDefinitionBuilder(this, CronFieldName.DAY_OF_WEEK);
    }

    /**
     * Adds definition for year field.
     *
     * @return new FieldDefinitionBuilder instance
     */
    public FieldDefinitionBuilder withYear() {
        return new FieldDefinitionBuilder(this, CronFieldName.YEAR);
    }

    /**
     * Adds definition for day of year field.
     *
     * @return new FieldDefinitionBuilder instance
     */
    public FieldQuestionMarkDefinitionBuilder withDayOfYear() {
        return new FieldQuestionMarkDefinitionBuilder(this, CronFieldName.DAY_OF_YEAR);
    }

    /**
     * Sets matchDayOfWeekAndDayOfMonth value to true.
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder matchDayOfWeekAndDayOfMonth() {
        matchDayOfWeekAndDayOfMonth = true;
        return this;
    }

    /**
     * Supports cron nickname @yearly
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameYearly() {
        cronNicknames.add(CronNicknames.YEARLY);
        return this;
    }

    /**
     * Supports cron nickname @annually
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameAnnually() {
        cronNicknames.add(CronNicknames.ANNUALLY);
        return this;
    }

    /**
     * Supports cron nickname @monthly
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameMonthly() {
        cronNicknames.add(CronNicknames.MONTHLY);
        return this;
    }

    /**
     * Supports cron nickname @weekly
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameWeekly() {
        cronNicknames.add(CronNicknames.WEEKLY);
        return this;
    }

    /**
     * Supports cron nickname @daily
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameDaily() {
        cronNicknames.add(CronNicknames.DAILY);
        return this;
    }

    /**
     * Supports cron nickname @midnight
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameMidnight() {
        cronNicknames.add(CronNicknames.MIDNIGHT);
        return this;
    }

    /**
     * Supports cron nickname @hourly
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameHourly() {
        cronNicknames.add(CronNicknames.HOURLY);
        return this;
    }

    /**
     * Supports cron nickname @reboot
     *
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withSupportedNicknameReboot() {
        cronNicknames.add(CronNicknames.REBOOT);
        return this;
    }

    /**
     * Adds a cron validation.
     * @param validation - constraint validation
     * @return this CronDefinitionBuilder instance
     */
    public CronDefinitionBuilder withCronValidation(final CronConstraint validation) {
        cronConstraints.add(validation);
        return this;
    }

    /**
     * Registers a certain FieldDefinition.
     *
     * @param definition - FieldDefinition  instance, never null
     */
    public void register(final FieldDefinition definition) {
        //ensure that we can't register a mandatory definition if there are already optional ones
        boolean hasOptionalField = false;
        for (final FieldDefinition fieldDefinition : fields.values()) {
            if (fieldDefinition.isOptional()) {
                hasOptionalField = true;
                break;
            }
        }
        if (!definition.isOptional() && hasOptionalField) {
            throw new IllegalArgumentException("Can't register mandatory definition after a optional definition.");
        }
        fields.put(definition.getFieldName(), definition);
    }

    /**
     * Creates a new CronDefinition instance with provided field definitions.
     *
     * @return returns CronDefinition instance, never null
     */
    public CronDefinition instance() {
        final Set validations = new HashSet<>();
        validations.addAll(cronConstraints);
        final List values = new ArrayList<>(fields.values());
        values.sort(FieldDefinition.createFieldDefinitionComparator());
        return new CronDefinition(values, validations, cronNicknames, matchDayOfWeekAndDayOfMonth);
    }

    /**
     * Creates CronDefinition instance matching cron4j specification.
     *
     * @return CronDefinition instance, never null;
     */
    private static CronDefinition cron4j() {
        return CronDefinitionBuilder.defineCron()
                .withMinutes().withValidRange(0, 59).withStrictRange().and()
                .withHours().withValidRange(0, 23).withStrictRange().and()
                .withDayOfMonth().withValidRange(0, 31).supportsL().withStrictRange().and()
                .withMonth().withValidRange(1, 12).withStrictRange().and()
                .withDayOfWeek().withValidRange(0, 6).withMondayDoWValue(1).withStrictRange().and()
                .matchDayOfWeekAndDayOfMonth()
                .instance();
    }

    /**
     * Creates CronDefinition instance matching Quartz specification.
     *
     * 

The cron expression is expected to be a string comprised of 6 or 7 * fields separated by white space. Fields can contain any of the allowed * values, along with various combinations of the allowed special characters * for that field. The fields are as follows: * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Field NameMandatoryAllowed ValuesAllowed Special Characters
SecondsYES0-59* , - /
MinutesYES0-59* , - /
HoursYES0-23* , - /
Day of monthYES1-31* ? , - / L W
MonthYES1-12 or JAN-DEC* , -
Day of weekYES1-7 or SUN-SAT* ? , - / L #
YearNOempty, 1970-2099* , - /
* *

Thus in general Quartz cron expressions are as follows: * *

S M H DoM M DoW [Y] * * @return {@link CronDefinition} instance, never {@code null} */ private static CronDefinition quartz() { return CronDefinitionBuilder.defineCron() .withSeconds().withValidRange(0, 59).and() .withMinutes().withValidRange(0, 59).and() .withHours().withValidRange(0, 23).and() .withDayOfMonth().withValidRange(1, 31).supportsL().supportsW().supportsLW().supportsQuestionMark().and() .withMonth().withValidRange(1, 12).and() .withDayOfWeek().withValidRange(1, 7).withMondayDoWValue(2).supportsHash().supportsL().supportsQuestionMark().and() .withYear().withValidRange(1970, 2099).withStrictRange().optional().and() .withCronValidation(CronConstraintsFactory.ensureEitherDayOfWeekOrDayOfMonth()) .instance(); } /** * Creates CronDefinition instance matching Spring (v5.2 and below) specification. * *

The cron expression is expected to be a string comprised of 6 * fields separated by white space. Fields can contain any of the allowed * values, along with various combinations of the allowed special characters * for that field. The fields are as follows: * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Field NameMandatoryAllowed ValuesAllowed Special Characters
SecondsYES0-59* , - /
MinutesYES0-59* , - /
HoursYES0-23* , - /
Day of monthYES1-31* ? , - /
MonthYES1-12 or JAN-DEC* , -
Day of weekYES0-7 or SUN-SAT* ? , - /
* *

Thus in general Spring cron expressions are as follows (up to version 5.2): * *

S M H DoM M DoW * * @return {@link CronDefinition} instance, never {@code null} */ private static CronDefinition spring() { return CronDefinitionBuilder.defineCron() .withSeconds().withValidRange(0, 59).withStrictRange().and() .withMinutes().withValidRange(0, 59).withStrictRange().and() .withHours().withValidRange(0, 23).withStrictRange().and() .withDayOfMonth().withValidRange(1, 31).supportsQuestionMark().and() .withMonth().withValidRange(1, 12).and() .withDayOfWeek().withValidRange(0, 7).withMondayDoWValue(1).withIntMapping(7,0) .supportsHash().supportsQuestionMark().and() .instance(); } /** * Creates CronDefinition instance matching Spring (v5.2 onwards) specification. * https://spring.io/blog/2020/11/10/new-in-spring-5-3-improved-cron-expressions * *

The cron expression is expected to be a string comprised of 6 * fields separated by white space. Fields can contain any of the allowed * values, along with various combinations of the allowed special characters * for that field. The fields are as follows: * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Field NameMandatoryAllowed ValuesAllowed Special Characters
SecondsYES0-59* , - /
MinutesYES0-59* , - /
HoursYES0-23* , - /
Day of monthYES1-31* ? , - / L W
MonthYES1-12 or JAN-DEC* , -
Day of weekYES0-7 or SUN-SAT* ? , - / L #
* *

Thus in general Spring cron expressions are as follows (from version 5.3 onwards): * *

S M H DoM M DoW * * @return {@link CronDefinition} instance, never {@code null} */ private static CronDefinition spring53() { return CronDefinitionBuilder.defineCron() .withSeconds().withValidRange(0, 59).withStrictRange().and() .withMinutes().withValidRange(0, 59).withStrictRange().and() .withHours().withValidRange(0, 23).withStrictRange().and() .withDayOfMonth().withValidRange(1, 31).supportsL().supportsW().supportsLW().supportsQuestionMark().and() .withMonth().withValidRange(1, 12).and() .withDayOfWeek().withValidRange(0, 7).withMondayDoWValue(1).withIntMapping(7,0) .supportsHash().supportsL().supportsQuestionMark().and() .withSupportedNicknameYearly().withSupportedNicknameAnnually() .withSupportedNicknameMonthly() .withSupportedNicknameWeekly() .withSupportedNicknameDaily().withSupportedNicknameMidnight() .withSupportedNicknameHourly() .instance(); } /** * Creates CronDefinition instance matching unix crontab specification. * * @return CronDefinition instance, never null; */ private static CronDefinition unixCrontab() { return CronDefinitionBuilder.defineCron() .withMinutes().withValidRange(0, 59).withStrictRange().and() .withHours().withValidRange(0, 23).withStrictRange().and() .withDayOfMonth().withValidRange(1, 31).withStrictRange().and() .withMonth().withValidRange(1, 12).withStrictRange().and() .withDayOfWeek().withValidRange(0, 7).withMondayDoWValue(1).withIntMapping(7, 0).withStrictRange().and() .instance(); } /** * Creates CronDefinition instance matching cronType specification. * * @param cronType - some cron type. If null, a RuntimeException will be raised. * @return CronDefinition instance if definition is found; a RuntimeException otherwise. */ public static CronDefinition instanceDefinitionFor(final CronType cronType) { switch (cronType) { case CRON4J: return cron4j(); case QUARTZ: return quartz(); case UNIX: return unixCrontab(); case SPRING: return spring(); case SPRING53: return spring53(); default: throw new IllegalArgumentException(String.format("No cron definition found for %s", cronType)); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy