View Javadoc

1   /*
2    * $Id: GenericTypeValidator.java 384656 2006-03-10 00:36:37Z niallp $
3    * $Rev: 384656 $
4    * $Date: 2006-03-10 00:36:37 +0000 (Fri, 10 Mar 2006) $
5    *
6    * ====================================================================
7    * Copyright 2001-2006 The Apache Software Foundation
8    *
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   *
13   *     http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
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              // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // Bad date so return null
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             // Bad date so return null
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