Coverage report

  %line %branch
org.apache.commons.validator.routines.AbstractNumberValidator
95% 
99% 

 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.text.DecimalFormatSymbols;
 20  
 import java.text.Format;
 21  
 import java.text.NumberFormat;
 22  
 import java.text.DecimalFormat;
 23  
 import java.util.Locale;
 24  
 
 25  
 /**
 26  
  * <p>Abstract class for Number Validation.</p>
 27  
  *
 28  
  * <p>This is a <i>base</i> class for building Number
 29  
  *    Validators using format parsing.</p>
 30  
  *    
 31  
  * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
 32  
  * @since Validator 1.3.0
 33  
  */
 34  
 public abstract class AbstractNumberValidator extends AbstractFormatValidator {
 35  
     
 36  
     /** Standard <code>NumberFormat</code> type */
 37  
     public static final int STANDARD_FORMAT = 0;
 38  
 
 39  
     /** Currency <code>NumberFormat</code> type */
 40  
     public static final int CURRENCY_FORMAT = 1;
 41  
 
 42  
     /** Percent <code>NumberFormat</code> type */
 43  
     public static final int PERCENT_FORMAT  = 2;
 44  
 
 45  
     private boolean allowFractions;
 46  
     private int     formatType;
 47  
 
 48  
     /**
 49  
      * Construct an instance with specified <i>strict</i>
 50  
      * and <i>decimal</i> parameters.
 51  
      * 
 52  
      * @param strict <code>true</code> if strict 
 53  
      *        <code>Format</code> parsing should be used.
 54  
      * @param formatType The <code>NumberFormat</code> type to
 55  
      *        create for validation, default is STANDARD_FORMAT.
 56  
      * @param allowFractions <code>true</code> if fractions are
 57  
      *        allowed or <code>false</code> if integers only.
 58  
      */
 59  
     public AbstractNumberValidator(boolean strict, int formatType, class="keyword">boolean allowFractions) {
 60  196
         super(strict);
 61  196
         this.allowFractions = allowFractions;
 62  196
         this.formatType = formatType;
 63  196
     }
 64  
 
 65  
     /**
 66  
      * <p>Indicates whether the number being validated is
 67  
      *    a decimal or integer.</p>
 68  
      * 
 69  
      * @return <code>true</code> if decimals are allowed
 70  
      *       or <code>false</code> if the number is an integer.
 71  
      */
 72  
     public boolean isAllowFractions() {
 73  737
         return allowFractions;
 74  
     }
 75  
 
 76  
     /**
 77  
      * <p>Indicates the type of <code>NumberFormat</code> created
 78  
      *    by this validator instance.</p>
 79  
      * 
 80  
      * @return the format type created.
 81  
      */
 82  
     public int getFormatType() {
 83  20
         return formatType;
 84  
     }
 85  
 
 86  
     /**
 87  
      * <p>Validate using the specified <code>Locale</code>.</p>
 88  
      * 
 89  
      * @param value The value validation is being performed on.
 90  
      * @param pattern The pattern used to validate the value against, or the
 91  
      *        default for the <code>Locale</code> if <code>null</code>.
 92  
      * @param locale The locale to use for the date format, system default if null.
 93  
      * @return <code>true</code> if the value is valid.
 94  
      */
 95  
     public boolean isValid(String value, String pattern, Locale locale) {
 96  388
         Object parsedValue = parse(value, pattern, locale);
 97  388
         return (parsedValue == null ? false : true);
 98  
     }
 99  
 
 100  
     /**
 101  
      * Check if the value is within a specified range.
 102  
      * 
 103  
      * @param value The value validation is being performed on.
 104  
      * @param min The minimum value of the range.
 105  
      * @param max The maximum value of the range.
 106  
      * @return <code>true</code> if the value is within the
 107  
      *         specified range.
 108  
      */
 109  
     public boolean isInRange(Number value, Number min, Number max) {
 110  40
         return (minValue(value, min) && maxValue(value, max));
 111  
     }
 112  
 
 113  
     /**
 114  
      * Check if the value is greater than or equal to a minimum.
 115  
      * 
 116  
      * @param value The value validation is being performed on.
 117  
      * @param min The minimum value.
 118  
      * @return <code>true</code> if the value is greater than
 119  
      *         or equal to the minimum.
 120  
      */
 121  
     public boolean minValue(Number value, Number min) {
 122  64
         if (isAllowFractions()) {
 123  24
             return (value.doubleValue() >= min.doubleValue());
 124  
         } else {
 125  40
             return (value.longValue() >= min.longValue());
 126  
         }
 127  
     }
 128  
 
 129  
     /**
 130  
      * Check if the value is less than or equal to a maximum.
 131  
      * 
 132  
      * @param value The value validation is being performed on.
 133  
      * @param max The maximum value.
 134  
      * @return <code>true</code> if the value is less than
 135  
      *         or equal to the maximum.
 136  
      */
 137  
     public boolean maxValue(Number value, Number max) {
 138  56
         if (isAllowFractions()) {
 139  21
             return (value.doubleValue() <= max.doubleValue());
 140  
         } else {
 141  35
             return (value.longValue() <= max.longValue());
 142  
         }
 143  
     }
 144  
 
 145  
     /**
 146  
      * <p>Parse the value using the specified pattern.</p>
 147  
      *
 148  
      * @param value The value validation is being performed on.
 149  
      * @param pattern The pattern used to validate the value against, or the
 150  
      *        default for the <code>Locale</code> if <code>null</code>.
 151  
      * @param locale The locale to use for the date format, system default if null.
 152  
      * @return The parsed value if valid or <code>null</code> if invalid.
 153  
      */
 154  
     protected Object parse(String value, String pattern, Locale locale) {
 155  
 
 156  903
         value = (value == null ? class="keyword">null : value.trim());
 157  903
         if (value == null || value.length() == 0) {
 158  136
             return null;
 159  
         }
 160  767
         Format formatter = getFormat(pattern, locale);
 161  767
         return parse(value, formatter);
 162  
 
 163  
     }
 164  
 
 165  
     /**
 166  
      * <p>Process the parsed value, performing any further validation 
 167  
      *    and type conversion required.</p>
 168  
      * 
 169  
      * @param value The parsed object created.
 170  
      * @param formatter The Format used to parse the value with.
 171  
      * @return The parsed value converted to the appropriate type
 172  
      *         if valid or <code>null</code> if invalid.
 173  
      */
 174  
     protected abstract Object processParsedValue(Object value, Format formatter);
 175  
 
 176  
     /**
 177  
      * <p>Returns a <code>NumberFormat</code> for the specified <i>pattern</i>
 178  
      *    and/or <code>Locale</code>.</p>
 179  
      * 
 180  
      * @param pattern The pattern used to validate the value against or
 181  
      *        <code>null</code> to use the default for the <code>Locale</code>.
 182  
      * @param locale The locale to use for the currency format, system default if null.
 183  
      * @return The <code>NumberFormat</code> to created.
 184  
      */
 185  
     protected Format getFormat(String pattern, Locale locale) {
 186  
 
 187  791
         NumberFormat formatter = null;
 188  791
         boolean usePattern = (pattern != null && pattern.length() > 0);
 189  791
         if (!usePattern) {
 190  407
             formatter = (NumberFormat)getFormat(locale);
 191  384
         } else if (locale == null) {
 192  347
             formatter =  new DecimalFormat(pattern);
 193  
         } else {
 194  37
             DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
 195  37
             formatter = new DecimalFormat(pattern, symbols);
 196  
         }
 197  
 
 198  791
         if (determineScale(formatter) == 0) {
 199  355
             formatter.setParseIntegerOnly(true);
 200  
         }
 201  791
         return formatter;
 202  
     }
 203  
 
 204  
     /**
 205  
      * <p>Returns the <i>multiplier</i> of the <code>NumberFormat</code>.</p>
 206  
      * 
 207  
      * @param format The <code>NumberFormat</code> to determine the 
 208  
      *        multiplier of.
 209  
      * @return The multiplying factor for the format..
 210  
      */
 211  
     protected int determineScale(NumberFormat format) {
 212  877
         if (!isStrict()) {
 213  260
             return -1;
 214  
         }
 215  617
         if (!isAllowFractions() || format.isParseIntegerOnly()) {
 216  323
             return 0;
 217  
         }
 218  294
         int minimumFraction = format.getMinimumFractionDigits();
 219  294
         int maximumFraction = format.getMaximumFractionDigits();
 220  294
         if (minimumFraction != maximumFraction) {
 221  175
             return -1;
 222  
         }
 223  119
         int scale = minimumFraction;
 224  119
         if (format instanceof DecimalFormat) {
 225  119
             int multiplier = ((DecimalFormat)format).getMultiplier();
 226  119
             if (multiplier == 100) {
 227  20
                 scale += 2;
 228  99
             } else if (multiplier == 1000) {
 229  0
                 scale += 3;
 230  
             }
 231  0
         } else if (formatType == PERCENT_FORMAT) {
 232  0
             scale += 2;
 233  
         }
 234  119
         return scale;
 235  
     }
 236  
 
 237  
     /**
 238  
      * <p>Returns a <code>NumberFormat</code> for the specified Locale.</p>
 239  
      * 
 240  
      * @param locale The locale a <code>NumberFormat</code> is required for,
 241  
      *   system default if null.
 242  
      * @return The <code>NumberFormat</code> to created.
 243  
      */
 244  
     protected Format getFormat(Locale locale) {
 245  407
         NumberFormat formatter = null;
 246  407
         switch (formatType) {
 247  
         case CURRENCY_FORMAT:
 248  26
             if (locale == null) {
 249  2
                 formatter = NumberFormat.getCurrencyInstance();
 250  
             } else {
 251  24
                 formatter = NumberFormat.getCurrencyInstance(locale);
 252  
             }
 253  24
             break;
 254  
         case PERCENT_FORMAT:
 255  13
             if (locale == null) {
 256  3
                 formatter = NumberFormat.getPercentInstance();
 257  
             } else {
 258  10
                 formatter = NumberFormat.getPercentInstance(locale);
 259  
             }
 260  10
             break;
 261  
         default:
 262  368
             if (locale == null) {
 263  48
                 formatter = NumberFormat.getInstance();
 264  
             } else {
 265  320
                 formatter = NumberFormat.getInstance(locale);
 266  
             }
 267  
             break;
 268  
         }
 269  407
         return formatter;
 270  
     }
 271  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.