forked from wildfly/wildfly
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IntegerBasedExpression.java
220 lines (192 loc) · 7.97 KB
/
IntegerBasedExpression.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.ejb3.timerservice.schedule.attribute;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.jboss.as.ejb3.logging.EjbLogger;
import org.jboss.as.ejb3.timerservice.schedule.value.IncrementValue;
import org.jboss.as.ejb3.timerservice.schedule.value.ListValue;
import org.jboss.as.ejb3.timerservice.schedule.value.RangeValue;
import org.jboss.as.ejb3.timerservice.schedule.value.ScheduleExpressionType;
import org.jboss.as.ejb3.timerservice.schedule.value.ScheduleValue;
import org.jboss.as.ejb3.timerservice.schedule.value.SingleValue;
/**
* Represents a {@link Integer} type value in a {@link javax.ejb.ScheduleExpression}.
* <p/>
* <p>
* Examples for {@link IntegerBasedExpression} are the value of seconds, years, months etc...
* which allow {@link Integer}.
* </p>
*
* @author Jaikiran Pai
* @version $Revision: $
*/
public abstract class IntegerBasedExpression {
protected abstract Integer getMaxValue();
protected abstract Integer getMinValue();
protected abstract boolean accepts(ScheduleExpressionType scheduleExprType);
protected final SortedSet<Integer> absoluteValues = new TreeSet<Integer>();
protected final Set<ScheduleValue> relativeValues = new HashSet<ScheduleValue>();
protected final ScheduleExpressionType scheduleExpressionType;
protected final String origValue;
public IntegerBasedExpression(String value) {
this.origValue = value;
// check the type of value
this.scheduleExpressionType = ScheduleExpressionType.getType(value);
if (!this.accepts(scheduleExpressionType)) {
throw EjbLogger.EJB3_TIMER_LOGGER.invalidScheduleExpressionType(value, this.getClass().getName(), this.scheduleExpressionType.toString());
}
switch (this.scheduleExpressionType) {
case RANGE:
RangeValue range = new RangeValue(value);
// process the range value
this.processRangeValue(range);
break;
case LIST:
ListValue list = new ListValue(value);
// process the list value
this.processListValue(list);
break;
case INCREMENT:
IncrementValue incrValue = new IncrementValue(value);
// process the increment value
this.processIncrement(incrValue);
break;
case SINGLE_VALUE:
SingleValue singleValue = new SingleValue(value);
// process the single value
this.processSingleValue(singleValue);
break;
case WILDCARD:
// a wildcard is equivalent to "all possible" values, so
// do nothing
break;
default:
throw EjbLogger.EJB3_TIMER_LOGGER.invalidValueForSecondInScheduleExpression(value);
}
}
protected void processListValue(ListValue list) {
for (String listItem : list.getValues()) {
this.processListItem(listItem);
}
}
protected void processListItem(String listItem) {
// check what type of a value the list item is.
// Each item in the list must be an individual attribute value or a range.
// List items can not themselves be lists, wild-cards, or increments.
ScheduleExpressionType listItemType = ScheduleExpressionType.getType(listItem);
switch (listItemType) {
case SINGLE_VALUE:
SingleValue singleVal = new SingleValue(listItem);
this.processSingleValue(singleVal);
return;
case RANGE:
RangeValue range = new RangeValue(listItem);
this.processRangeValue(range);
return;
default:
throw EjbLogger.EJB3_TIMER_LOGGER.invalidListValue(listItem);
}
}
protected void processRangeValue(RangeValue range) {
String start = range.getStart();
String end = range.getEnd();
if (this.isRelativeValue(start) || this.isRelativeValue(end)) {
this.relativeValues.add(range);
return;
}
Integer rangeStart = this.parseInt(start);
Integer rangeEnd = this.parseInt(end);
// validations
this.assertValid(rangeStart);
this.assertValid(rangeEnd);
// start and end are both the same. So it's just a single value
if (rangeStart.equals(rangeEnd)) {
this.absoluteValues.add(rangeStart);
return;
}
if (rangeStart > rangeEnd) {
// In range "x-y", if x is larger than y, the range is equivalent to
// "x-max, min-y", where max is the largest value of the corresponding attribute
// and min is the smallest.
for (int i = rangeStart; i <= this.getMaxValue(); i++) {
this.absoluteValues.add(i);
}
for (int i = this.getMinValue(); i <= rangeEnd; i++) {
this.absoluteValues.add(i);
}
} else {
// just keep adding from range start to range end (both inclusive).
for (int i = rangeStart; i <= rangeEnd; i++) {
this.absoluteValues.add(i);
}
}
}
protected void processIncrement(IncrementValue incr) {
String startValue = incr.getStart();
Integer start = startValue.equals("*") ? 0 : this.parseInt(startValue);
// make sure it's a valid value
this.assertValid(start);
Integer interval = this.parseInt(incr.getInterval());
this.absoluteValues.add(start);
int next = start + interval;
int maxValue = this.getMaxValue();
while (next <= maxValue) {
this.absoluteValues.add(next);
next = next + interval;
}
}
protected void processSingleValue(SingleValue singleValue) {
String value = singleValue.getValue();
if (this.isRelativeValue(value)) {
this.relativeValues.add(singleValue);
} else {
Integer val = this.parseInt(value);
this.assertValid(val);
this.absoluteValues.add(val);
}
}
protected Integer parseInt(String alias) {
if (alias == null) {
return null;
}
return Integer.parseInt(alias.trim());
}
protected void assertValid(Integer value) throws IllegalArgumentException {
if (value == null) {
throw EjbLogger.EJB3_TIMER_LOGGER.invalidScheduleValue("", this.origValue);
}
int max = this.getMaxValue();
int min = this.getMinValue();
if (value > max || value < min) {
throw EjbLogger.EJB3_TIMER_LOGGER.invalidValuesRange(value, min, max);
}
}
/**
* Checks if relative value is supported.
* @param value non-null value
* @return true if relative value is supported
*/
public abstract boolean isRelativeValue(String value);
}