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