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.routines;
    18
    19  import java.math.BigDecimal;
    20  import java.text.Format;
    21  import java.text.NumberFormat;
    22  import java.util.Locale;
    23
    24  /***
    25   * <p><b>BigDecimal Validation</b> and Conversion routines (<code>java.math.BigDecimal</code>).</p>
    26   *
    27   * <p>This validator provides a number of methods for
    28   *    validating/converting a <code>String</code> value to
    29   *    a <code>BigDecimal</code> using <code>java.text.NumberFormat</code>
    30   *    to parse either:</p>
    31   *    <ul>
    32   *       <li>using the default format for the default <code>Locale</code></li>
    33   *       <li>using a specified pattern with the default <code>Locale</code></li>
    34   *       <li>using the default format for a specified <code>Locale</code></li>
    35   *       <li>using a specified pattern with a specified <code>Locale</code></li>
    36   *    </ul>
    37   *
    38   * <p>Use one of the <code>isValid()</code> methods to just validate or
    39   *    one of the <code>validate()</code> methods to validate and receive a
    40   *    <i>converted</i> <code>BigDecimal</code> value.</p>
    41   *
    42   * <p>Fraction/decimal values are automatically trimmed to the appropriate length.</p>
    43   *
    44   * <p>Once a value has been sucessfully converted the following
    45   *    methods can be used to perform minimum, maximum and range checks:</p>
    46   *    <ul>
    47   *       <li><code>minValue()</code> checks whether the value is greater
    48   *           than or equal to a specified minimum.</li>
    49   *       <li><code>maxValue()</code> checks whether the value is less
    50   *           than or equal to a specified maximum.</li>
    51   *       <li><code>isInRange()</code> checks whether the value is within
    52   *           a specified range of values.</li>
    53   *    </ul>
    54   *
    55   * <p>So that the same mechanism used for parsing an <i>input</i> value
    56   *    for validation can be used to format <i>output</i>, corresponding
    57   *    <code>format()</code> methods are also provided. That is you can
    58   *    format either:</p>
    59   *    <ul>
    60   *       <li>using the default format for the default <code>Locale</code></li>
    61   *       <li>using a specified pattern with the default <code>Locale</code></li>
    62   *       <li>using the default format for a specified <code>Locale</code></li>
    63   *       <li>using a specified pattern with a specified <code>Locale</code></li>
    64   *    </ul>
    65   *
    66   * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
    67   * @since Validator 1.3.0
    68   */
    69  public class BigDecimalValidator extends AbstractNumberValidator {
    70
    71      private static final BigDecimalValidator VALIDATOR = new BigDecimalValidator();
    72
    73      /***
    74       * Return a singleton instance of this validator.
    75       * @return A singleton instance of the BigDecimalValidator.
    76       */
    77      public static BigDecimalValidator getInstance() {
    78          return VALIDATOR;
    79      }
    80
    81      /***
    82       * Construct a <i>strict</i> instance.
    83       */
    84      public BigDecimalValidator() {
    85          this(true);
    86      }
    87
    88      /***
    89       * <p>Construct an instance with the specified strict setting.</p>
    90       *
    91       * @param strict <code>true</code> if strict
    92       *        <code>Format</code> parsing should be used.
    93       */
    94      public BigDecimalValidator(boolean strict) {
    95          this(strict, STANDARD_FORMAT, true);
    96      }
    97
    98      /***
    99       * <p>Construct an instance with the specified strict setting
    100      *    and format type.</p>
    101      *
    102      * <p>The <code>formatType</code> specified what type of
    103      *    <code>NumberFormat</code> is created - valid types
    104      *    are:</p>
    105      *    <ul>
    106      *       <li>AbstractNumberValidator.STANDARD_FORMAT -to create
    107      *           <i>standard</i> number formats (the default).</li>
    108      *       <li>AbstractNumberValidator.CURRENCY_FORMAT -to create
    109      *           <i>currency</i> number formats.</li>
    110      *       <li>AbstractNumberValidator.PERCENT_FORMAT -to create
    111      *           <i>percent</i> number formats (the default).</li>
    112      *    </ul>
    113      *
    114      * @param strict <code>true</code> if strict
    115      *        <code>Format</code> parsing should be used.
    116      * @param formatType The <code>NumberFormat</code> type to
    117      *        create for validation, default is STANDARD_FORMAT.
    118      * @param allowFractions <code>true</code> if fractions are
    119      *        allowed or <code>false</code> if integers only.
    120      */
    121     protected BigDecimalValidator(boolean strict, int formatType,
    122             boolean allowFractions) {
    123         super(strict, formatType, allowFractions);
    124     }
    125
    126     /***
    127      * <p>Validate/convert a <code>BigDecimal</code> using the default
    128      *    <code>Locale</code>.
    129      *
    130      * @param value The value validation is being performed on.
    131      * @return The parsed <code>BigDecimal</code> if valid or <code>null</code>
    132      *  if invalid.
    133      */
    134     public BigDecimal validate(String value) {
    135         return (BigDecimal)parse(value, (String)null, (Locale)null);
    136     }
    137
    138     /***
    139      * <p>Validate/convert a <code>BigDecimal</code> using the
    140      *    specified <i>pattern</i>.
    141      *
    142      * @param value The value validation is being performed on.
    143      * @param pattern The pattern used to validate the value against, or the
    144      *        default for the <code>Locale</code> if <code>null</code>.
    145      * @return The parsed <code>BigDecimal</code> if valid or <code>null</code> if invalid.
    146      */
    147     public BigDecimal validate(String value, String pattern) {
    148         return (BigDecimal)parse(value, pattern, (Locale)null);
    149     }
    150
    151     /***
    152      * <p>Validate/convert a <code>BigDecimal</code> using the
    153      *    specified <code>Locale</code>.
    154      *
    155      * @param value The value validation is being performed on.
    156      * @param locale The locale to use for the number format, system default if null.
    157      * @return The parsed <code>BigDecimal</code> if valid or <code>null</code> if invalid.
    158      */
    159     public BigDecimal validate(String value, Locale locale) {
    160         return (BigDecimal)parse(value, (String)null, locale);
    161     }
    162
    163     /***
    164      * <p>Validate/convert a <code>BigDecimal</code> using the
    165      *    specified pattern and/ or <code>Locale</code>.
    166      *
    167      * @param value The value validation is being performed on.
    168      * @param pattern The pattern used to validate the value against, or the
    169      *        default for the <code>Locale</code> if <code>null</code>.
    170      * @param locale The locale to use for the date format, system default if null.
    171      * @return The parsed <code>BigDecimal</code> if valid or <code>null</code> if invalid.
    172      */
    173     public BigDecimal validate(String value, String pattern, Locale locale) {
    174         return (BigDecimal)parse(value, pattern, locale);
    175     }
    176
    177     /***
    178      * Check if the value is within a specified range.
    179      *
    180      * @param value The <code>Number</code> value to check.
    181      * @param min The minimum value of the range.
    182      * @param max The maximum value of the range.
    183      * @return <code>true</code> if the value is within the
    184      *         specified range.
    185      */
    186     public boolean isInRange(BigDecimal value, double min, double max) {
    187         return (value.doubleValue() >= min && value.doubleValue() <= max);
    188     }
    189
    190     /***
    191      * Check if the value is greater than or equal to a minimum.
    192      *
    193      * @param value The value validation is being performed on.
    194      * @param min The minimum value.
    195      * @return <code>true</code> if the value is greater than
    196      *         or equal to the minimum.
    197      */
    198     public boolean minValue(BigDecimal value, double min) {
    199         return (value.doubleValue() >= min);
    200     }
    201
    202     /***
    203      * Check if the value is less than or equal to a maximum.
    204      *
    205      * @param value The value validation is being performed on.
    206      * @param max The maximum value.
    207      * @return <code>true</code> if the value is less than
    208      *         or equal to the maximum.
    209      */
    210     public boolean maxValue(BigDecimal value, double max) {
    211         return (value.doubleValue() <= max);
    212     }
    213
    214     /***
    215      * Convert the parsed value to a <code>BigDecimal</code>.
    216      *
    217      * @param value The parsed <code>Number</code> object created.
    218      * @param formatter The Format used to parse the value with.
    219      * @return The parsed <code>Number</code> converted to a
    220      *         <code>BigDecimal</code>.
    221      */
    222     protected Object processParsedValue(Object value, Format formatter) {
    223         BigDecimal decimal = null;
    224         if (value instanceof Long) {
    225             decimal = BigDecimal.valueOf(((Long)value).longValue());
    226         } else {
    227             decimal = new BigDecimal(value.toString());
    228         }
    229
    230         int scale = determineScale((NumberFormat)formatter);
    231         if (scale >= 0) {
    232             decimal = decimal.setScale(scale, BigDecimal.ROUND_DOWN);
    233         }
    234
    235         return decimal;
    236     }
    237 }