1 package org.apache.fulcrum.intake.validator;
2
3 import java.text.NumberFormat;
4 import java.text.ParseException;
5 import java.text.ParsePosition;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import java.util.Locale;
27 import java.util.Map;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.fulcrum.intake.model.Field;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public abstract class NumberValidator<T extends Number>
53 extends DefaultValidator<T>
54 {
55
56 String minValueMessage = null;
57
58
59 String maxValueMessage = null;
60
61
62 String invalidNumberMessage = null;
63
64 private T minValue = null;
65 private T maxValue = null;
66
67
68
69
70 public NumberValidator()
71 {
72 super();
73 }
74
75
76
77
78
79
80
81
82
83 @Override
84 public void init(Map<String, ? extends Constraint> paramMap)
85 throws InvalidMaskException
86 {
87 super.init(paramMap);
88
89 Constraint constraint = paramMap.get(INVALID_NUMBER_RULE_NAME);
90
91 if (constraint != null)
92 {
93 invalidNumberMessage = constraint.getMessage();
94 }
95
96 constraint = paramMap.get(MIN_VALUE_RULE_NAME);
97 if (constraint != null)
98 {
99 String param = constraint.getValue();
100 try
101 {
102 minValue = parseNumber(param, Locale.US);
103 }
104 catch (NumberFormatException e)
105 {
106 throw new InvalidMaskException("Could not parse minimum value " + param, e);
107 }
108 minValueMessage = constraint.getMessage();
109 }
110
111 constraint = paramMap.get(MAX_VALUE_RULE_NAME);
112 if (constraint != null)
113 {
114 String param = constraint.getValue();
115 try
116 {
117 maxValue = parseNumber(param, Locale.US);
118 }
119 catch (NumberFormatException e)
120 {
121 throw new InvalidMaskException("Could not parse minimum value " + param, e);
122 }
123 maxValueMessage = constraint.getMessage();
124 }
125 }
126
127
128
129
130
131
132
133
134
135
136
137 protected abstract T parseNumber(String stringValue, Locale locale) throws NumberFormatException;
138
139
140
141
142
143
144
145
146
147
148
149 protected Number parseIntoNumber(String stringValue, Locale locale) throws NumberFormatException
150 {
151 NumberFormat nf = NumberFormat.getInstance(locale);
152
153 try
154 {
155 ParsePosition pos = new ParsePosition(0);
156 Number number = nf.parse(stringValue, pos);
157
158 if (pos.getIndex() != stringValue.length())
159 {
160 throw new ParseException("Could not parse string completely", pos.getErrorIndex());
161 }
162
163 return number;
164 }
165 catch (ParseException e)
166 {
167 throw new NumberFormatException(e.getMessage());
168 }
169 }
170
171
172
173
174
175
176
177
178
179 @Override
180 public void assertValidity(Field<T> field) throws ValidationException
181 {
182 Locale locale = field.getLocale();
183
184 if (field.isMultiValued())
185 {
186 String[] stringValues = (String[])field.getTestValue();
187
188 for (int i = 0; i < stringValues.length; i++)
189 {
190 assertValidity(stringValues[i], locale);
191 }
192 }
193 else
194 {
195 assertValidity((String)field.getTestValue(), locale);
196 }
197 }
198
199
200
201
202
203
204
205
206
207
208 public void assertValidity(String testValue, Locale locale) throws ValidationException
209 {
210 super.assertValidity(testValue);
211
212 if (required || StringUtils.isNotEmpty(testValue))
213 {
214 T number = null;
215 try
216 {
217 number = parseNumber(testValue, locale);
218 }
219 catch (NumberFormatException e)
220 {
221 errorMessage = invalidNumberMessage;
222 throw new ValidationException(invalidNumberMessage);
223 }
224
225 if (minValue != null && number.doubleValue() < minValue.doubleValue())
226 {
227 errorMessage = minValueMessage;
228 throw new ValidationException(minValueMessage);
229 }
230 if (maxValue != null && number.doubleValue() > maxValue.doubleValue())
231 {
232 errorMessage = maxValueMessage;
233 throw new ValidationException(maxValueMessage);
234 }
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247 public String getMinValueMessage()
248 {
249 return minValueMessage;
250 }
251
252
253
254
255
256
257 public void setMinValueMessage(String minValueMessage)
258 {
259 this.minValueMessage = minValueMessage;
260 }
261
262
263
264
265
266
267 public String getMaxValueMessage()
268 {
269 return maxValueMessage;
270 }
271
272
273
274
275
276
277 public void setMaxValueMessage(String maxValueMessage)
278 {
279 this.maxValueMessage = maxValueMessage;
280 }
281
282
283
284
285
286
287 public String getInvalidNumberMessage()
288 {
289 return invalidNumberMessage;
290 }
291
292
293
294
295
296
297 public void setInvalidNumberMessage(String invalidNumberMessage)
298 {
299 this.invalidNumberMessage = invalidNumberMessage;
300 }
301
302
303
304
305
306
307 public T getMinValue()
308 {
309 return minValue;
310 }
311
312
313
314
315
316
317 public void setMinValue(T minValue)
318 {
319 this.minValue = minValue;
320 }
321
322
323
324
325
326
327 public T getMaxValue()
328 {
329 return maxValue;
330 }
331
332
333
334
335
336
337 public void setMaxValue(T maxValue)
338 {
339 this.maxValue = maxValue;
340 }
341 }