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