Coverage report

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

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

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