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