1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.commons.validator;
22
23 import java.io.Serializable;
24 import java.util.Date;
25 import java.util.Locale;
26 import java.text.DateFormat;
27 import java.text.SimpleDateFormat;
28 import java.text.NumberFormat;
29 import java.text.ParseException;
30 import java.text.ParsePosition;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 /***
35 * This class contains basic methods for performing validations that return the
36 * correctly typed class based on the validation performed.
37 */
38 public class GenericTypeValidator implements Serializable {
39
40 private final static Log log = LogFactory.getLog(GenericTypeValidator.class);
41
42 /***
43 * Checks if the value can safely be converted to a byte primitive.
44 *
45 *@param value The value validation is being performed on.
46 *@return the converted Byte value.
47 */
48 public static Byte formatByte(String value) {
49 if (value == null) {
50 return null;
51 }
52
53 try {
54 return new Byte(value);
55 } catch (NumberFormatException e) {
56 return null;
57 }
58
59 }
60
61 /***
62 * Checks if the value can safely be converted to a byte primitive.
63 *
64 *@param value The value validation is being performed on.
65 *@param locale The locale to use to parse the number (system default if
66 * null)
67 *@return the converted Byte value.
68 */
69 public static Byte formatByte(String value, Locale locale) {
70 Byte result = null;
71
72 if (value != null) {
73 NumberFormat formatter = null;
74 if (locale != null) {
75 formatter = NumberFormat.getNumberInstance(locale);
76 } else {
77 formatter = NumberFormat.getNumberInstance(Locale.getDefault());
78 }
79 formatter.setParseIntegerOnly(true);
80 ParsePosition pos = new ParsePosition(0);
81 Number num = formatter.parse(value, pos);
82
83
84 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) {
85 if (num.doubleValue() >= Byte.MIN_VALUE &&
86 num.doubleValue() <= Byte.MAX_VALUE) {
87 result = new Byte(num.byteValue());
88 }
89 }
90 }
91
92 return result;
93 }
94
95 /***
96 * Checks if the value can safely be converted to a short primitive.
97 *
98 *@param value The value validation is being performed on.
99 *@return the converted Short value.
100 */
101 public static Short formatShort(String value) {
102 if (value == null) {
103 return null;
104 }
105
106 try {
107 return new Short(value);
108 } catch (NumberFormatException e) {
109 return null;
110 }
111
112 }
113
114 /***
115 * Checks if the value can safely be converted to a short primitive.
116 *
117 *@param value The value validation is being performed on.
118 *@param locale The locale to use to parse the number (system default if
119 * null)vv
120 *@return the converted Short value.
121 */
122 public static Short formatShort(String value, Locale locale) {
123 Short result = null;
124
125 if (value != null) {
126 NumberFormat formatter = null;
127 if (locale != null) {
128 formatter = NumberFormat.getNumberInstance(locale);
129 } else {
130 formatter = NumberFormat.getNumberInstance(Locale.getDefault());
131 }
132 formatter.setParseIntegerOnly(true);
133 ParsePosition pos = new ParsePosition(0);
134 Number num = formatter.parse(value, pos);
135
136
137 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) {
138 if (num.doubleValue() >= Short.MIN_VALUE &&
139 num.doubleValue() <= Short.MAX_VALUE) {
140 result = new Short(num.shortValue());
141 }
142 }
143 }
144
145 return result;
146 }
147
148 /***
149 * Checks if the value can safely be converted to a int primitive.
150 *
151 *@param value The value validation is being performed on.
152 *@return the converted Integer value.
153 */
154 public static Integer formatInt(String value) {
155 if (value == null) {
156 return null;
157 }
158
159 try {
160 return new Integer(value);
161 } catch (NumberFormatException e) {
162 return null;
163 }
164
165 }
166
167 /***
168 * Checks if the value can safely be converted to an int primitive.
169 *
170 *@param value The value validation is being performed on.
171 *@param locale The locale to use to parse the number (system default if
172 * null)
173 *@return the converted Integer value.
174 */
175 public static Integer formatInt(String value, Locale locale) {
176 Integer result = null;
177
178 if (value != null) {
179 NumberFormat formatter = null;
180 if (locale != null) {
181 formatter = NumberFormat.getNumberInstance(locale);
182 } else {
183 formatter = NumberFormat.getNumberInstance(Locale.getDefault());
184 }
185 formatter.setParseIntegerOnly(true);
186 ParsePosition pos = new ParsePosition(0);
187 Number num = formatter.parse(value, pos);
188
189
190 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) {
191 if (num.doubleValue() >= Integer.MIN_VALUE &&
192 num.doubleValue() <= Integer.MAX_VALUE) {
193 result = new Integer(num.intValue());
194 }
195 }
196 }
197
198 return result;
199 }
200
201 /***
202 * Checks if the value can safely be converted to a long primitive.
203 *
204 *@param value The value validation is being performed on.
205 *@return the converted Long value.
206 */
207 public static Long formatLong(String value) {
208 if (value == null) {
209 return null;
210 }
211
212 try {
213 return new Long(value);
214 } catch (NumberFormatException e) {
215 return null;
216 }
217
218 }
219
220 /***
221 * Checks if the value can safely be converted to a long primitive.
222 *
223 *@param value The value validation is being performed on.
224 *@param locale The locale to use to parse the number (system default if
225 * null)
226 *@return the converted Long value.
227 */
228 public static Long formatLong(String value, Locale locale) {
229 Long result = null;
230
231 if (value != null) {
232 NumberFormat formatter = null;
233 if (locale != null) {
234 formatter = NumberFormat.getNumberInstance(locale);
235 } else {
236 formatter = NumberFormat.getNumberInstance(Locale.getDefault());
237 }
238 formatter.setParseIntegerOnly(true);
239 ParsePosition pos = new ParsePosition(0);
240 Number num = formatter.parse(value, pos);
241
242
243 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) {
244 if (num.doubleValue() >= Long.MIN_VALUE &&
245 num.doubleValue() <= Long.MAX_VALUE) {
246 result = new Long(num.longValue());
247 }
248 }
249 }
250
251 return result;
252 }
253
254 /***
255 * Checks if the value can safely be converted to a float primitive.
256 *
257 *@param value The value validation is being performed on.
258 *@return the converted Float value.
259 */
260 public static Float formatFloat(String value) {
261 if (value == null) {
262 return null;
263 }
264
265 try {
266 return new Float(value);
267 } catch (NumberFormatException e) {
268 return null;
269 }
270
271 }
272
273 /***
274 * Checks if the value can safely be converted to a float primitive.
275 *
276 *@param value The value validation is being performed on.
277 *@param locale The locale to use to parse the number (system default if
278 * null)
279 *@return the converted Float value.
280 */
281 public static Float formatFloat(String value, Locale locale) {
282 Float result = null;
283
284 if (value != null) {
285 NumberFormat formatter = null;
286 if (locale != null) {
287 formatter = NumberFormat.getInstance(locale);
288 } else {
289 formatter = NumberFormat.getInstance(Locale.getDefault());
290 }
291 ParsePosition pos = new ParsePosition(0);
292 Number num = formatter.parse(value, pos);
293
294
295 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) {
296 if (num.doubleValue() >= (Float.MAX_VALUE * -1) &&
297 num.doubleValue() <= Float.MAX_VALUE) {
298 result = new Float(num.floatValue());
299 }
300 }
301 }
302
303 return result;
304 }
305
306 /***
307 * Checks if the value can safely be converted to a double primitive.
308 *
309 *@param value The value validation is being performed on.
310 *@return the converted Double value.
311 */
312 public static Double formatDouble(String value) {
313 if (value == null) {
314 return null;
315 }
316
317 try {
318 return new Double(value);
319 } catch (NumberFormatException e) {
320 return null;
321 }
322
323 }
324
325 /***
326 * Checks if the value can safely be converted to a double primitive.
327 *
328 *@param value The value validation is being performed on.
329 *@param locale The locale to use to parse the number (system default if
330 * null)
331 *@return the converted Double value.
332 */
333 public static Double formatDouble(String value, Locale locale) {
334 Double result = null;
335
336 if (value != null) {
337 NumberFormat formatter = null;
338 if (locale != null) {
339 formatter = NumberFormat.getInstance(locale);
340 } else {
341 formatter = NumberFormat.getInstance(Locale.getDefault());
342 }
343 ParsePosition pos = new ParsePosition(0);
344 Number num = formatter.parse(value, pos);
345
346
347 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) {
348 if (num.doubleValue() >= (Double.MAX_VALUE * -1) &&
349 num.doubleValue() <= Double.MAX_VALUE) {
350 result = new Double(num.doubleValue());
351 }
352 }
353 }
354
355 return result;
356 }
357
358 /***
359 * <p>
360 *
361 * Checks if the field is a valid date. The <code>Locale</code> is used
362 * with <code>java.text.DateFormat</code>. The setLenient method is set to
363 * <code>false</code> for all.</p>
364 *
365 *@param value The value validation is being performed on.
366 *@param locale The Locale to use to parse the date (system default if
367 * null)
368 *@return the converted Date value.
369 */
370 public static Date formatDate(String value, Locale locale) {
371 Date date = null;
372
373 if (value == null) {
374 return null;
375 }
376
377 try {
378 DateFormat formatter = null;
379 if (locale != null) {
380 formatter =
381 DateFormat.getDateInstance(DateFormat.SHORT, locale);
382 } else {
383 formatter =
384 DateFormat.getDateInstance(
385 DateFormat.SHORT,
386 Locale.getDefault());
387 }
388
389 formatter.setLenient(false);
390
391 date = formatter.parse(value);
392 } catch (ParseException e) {
393
394 if (log.isDebugEnabled()) {
395 log.debug("Date parse failed value=[" + value + "], " +
396 "locale=[" + locale + "] " + e);
397 }
398 }
399
400 return date;
401 }
402
403 /***
404 * <p>
405 * Checks if the field is a valid date. The pattern is used with <code>java.text.SimpleDateFormat</code>
406 * . If strict is true, then the length will be checked so '2/12/1999' will
407 * not pass validation with the format 'MM/dd/yyyy' because the month isn't
408 * two digits. The setLenient method is set to <code>false</code> for all.
409 * </p>
410 *
411 *@param value The value validation is being performed on.
412 *@param datePattern The pattern passed to <code>SimpleDateFormat</code>.
413 *@param strict Whether or not to have an exact match of the
414 * datePattern.
415 *@return the converted Date value.
416 */
417 public static Date formatDate(String value, String datePattern, boolean strict) {
418 Date date = null;
419
420 if (value == null
421 || datePattern == null
422 || datePattern.length() == 0) {
423 return null;
424 }
425
426 try {
427 SimpleDateFormat formatter = new SimpleDateFormat(datePattern);
428 formatter.setLenient(false);
429
430 date = formatter.parse(value);
431
432 if (strict) {
433 if (datePattern.length() != value.length()) {
434 date = null;
435 }
436 }
437 } catch (ParseException e) {
438
439 if (log.isDebugEnabled()) {
440 log.debug("Date parse failed value=[" + value + "], " +
441 "pattern=[" + datePattern + "], " +
442 "strict=[" + strict + "] " + e);
443 }
444 }
445
446 return date;
447 }
448
449 /***
450 * <p>
451 * Checks if the field is a valid credit card number.</p> <p>
452 *
453 * Reference Sean M. Burke's <a href="http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl">
454 * script</a> .</p>
455 *
456 *@param value The value validation is being performed on.
457 *@return the converted Credit Card number.
458 */
459 public static Long formatCreditCard(String value) {
460 return GenericValidator.isCreditCard(value) ? new Long(value) : null;
461 }
462
463 }
464