View Javadoc

1   /*
2    * $Id: GenericTypeValidator.java 293556 2005-10-04 07:07:32Z niallp $
3    * $Rev: 293556 $
4    * $Date: 2005-10-04 08:07:32 +0100 (Tue, 04 Oct 2005) $
5    *
6    * ====================================================================
7    * Copyright 2001-2005 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      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              // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // Bad date so return null
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             // Bad date so return null
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