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