Coverage Report - javax.faces.convert.NumberConverter
 
Classes in this File Line Coverage Branch Coverage Complexity
NumberConverter
81%
149/183
42%
27/64
1.952
 
 1  
 /*
 2  
  * Copyright 2004-2011 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package javax.faces.convert;
 17  
 
 18  
 import java.text.DecimalFormat;
 19  
 import java.text.DecimalFormatSymbols;
 20  
 import java.text.NumberFormat;
 21  
 import java.text.ParseException;
 22  
 import java.util.Currency;
 23  
 import java.util.Locale;
 24  
 
 25  
 import javax.faces.component.StateHolder;
 26  
 import javax.faces.component.UIComponent;
 27  
 import javax.faces.context.FacesContext;
 28  
 import javax.faces.internal.ConvertUtil;
 29  
 import javax.faces.internal.FacesMessageUtil;
 30  
 
 31  
 import org.seasar.framework.util.AssertionUtil;
 32  
 import org.seasar.framework.util.NumberConversionUtil;
 33  
 
 34  
 /**
 35  
  * @author shot
 36  
  */
 37  
 public class NumberConverter implements Converter, StateHolder {
 38  
 
 39  
     public static final String CONVERTER_ID = "javax.faces.Number";
 40  
 
 41  2
     public static final String CONVERSION_OBJECT_ID = NumberConverter.class
 42  
             .getName()
 43  
             + ".CONVERSION";
 44  
 
 45  1
     public static final String CONVERSION_STRING_ID = NumberConverter.class
 46  
             .getName()
 47  
             + ".CONVERSION_STRING";
 48  
 
 49  37
     private Locale locale = null;
 50  
 
 51  37
     private String pattern = null;
 52  
 
 53  37
     private String type = null;
 54  
 
 55  37
     private String currencyCode = null;
 56  
 
 57  37
     private String currencySymbol = null;
 58  
 
 59  37
     private boolean isIntegerOnly = false;
 60  
 
 61  37
     private boolean isTransient = false;
 62  
 
 63  37
     private boolean isGroupingUsed = false;
 64  
 
 65  37
     private int maxFractionDigits = 0;
 66  
 
 67  37
     private int maxIntegerDigits = 0;
 68  
 
 69  37
     private int minFractionDigits = 0;
 70  
 
 71  37
     private int minIntegerDigits = 0;
 72  
 
 73  
     private static final String TYPE_CURRENCY = "currency";
 74  
 
 75  
     private static final String TYPE_NUMBER = "number";
 76  
 
 77  
     private static final String TYPE_PERCENT = "percent";
 78  
 
 79  37
     private boolean isSetMaxFractionDigits = false;
 80  
 
 81  37
     private boolean isSetMaxIntegerDigits = false;
 82  
 
 83  37
     private boolean isSetMinFractionDigits = false;
 84  
 
 85  37
     private boolean isSetMinIntegerDigits = false;
 86  
 
 87  37
     public NumberConverter() {
 88  37
     }
 89  
 
 90  
     public Object getAsObject(FacesContext context, UIComponent component,
 91  
             String value) throws ConverterException {
 92  7
         AssertionUtil.assertNotNull("FacesContext", context);
 93  6
         AssertionUtil.assertNotNull("UIComponent", component);
 94  5
         if (value == null) {
 95  1
             return null;
 96  
         }
 97  4
         value = value.trim();
 98  4
         if (value.length() < 1) {
 99  1
             return null;
 100  
         }
 101  3
         Locale locale = getLocale(context);
 102  3
         value = NumberConversionUtil.removeDelimeter(value, locale);
 103  
 
 104  3
         NumberFormat formatter = getNumberFormat(locale);
 105  3
         formatter.setParseIntegerOnly(isIntegerOnly());
 106  
         try {
 107  3
             return formatter.parse(value);
 108  1
         } catch (ParseException e) {
 109  1
             Object[] args = ConvertUtil.createExceptionMessageArgs(component,
 110  
                     value);
 111  1
             throw new ConverterException(FacesMessageUtil.getMessage(context,
 112  
                     getObjectMessageId(), args), e);
 113  
         }
 114  
     }
 115  
 
 116  
     public String getAsString(FacesContext context, UIComponent component,
 117  
             Object value) throws ConverterException {
 118  9
         AssertionUtil.assertNotNull("FacesContext", context);
 119  8
         AssertionUtil.assertNotNull("UIComponent", component);
 120  7
         if (value == null) {
 121  2
             return "";
 122  
         }
 123  5
         if (value instanceof String) {
 124  2
             return (String) value;
 125  
         }
 126  3
         Locale locale = getLocale(context);
 127  3
         String pattern = getPattern();
 128  3
         NumberFormat formatter = getNumberFormat(locale);
 129  3
         if (pattern == null) {
 130  2
             configureFormatter(formatter);
 131  2
             if (TYPE_CURRENCY.equals(type)) {
 132  0
                 configureCurrency(formatter);
 133  
             }
 134  
         }
 135  
         try {
 136  3
             return formatter.format(value);
 137  1
         } catch (Exception e) {
 138  1
             Object[] args = ConvertUtil.createExceptionMessageArgs(component,
 139  
                     value);
 140  1
             throw new ConverterException(FacesMessageUtil.getMessage(context,
 141  
                     getStringMessageId(), args), e);
 142  
         }
 143  
     }
 144  
 
 145  
     public Object saveState(FacesContext context) {
 146  1
         Object values[] = new Object[15];
 147  1
         values[0] = getCurrencyCode();
 148  1
         values[1] = getCurrencySymbol();
 149  1
         values[2] = isGroupingUsed() ? Boolean.TRUE : Boolean.FALSE;
 150  1
         values[3] = isIntegerOnly() ? Boolean.TRUE : Boolean.FALSE;
 151  1
         values[4] = new Integer(getMaxFractionDigits());
 152  1
         values[5] = isSetMaxFractionDigits ? Boolean.TRUE : Boolean.FALSE;
 153  1
         values[6] = new Integer(getMaxIntegerDigits());
 154  1
         values[7] = isSetMaxIntegerDigits ? Boolean.TRUE : Boolean.FALSE;
 155  1
         values[8] = new Integer(getMinFractionDigits());
 156  1
         values[9] = isSetMinFractionDigits ? Boolean.TRUE : Boolean.FALSE;
 157  1
         values[10] = new Integer(getMinIntegerDigits());
 158  1
         values[11] = isSetMinIntegerDigits ? Boolean.TRUE : Boolean.FALSE;
 159  1
         values[12] = getLocale();
 160  1
         values[13] = getPattern();
 161  1
         values[14] = getType();
 162  1
         return values;
 163  
     }
 164  
 
 165  
     public void restoreState(FacesContext context, Object state) {
 166  1
         Object[] values = (Object[]) state;
 167  1
         currencyCode = (String) values[0];
 168  1
         currencySymbol = (String) values[1];
 169  1
         isGroupingUsed = ((Boolean) values[2]).booleanValue();
 170  1
         isIntegerOnly = ((Boolean) values[3]).booleanValue();
 171  1
         maxFractionDigits = ((Integer) values[4]).intValue();
 172  1
         isSetMaxFractionDigits = ((Boolean) values[5]).booleanValue();
 173  1
         maxIntegerDigits = ((Integer) values[6]).intValue();
 174  1
         isSetMaxIntegerDigits = ((Boolean) values[7]).booleanValue();
 175  1
         minFractionDigits = ((Integer) values[8]).intValue();
 176  1
         isSetMinFractionDigits = ((Boolean) values[9]).booleanValue();
 177  1
         minIntegerDigits = ((Integer) values[10]).intValue();
 178  1
         isSetMinIntegerDigits = ((Boolean) values[11]).booleanValue();
 179  1
         locale = (Locale) values[12];
 180  1
         pattern = (String) values[13];
 181  1
         type = (String) values[14];
 182  1
     }
 183  
 
 184  
     public boolean isTransient() {
 185  0
         return isTransient;
 186  
     }
 187  
 
 188  
     public void setTransient(boolean isTransient) {
 189  0
         this.isTransient = isTransient;
 190  0
     }
 191  
 
 192  
     public Locale getLocale() {
 193  9
         return locale;
 194  
     }
 195  
 
 196  
     public void setLocale(Locale locale) {
 197  4
         this.locale = locale;
 198  4
     }
 199  
 
 200  
     public String getPattern() {
 201  6
         return pattern;
 202  
     }
 203  
 
 204  
     public void setPattern(String pattern) {
 205  5
         this.pattern = pattern;
 206  5
     }
 207  
 
 208  
     public String getType() {
 209  3
         return type;
 210  
     }
 211  
 
 212  
     public void setType(String type) {
 213  9
         this.type = type;
 214  9
     }
 215  
 
 216  
     public boolean isIntegerOnly() {
 217  7
         return isIntegerOnly;
 218  
     }
 219  
 
 220  
     public void setIntegerOnly(boolean isIntegerOnly) {
 221  3
         this.isIntegerOnly = isIntegerOnly;
 222  3
     }
 223  
 
 224  
     public boolean isGroupingUsed() {
 225  6
         return isGroupingUsed;
 226  
     }
 227  
 
 228  
     public void setGroupingUsed(boolean isGroupingUsed) {
 229  6
         this.isGroupingUsed = isGroupingUsed;
 230  6
     }
 231  
 
 232  
     public String getCurrencyCode() {
 233  4
         return currencyCode;
 234  
     }
 235  
 
 236  
     public void setCurrencyCode(String currencyCode) {
 237  3
         this.currencyCode = currencyCode;
 238  3
     }
 239  
 
 240  
     public String getCurrencySymbol() {
 241  3
         return currencySymbol;
 242  
     }
 243  
 
 244  
     public void setCurrencySymbol(String currencySymbol) {
 245  2
         this.currencySymbol = currencySymbol;
 246  2
     }
 247  
 
 248  
     public int getMaxFractionDigits() {
 249  4
         return maxFractionDigits;
 250  
     }
 251  
 
 252  
     public void setMaxFractionDigits(int maxFractionDigits) {
 253  3
         this.maxFractionDigits = maxFractionDigits;
 254  3
         this.isSetMaxFractionDigits = true;
 255  3
     }
 256  
 
 257  
     public int getMaxIntegerDigits() {
 258  4
         return maxIntegerDigits;
 259  
     }
 260  
 
 261  
     public void setMaxIntegerDigits(int maxIntegerDigits) {
 262  3
         this.maxIntegerDigits = maxIntegerDigits;
 263  3
         this.isSetMaxIntegerDigits = true;
 264  3
     }
 265  
 
 266  
     public int getMinFractionDigits() {
 267  4
         return minFractionDigits;
 268  
     }
 269  
 
 270  
     public void setMinFractionDigits(int minFractionDigits) {
 271  3
         this.minFractionDigits = minFractionDigits;
 272  3
         this.isSetMinFractionDigits = true;
 273  3
     }
 274  
 
 275  
     public int getMinIntegerDigits() {
 276  4
         return minIntegerDigits;
 277  
     }
 278  
 
 279  
     public void setMinIntegerDigits(int minIntegerDigits) {
 280  3
         this.minIntegerDigits = minIntegerDigits;
 281  3
         this.isSetMinIntegerDigits = true;
 282  3
     }
 283  
 
 284  
     private Locale getLocale(FacesContext context) {
 285  6
         Locale locale = getLocale();
 286  6
         if (locale != null) {
 287  0
             return locale;
 288  
         }
 289  6
         return context.getViewRoot().getLocale();
 290  
     }
 291  
 
 292  
     private NumberFormat getNumberFormat(Locale locale) {
 293  6
         if (pattern != null) {
 294  2
             DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
 295  2
             return new DecimalFormat(pattern, symbols);
 296  
         }
 297  4
         if (type != null) {
 298  4
             return getNumberFormatForType();
 299  
         }
 300  0
         throw new ConverterException("NumberFormat not found");
 301  
     }
 302  
 
 303  
     private NumberFormat getNumberFormatForType() {
 304  4
         if (type.equals(TYPE_CURRENCY)) {
 305  0
             return NumberFormat.getCurrencyInstance();
 306  4
         } else if (type.equals(TYPE_NUMBER)) {
 307  4
             return NumberFormat.getNumberInstance();
 308  0
         } else if (type.equals(TYPE_PERCENT)) {
 309  0
             return NumberFormat.getPercentInstance();
 310  
         } else {
 311  0
             throw new ConverterException(new IllegalArgumentException());
 312  
         }
 313  
     }
 314  
 
 315  
     protected void configureFormatter(NumberFormat formatter) {
 316  2
         formatter.setGroupingUsed(isGroupingUsed());
 317  2
         setMaximumFractionDigitsToFormatter(formatter);
 318  2
         setMaximumIntegerDigitsToFormatter(formatter);
 319  2
         setMinimumFractionDigitsToFormatter(formatter);
 320  2
         setMinimumIntegerDigitsToFormatter(formatter);
 321  2
     }
 322  
 
 323  
     protected void setMaximumFractionDigitsToFormatter(NumberFormat formatter) {
 324  2
         if (isSetMaxFractionDigits) {
 325  0
             formatter.setMaximumFractionDigits(getMaxFractionDigits());
 326  
         }
 327  2
     }
 328  
 
 329  
     protected void setMaximumIntegerDigitsToFormatter(NumberFormat formatter) {
 330  2
         if (isSetMaxIntegerDigits) {
 331  0
             formatter.setMaximumIntegerDigits(getMaxIntegerDigits());
 332  
         }
 333  2
     }
 334  
 
 335  
     protected void setMinimumFractionDigitsToFormatter(NumberFormat formatter) {
 336  2
         if (isSetMinFractionDigits) {
 337  0
             formatter.setMinimumFractionDigits(getMinFractionDigits());
 338  
         }
 339  2
     }
 340  
 
 341  
     protected void setMinimumIntegerDigitsToFormatter(NumberFormat formatter) {
 342  2
         if (isSetMinIntegerDigits) {
 343  0
             formatter.setMinimumIntegerDigits(getMinIntegerDigits());
 344  
         }
 345  2
     }
 346  
 
 347  
     protected void configureCurrency(NumberFormat formatter) {
 348  0
         boolean isCurrencyCodeUse = false;
 349  0
         String currencyCode = getCurrencyCode();
 350  0
         String currencySymbol = getCurrencySymbol();
 351  0
         if ((currencyCode == null) && (currencySymbol == null)) {
 352  0
             return;
 353  
         }
 354  0
         if (isSetBothCurrencyProperties() && isJava14()) {
 355  0
             isCurrencyCodeUse = (currencyCode != null);
 356  
         } else {
 357  0
             isCurrencyCodeUse = (currencySymbol == null);
 358  
         }
 359  0
         if (isCurrencyCodeUse) {
 360  0
             formatter.setCurrency(Currency.getInstance(currencyCode));
 361  
         } else {
 362  0
             DecimalFormat df = (DecimalFormat) formatter;
 363  0
             DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
 364  0
             symbols.setCurrencySymbol(currencySymbol);
 365  0
             df.setDecimalFormatSymbols(symbols);
 366  
         }
 367  0
     }
 368  
 
 369  
     protected boolean isSetBothCurrencyProperties() {
 370  0
         return ((getCurrencyCode() != null) && (getCurrencySymbol() != null));
 371  
     }
 372  
 
 373  
     protected static boolean isJava14() {
 374  
         try {
 375  0
             Class clazz = Class.forName("java.util.Currency");
 376  0
             return (clazz != null);
 377  0
         } catch (Exception ignore) {
 378  0
             return false;
 379  
         }
 380  
     }
 381  
 
 382  
     protected String getObjectMessageId() {
 383  1
         return CONVERSION_OBJECT_ID;
 384  
     }
 385  
 
 386  
     protected String getStringMessageId() {
 387  1
         return CONVERSION_STRING_ID;
 388  
     }
 389  
 
 390  
 }