forked from jmrozanec/cron-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EveryFieldValueGenerator.java
145 lines (124 loc) · 4.98 KB
/
EveryFieldValueGenerator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Copyright 2015 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.cronutils.model.time.generator;
import com.cronutils.model.field.CronField;
import com.cronutils.model.field.expression.Between;
import com.cronutils.model.field.expression.Every;
import com.cronutils.model.field.expression.FieldExpression;
import com.cronutils.model.field.expression.On;
import com.cronutils.utils.VisibleForTesting;
import java.util.ArrayList;
import java.util.List;
class EveryFieldValueGenerator extends FieldValueGenerator {
protected final int from;
protected final int to;
public EveryFieldValueGenerator(final CronField cronField) {
super(cronField);
final Every every = (Every) cronField.getExpression();
final FieldExpression everyExpression = every.getExpression();
if (everyExpression instanceof Between) {
final Between between = (Between) everyExpression;
from = Math.max(cronField.getConstraints().getStartRange(), BetweenFieldValueGenerator.map(between.getFrom()));
to = Math.min(cronField.getConstraints().getEndRange(), BetweenFieldValueGenerator.map(between.getTo()));
} else if(everyExpression instanceof On){
final On on = (On) everyExpression;
from = on.getTime().getValue();
to = cronField.getConstraints().getEndRange();
} else {
from = cronField.getConstraints().getStartRange();
to = cronField.getConstraints().getEndRange();
}
}
@Override
public int generateNextValue(final int reference) throws NoSuchValueException {
//intuition: for valid values, we have: offset+period*i
if (reference >= to) {
throw new NoSuchValueException();
}
final Every every = (Every) cronField.getExpression();
final int next = getNext(reference, every);
if (next < from) {
return from;
}
if (next > to) {
throw new NoSuchValueException();
}
return next;
}
private int getNext(int reference, Every every) {
final int offset = offset();
if (reference >= offset) {
final int referenceWithoutOffset = reference - offset;
final int period = every.getPeriod().getValue();
final int remainder = referenceWithoutOffset % period;
return reference + (period - remainder);
} else {
return offset;
}
}
@Override
public int generatePreviousValue(final int reference) throws NoSuchValueException {
final Every every = (Every) cronField.getExpression();
if (reference < from) {
throw new NoSuchValueException();
}
if (reference > to) {
return to;
}
final int period = every.getPeriod().getValue();
final int remainder = (reference - from) % period;
if (remainder == 0) {
return reference - period;
} else {
return reference - remainder;
}
}
@Override
protected List<Integer> generateCandidatesNotIncludingIntervalExtremes(final int start, final int end) {
final List<Integer> values = new ArrayList<>();
try {
final int offset = offset();
if (start < offset && offset < end) {
values.add(offset);
}
int reference = generateNextValue(start);
while (reference < end) {
if (reference != offset) {
values.add(reference);
}
reference = generateNextValue(reference);
}
} catch (final NoSuchValueException ignored) {
// We just skip, since we generate values until we get the exception
}
return values;
}
@Override
public boolean isMatch(final int value) {
final Every every = (Every) cronField.getExpression();
final int start = offset();
return value >= start && ((value - start) % every.getPeriod().getValue()) == 0 && value >= from && value <= to;
}
@Override
protected boolean matchesFieldExpressionClass(final FieldExpression fieldExpression) {
return fieldExpression instanceof Every;
}
@VisibleForTesting
int offset() {
final FieldExpression expression = ((Every) cronField.getExpression()).getExpression();
if (expression instanceof On) {
return ((On) expression).getTime().getValue();
}
return from;
}
}