Skip to content

Commit e633f57

Browse files
committed
#520: Implement support for @reboot.
1 parent b2688e3 commit e633f57

8 files changed

Lines changed: 128 additions & 6 deletions

File tree

src/main/java/com/cronutils/builder/CronBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package com.cronutils.builder;
1515

1616
import com.cronutils.model.Cron;
17+
import com.cronutils.model.RebootCron;
1718
import com.cronutils.model.SingleCron;
1819
import com.cronutils.model.definition.CronDefinition;
1920
import com.cronutils.model.field.CronField;
@@ -210,6 +211,10 @@ public static Cron hourly(final CronDefinition definition){
210211
return builder.instance();
211212
}
212213

214+
public static Cron reboot(final CronDefinition definition){
215+
return new RebootCron(definition);
216+
}
217+
213218
@VisibleForTesting
214219
CronBuilder addField(final CronFieldName name, final FieldExpression expression) {
215220
checkState(definition != null, "CronBuilder not initialized.");
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.cronutils.model;
2+
3+
import com.cronutils.mapper.CronMapper;
4+
import com.cronutils.model.definition.CronConstraint;
5+
import com.cronutils.model.definition.CronDefinition;
6+
import com.cronutils.model.field.CronField;
7+
import com.cronutils.model.field.CronFieldName;
8+
import com.cronutils.model.field.expression.visitor.ValidationFieldExpressionVisitor;
9+
import com.cronutils.utils.Preconditions;
10+
11+
import java.util.*;
12+
13+
public class RebootCron implements Cron {
14+
private static final long serialVersionUID = 7487370826825439099L;
15+
private final CronDefinition cronDefinition;
16+
17+
/**
18+
* Creates a Cron with the given cron definition and the given fields.
19+
* @param cronDefinition the definition to use for this Cron
20+
*/
21+
public RebootCron(final CronDefinition cronDefinition) {
22+
this.cronDefinition = Preconditions.checkNotNull(cronDefinition, "CronDefinition must not be null");
23+
}
24+
25+
/**
26+
* Retrieve value for cron field.
27+
*
28+
* @param name - cron field name.
29+
* If null, a NullPointerException will be raised.
30+
* @return CronField that corresponds to given CronFieldName
31+
*/
32+
public CronField retrieve(final CronFieldName name) {
33+
Preconditions.checkNotNull(name, "CronFieldName must not be null");
34+
return null;
35+
}
36+
37+
/**
38+
* Retrieve all cron field values as map.
39+
*
40+
* @return unmodifiable Map with key CronFieldName and values CronField, never null
41+
*/
42+
public Map<CronFieldName, CronField> retrieveFieldsAsMap() {
43+
return Collections.unmodifiableMap(new HashMap<>());
44+
}
45+
46+
public String asString() {
47+
return "@reboot";
48+
}
49+
50+
public CronDefinition getCronDefinition() {
51+
return cronDefinition;
52+
}
53+
54+
/**
55+
* Validates this Cron instance by validating its cron expression.
56+
*
57+
* @return this Cron instance
58+
* @throws IllegalArgumentException if the cron expression is invalid
59+
*/
60+
public Cron validate() {
61+
for (final Map.Entry<CronFieldName, CronField> field : retrieveFieldsAsMap().entrySet()) {
62+
final CronFieldName fieldName = field.getKey();
63+
field.getValue().getExpression().accept(
64+
new ValidationFieldExpressionVisitor(getCronDefinition().getFieldDefinition(fieldName).getConstraints())
65+
);
66+
}
67+
for (final CronConstraint constraint : getCronDefinition().getCronConstraints()) {
68+
if (!constraint.validate(this)) {
69+
throw new IllegalArgumentException(String.format("Invalid cron expression: %s. %s", asString(), constraint.getDescription()));
70+
}
71+
}
72+
return this;
73+
}
74+
75+
/**
76+
* Provides means to compare if two cron expressions are equivalent.
77+
*
78+
* @param cronMapper - maps 'cron' parameter to this instance definition;
79+
* @param cron - any cron instance, never null
80+
* @return boolean - true if equivalent; false otherwise.
81+
*/
82+
public boolean equivalent(final CronMapper cronMapper, final Cron cron) {
83+
return asString().equals(cronMapper.map(cron).asString());
84+
}
85+
86+
/**
87+
* Provides means to compare if two cron expressions are equivalent.
88+
* Assumes same cron definition.
89+
*
90+
* @param cron - any cron instance, never null
91+
* @return boolean - true if equivalent; false otherwise.
92+
*/
93+
public boolean equivalent(final Cron cron) {
94+
return asString().equals(cron.asString());
95+
}
96+
}

src/main/java/com/cronutils/model/SingleCron.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class SingleCron implements Cron {
1717
private String asString;
1818

1919
/**
20-
* Creates a Cron with the iven cron definition and the given fields.
20+
* Creates a Cron with the given cron definition and the given fields.
2121
* @param cronDefinition the definition to use for this Cron
2222
* @param fields the fields that should be used
2323
*/

src/main/java/com/cronutils/model/definition/CronDefinition.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ public class CronDefinition implements Serializable {
4040
* Throws an IllegalArgumentException if an empty list is received
4141
*/
4242
public CronDefinition(final List<FieldDefinition> fieldDefinitions, final Set<CronConstraint> cronConstraints, Set<CronNicknames> cronNicknames, final boolean matchDayOfWeekAndDayOfMonth) {
43-
Preconditions.checkNotNull(fieldDefinitions, "Field definitions must not be null");
44-
Preconditions.checkNotNull(cronConstraints, "Cron validations must not be null");
4543
Preconditions.checkNotNull(cronNicknames, "Cron nicknames must not be null");
46-
Preconditions.checkNotNullNorEmpty(fieldDefinitions, "Field definitions must not be empty");
47-
Preconditions.checkArgument(!fieldDefinitions.get(0).isOptional(), "The first field must not be optional");
44+
if(!cronNicknames.contains(CronNicknames.REBOOT)){
45+
Preconditions.checkNotNull(fieldDefinitions, "Field definitions must not be null");
46+
Preconditions.checkNotNull(cronConstraints, "Cron validations must not be null");
47+
Preconditions.checkNotNullNorEmpty(fieldDefinitions, "Field definitions must not be empty");
48+
Preconditions.checkArgument(!fieldDefinitions.get(0).isOptional(), "The first field must not be optional");
49+
}
4850
this.fieldDefinitions = new EnumMap<>(CronFieldName.class);
4951
for (final FieldDefinition field : fieldDefinitions) {
5052
this.fieldDefinitions.put(field.getFieldName(), field);

src/main/java/com/cronutils/model/definition/CronDefinitionBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ public CronDefinitionBuilder withSupportedNicknameHourly() {
194194
return this;
195195
}
196196

197+
/**
198+
* Supports cron nickname @reboot
199+
*
200+
* @return this CronDefinitionBuilder instance
201+
*/
202+
public CronDefinitionBuilder withSupportedNicknameReboot() {
203+
cronNicknames.add(CronNicknames.REBOOT);
204+
return this;
205+
}
206+
197207
/**
198208
* Adds a cron validation.
199209
* @param validation - constraint validation
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.cronutils.model.definition;
22

33
public enum CronNicknames {
4-
YEARLY, ANNUALLY, MONTHLY, WEEKLY, DAILY, MIDNIGHT, HOURLY;
4+
YEARLY, ANNUALLY, MONTHLY, WEEKLY, DAILY, MIDNIGHT, HOURLY, REBOOT;
55
}

src/main/java/com/cronutils/parser/CronParser.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ public Cron parse(final String expression) {
118118
return validateAndReturnSupportedCronNickname(expression, cronNicknames, CronNicknames.MIDNIGHT, CronBuilder.midnight(cronDefinition));
119119
case "@hourly":
120120
return validateAndReturnSupportedCronNickname(expression, cronNicknames, CronNicknames.HOURLY, CronBuilder.hourly(cronDefinition));
121+
case "@reboot":
122+
return validateAndReturnSupportedCronNickname(expression, cronNicknames, CronNicknames.REBOOT, CronBuilder.reboot(cronDefinition));
121123
}
122124
}
123125

src/test/java/com/cronutils/model/definition/CronDefinitionBuilderTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,4 +416,11 @@ public void testSpring53ScheduleHourly(){
416416
CronParser parser = new CronParser(cronDefinition);
417417
parser.parse("@hourly");
418418
}
419+
420+
@Test
421+
public void testScheduleReboot(){
422+
CronDefinition cronDefinition = builder.withSupportedNicknameReboot().instance();
423+
CronParser parser = new CronParser(cronDefinition);
424+
parser.parse("@reboot");
425+
}
419426
}

0 commit comments

Comments
 (0)