View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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              // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // If there was no error      and we used the whole string
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             // Bad date so return null
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             // Bad date so return null
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