Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 
 package javax.faces.convert;
 
 

Converter implementation for java.lang.Number values.

The getAsObject() method parses a String into an java.lang.Double or java.lang.Long, according to the following algorithm:

  • If the specified String is null, return a null. Otherwise, trim leading and trailing whitespace before proceeding.
  • If the specified String - after trimming - has a zero length, return null.
  • If the locale property is not null, use that Locale for managing parsing. Otherwise, use the Locale from the UIViewRoot.
  • If a pattern has been specified, its syntax must conform the rules specified by java.text.DecimalFormat. Such a pattern will be used to parse, and the type property will be ignored.
  • If a pattern has not been specified, parsing will be based on the type property, which expects a currency, a number, or a percent. The parse pattern for currencies, numbers, and percentages is determined by calling the getCurrencyInstance(), getNumberInstance(), or getPercentInstance() method of the java.text.NumberFormat class, passing in the selected Locale.
  • If the integerOnly property has been set to true, only the integer portion of the String will be parsed. See the JavaDocs for the setParseIntegerOnly() method of the java.text.NumberFormat class for more information.

The getAsString() method expects a value of type java.lang.Number (or a subclass), and creates a formatted String according to the following algorithm:

  • If the specified value is null, return a zero-length String.
  • If the specified value is a String, return it unmodified.
  • If the locale property is not null, use that Locale for managing formatting. Otherwise, use the Locale from the FacesContext.
  • If a pattern has been specified, its syntax must conform the rules specified by java.text.DecimalFormat. Such a pattern will be used to format, and the type property (along with related formatting options described in the next paragraph) will be ignored.
  • If a pattern has not been specified, formatting will be based on the type property, which formats the value as a currency, a number, or a percent. The format pattern for currencies, numbers, and percentages is determined by calling the percentages is determined by calling the getCurrencyInstance(), getNumberInstance(), or getPercentInstance() method of the java.text.NumberFormat class, passing in the selected Locale. In addition, the following properties will be applied to the format pattern, if specified:
    • If the groupingUsed property is true, the setGroupingUsed(true) method on the corresponding NumberFormat instance will be called.
    • The minimum and maximum number of digits in the integer and fractional portions of the result will be configured based on any values set for the maxFractionDigits, maxIntegerDigits, minFractionDigits, and minIntegerDigits properties.
    • If the type is set to currency, it is also possible to configure the currency symbol to be used, using either the currencyCode or currencySymbol properties. If both are set, the value for currencyCode takes precedence on a JDK 1.4 (or later) JVM; otherwise, the value for currencySymbol takes precedence.
public class NumberConverter implements ConverterPartialStateHolder {
    // ------------------------------------------------------ Manifest Constants


    

The standard converter id for this converter.

    public static final String CONVERTER_ID = "javax.faces.Number";

    

The message identifier of the javax.faces.application.FacesMessage to be created if the conversion to Number fails. The message format string for this message may optionally include the following placeholders:

  • {0} replaced by the unconverted value.
  • {1} replaced by an example value.
  • {2} replaced by a String whose value is the label of the input component that produced this message.
    public static final String CURRENCY_ID =
         "javax.faces.converter.NumberConverter.CURRENCY";

    

The message identifier of the javax.faces.application.FacesMessage to be created if the conversion to Number fails. The message format string for this message may optionally include the following placeholders:

  • {0} replaced by the unconverted value.
  • HA
  • {1} replaced by an example value.
  • {2} replaced by a String whose value is the label of the input component that produced this message.
    public static final String NUMBER_ID =
         "javax.faces.converter.NumberConverter.NUMBER";

    

The message identifier of the javax.faces.application.FacesMessage to be created if the conversion to Number fails. The message format string for this message may optionally include the following placeholders:

  • {0} replaced by the unconverted value.
  • {1} replaced by an example value.
  • {2} replaced by a String whose value is the label of the input component that produced this message.
    public static final String PATTERN_ID =
         "javax.faces.converter.NumberConverter.PATTERN";

    

The message identifier of the javax.faces.application.FacesMessage to be created if the conversion to Number fails. The message format string for this message may optionally include the following placeholders:

  • {0} replaced by the unconverted value.
  • {1} replaced by an example value.
  • {2} replaced by a String whose value is the label of the input component that produced this message.
    public static final String PERCENT_ID =
         "javax.faces.converter.NumberConverter.PERCENT";

    

The message identifier of the javax.faces.application.FacesMessage to be created if the conversion of the Number value to String fails. The message format string for this message may optionally include the following placeholders:

  • {0} relaced by the unconverted value.
  • {1} replaced by a String whose value is the label of the input component that produced this message.
    public static final String STRING_ID =
         "javax.faces.converter.STRING";
     private static final String NBSP = "\u00a0";
    // ------------------------------------------------------ Instance Variables
    private String currencyCode = null;
    private String currencySymbol = null;
    private Boolean groupingUsed = true;
    private Boolean integerOnly = false;
    private Integer maxFractionDigits;
    private Integer maxIntegerDigits;
    private Integer minFractionDigits;
    private Integer minIntegerDigits;
    private Locale locale = null;
    private String pattern = null;
    private String type = "number";
    // -------------------------------------------------------------- Properties


    

Return the ISO 4217 currency code used by getAsString() with a type of currency. If not set, the value used will be based on the formatting Locale.

    public String getCurrencyCode() {
        return (this.);
    }


    

Set the ISO 4217 currency code used by getAsString() with a type of currency.

Parameters:
currencyCode The new currency code
    public void setCurrencyCode(String currencyCode) {
        clearInitialState();
        this. = currencyCode;
    }


    

Return the currency symbol used by getAsString() with a type of currency. If not set, the value used will be based on the formatting Locale.

    public String getCurrencySymbol() {
        return (this.);
    }


    

Set the currency symbol used by getAsString() with a type of currency.

Parameters:
currencySymbol The new currency symbol
    public void setCurrencySymbol(String currencySymbol) {
        clearInitialState();
        this. = currencySymbol;
    }


    

Return true if getAsString should include grouping separators if necessary. If not modified, the default value is true.

    public boolean isGroupingUsed() {
        return (this. != null ? this. : true);
    }


    

Set the flag indicating whether getAsString() should include grouping separators if necessary.

Parameters:
groupingUsed The new grouping used flag
    public void setGroupingUsed(boolean groupingUsed) {
        clearInitialState();
        this. = groupingUsed;
    }


    

Return true if only the integer portion of the given value should be returned from getAsObject(). If not modified, the default value is false.

    public boolean isIntegerOnly() {
        return (this. != null ? this. : false);
    }


    

Set to true if only the integer portion of the given value should be returned from getAsObject().

Parameters:
integerOnly The new integer-only flag
    public void setIntegerOnly(boolean integerOnly) {
        clearInitialState();
        this. = integerOnly;
    }


    

Return the maximum number of digits getAsString() should render in the fraction portion of the result.

    public int getMaxFractionDigits() {
        return (this. != null ? this. : 0);
    }


    

Set the maximum number of digits getAsString() should render in the fraction portion of the result. If not set, the number of digits depends on the value being converted.

Parameters:
maxFractionDigits The new limit
    public void setMaxFractionDigits(int maxFractionDigits) {
        clearInitialState();
        this. = maxFractionDigits;
    }


    

Return the maximum number of digits getAsString() should render in the integer portion of the result.

    public int getMaxIntegerDigits() {
        return (this. != null ? this. : 0);
    }


    

Set the maximum number of digits getAsString() should render in the integer portion of the result. If not set, the number of digits depends on the value being converted.

Parameters:
maxIntegerDigits The new limit
    public void setMaxIntegerDigits(int maxIntegerDigits) {
        clearInitialState();
        this. = maxIntegerDigits;
    }


    

Return the minimum number of digits getAsString() should render in the fraction portion of the result.

    public int getMinFractionDigits() {
        return (this. != null ? this. : 0);
    }


    

Set the minimum number of digits getAsString() should render in the fraction portion of the result. If not set, the number of digits depends on the value being converted.

Parameters:
minFractionDigits The new limit
    public void setMinFractionDigits(int minFractionDigits) {
        clearInitialState();
        this. = minFractionDigits;
    }


    

Return the minimum number of digits getAsString() should render in the integer portion of the result.

    public int getMinIntegerDigits() {
        return (this. != null ? this. : 0);
    }


    

Set the minimum number of digits getAsString() should render in the integer portion of the result. If not set, the number of digits depends on the value being converted.

Parameters:
minIntegerDigits The new limit
    public void setMinIntegerDigits(int minIntegerDigits) {
        clearInitialState();
        this. = minIntegerDigits;
    }


    

Return the Locale to be used when parsing numbers. If this value is null, the Locale stored in the javax.faces.component.UIViewRoot for the current request will be utilized.

    public Locale getLocale() {
        if (this. == null) {
            this. =
                 getLocale(FacesContext.getCurrentInstance());
        }
        return (this.);
    }


    

Set the Locale to be used when parsing numbers. If set to null, the Locale stored in the javax.faces.component.UIViewRoot for the current request will be utilized.

Parameters:
locale The new Locale (or null)
    public void setLocale(Locale locale) {
        clearInitialState();
        this. = locale;
    }


    

Return the format pattern to be used when formatting and parsing numbers.

    public String getPattern() {
        return (this.);
    }


    

Set the format pattern to be used when formatting and parsing numbers. Valid values are those supported by java.text.DecimalFormat. An invalid value will cause a ConverterException when getAsObject() or getAsString() is called.

Parameters:
pattern The new format pattern
    public void setPattern(String pattern) {
        clearInitialState();
        this. = pattern;
    }


    

Return the number type to be used when formatting and parsing numbers. If not modified, the default type is number.

    public String getType() {
        return (this.);
    }


    

Set the number type to be used when formatting and parsing numbers. Valid values are currency, number, or percent. An invalid value will cause a ConverterException when getAsObject() or getAsString() is called.

Parameters:
type The new number style
    public void setType(String type) {
        clearInitialState();
        this. = type;
    }
    // ------------------------------------------------------- Converter Methods

    
    public Object getAsObject(FacesContext contextUIComponent component,
                              String value) {
        if (context == null || component == null) {
            throw new NullPointerException();
        }
        Object returnValue = null;
        NumberFormat parser = null;
        try {
            // If the specified value is null or zero-length, return null
            if (value == null) {
                return (null);
            }
            value = value.trim();
            if (value.length() < 1) {
                return (null);
            }
            // Identify the Locale to use for parsing
            Locale locale = getLocale(context);
            // Create and configure the parser to be used
            parser = getNumberFormat(locale);
            if ((( != null) && .length() != 0)
                 || "currency".equals()) {
                configureCurrency(parser);
            }
            parser.setParseIntegerOnly(isIntegerOnly());
            boolean groupSepChanged = false;
            // BEGIN HACK 4510618
            // This lovely bit of code is for a workaround in some
            // oddities in the JDK's parsing code.
            // See:  http://bugs.sun.com/view_bug.do?bug_id=4510618
            if (parser instanceof DecimalFormat) {
                DecimalFormat dParser = (DecimalFormatparser;
                // Take a small hit in performance to avoid a loss in
                // precision due to DecimalFormat.parse() returning Double
                ValueExpression ve = component.getValueExpression("value");
                if (ve != null) {
                    Class<?> expectedType = ve.getType(context.getELContext());
                    if (expectedType != null && expectedType.isAssignableFrom(BigDecimal.class)) {
                        dParser.setParseBigDecimal(true);
                    }
                }
                DecimalFormatSymbols symbols =
                      dParser.getDecimalFormatSymbols();
                if (symbols.getGroupingSeparator() == '\u00a0') {
                    groupSepChanged = true;
                    String tValue;
                    if (value.contains()) {
                        tValue = value.replace('\u00a0'' ');
                    } else {
                        tValue = value;
                    }
                    symbols.setGroupingSeparator(' ');
                    dParser.setDecimalFormatSymbols(symbols);
                    try {
                        return dParser.parse(tValue);
                    } catch (ParseException pe) {
                        if (groupSepChanged) {
                            symbols.setGroupingSeparator('\u00a0');
                            dParser.setDecimalFormatSymbols(symbols);
                        }
                    }
                }
            }
            // END HACK 4510618
            // Perform the requested parsing
            returnValue = parser.parse(value);
        } catch (ParseException e) {
            if ( != null) {
                throw new ConverterException(MessageFactory.getMessage(
                     contextvalue"#,##0.0#",
                     MessageFactory.getLabel(contextcomponent)), e);
            } else if (.equals("currency")) {
                throw new ConverterException(MessageFactory.getMessage(
                     contextvalue,
                     parser.format(99.99),
                     MessageFactory.getLabel(contextcomponent)), e);
            } else if (.equals("number")) {
                throw new ConverterException(MessageFactory.getMessage(
                     contextvalue,
                     parser.format(99),
                     MessageFactory.getLabel(contextcomponent)), e);
            } else if (.equals("percent")) {
                throw new ConverterException(MessageFactory.getMessage(
                     contextvalue,
                     parser.format(.75),
                     MessageFactory.getLabel(contextcomponent)), e);
            }
        } catch (Exception e) {
            throw new ConverterException(e);
        }
        return returnValue;
    }

    
    public String getAsString(FacesContext contextUIComponent component,
                              Object value) {
        if (context == null || component == null) {
            throw new NullPointerException();
        }
        try {
            // If the specified value is null, return a zero-length String
            if (value == null) {
                return "";
            }
            // If the incoming value is still a string, play nice
            // and return the value unmodified
            if (value instanceof String) {
                return (Stringvalue;
            }
            // Identify the Locale to use for formatting
            Locale locale = getLocale(context);
            // Create and configure the formatter to be used
            NumberFormat formatter =
                 getNumberFormat(locale);
            if ((( != null) && .length() != 0)
                 || "currency".equals()) {
                configureCurrency(formatter);
            }
            configureFormatter(formatter);
            // Perform the requested formatting
            return (formatter.format(value));
        } catch (ConverterException e) {
            throw new ConverterException(MessageFactory.getMessage(
                 contextvalue,
                 MessageFactory.getLabel(contextcomponent)), e);
        } catch (Exception e) {
            throw new ConverterException(MessageFactory.getMessage(
                 contextvalue,
                 MessageFactory.getLabel(contextcomponent)), e);
        }
    }
    // --------------------------------------------------------- Private Methods
    private static Class currencyClass;
    static {
        try {
             = Class.forName("java.util.Currency");
            // container's runtime is J2SE 1.4 or greater
        } catch (Exception ignored) {
        }
    }
    private static final Class[] GET_INSTANCE_PARAM_TYPES =
         new Class[]{String.class};


    

Override the formatting locale's default currency symbol with the specified currency code (specified via the "currencyCode" attribute) or currency symbol (specified via the "currencySymbol" attribute).

If both "currencyCode" and "currencySymbol" are present, "currencyCode" takes precedence over "currencySymbol" if the java.util.Currency class is defined in the container's runtime (that is, if the container's runtime is J2SE 1.4 or greater), and "currencySymbol" takes precendence over "currencyCode" otherwise.

If only "currencyCode" is given, it is used as a currency symbol if java.util.Currency is not defined.

 Example:
 

JDK "currencyCode" "currencySymbol" Currency symbol being displayed ----------------------------------------------------------------------- all --- --- Locale's default currency symbol

<1.4 EUR --- EUR >=1.4 EUR --- Locale's currency symbol for Euro

all --- \u20AC \u20AC

<1.4 EUR \u20AC \u20AC >=1.4 EUR \u20AC Locale's currency symbol for Euro

Parameters:
formatter The NumberFormatter to be configured
    private void configureCurrency(NumberFormat formatterthrows Exception {
        // Implementation copied from JSTL's FormatNumberSupport.setCurrency()
        String code = null;
        String symbol = null;
        if (( == null) && ( == null)) {
            return;
        }
        if (( != null) && ( != null)) {
            if ( != null)
                code = ;
            else
                symbol = ;
        } else if ( == null) {
            symbol = ;
        } else {
            if ( != null)
                code = ;
            else
                symbol = ;
        }
        if (code != null) {
            Object[] methodArgs = new Object[1];
            /*
            * java.util.Currency.getInstance()
            */
            Method m = .getMethod("getInstance",
                 );
            methodArgs[0] = code;
            Object currency = m.invoke(nullmethodArgs);
            /*
            * java.text.NumberFormat.setCurrency()
            */
            Class[] paramTypes = new Class[1];
            paramTypes[0] = ;
            Class numberFormatClass = Class.forName("java.text.NumberFormat");
            m = numberFormatClass.getMethod("setCurrency"paramTypes);
            methodArgs[0] = currency;
            m.invoke(formattermethodArgs);
        } else {
            /*
            * Let potential ClassCastException propagate up (will almost
            * never happen)
            */
            DecimalFormat df = (DecimalFormatformatter;
            DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
            dfs.setCurrencySymbol(symbol);
            df.setDecimalFormatSymbols(dfs);
        }
    }


    

Configure the specified NumberFormat based on the formatting properties that have been set.

Parameters:
formatter The NumberFormat instance to configure
    private void configureFormatter(NumberFormat formatter) {
        formatter.setGroupingUsed();
        if (isMaxIntegerDigitsSet()) {
            formatter.setMaximumIntegerDigits();
        }
        if (isMinIntegerDigitsSet()) {
            formatter.setMinimumIntegerDigits();
        }
        if (isMaxFractionDigitsSet()) {
            formatter.setMaximumFractionDigits();
        }
        if (isMinFractionDigitsSet()) {
            formatter.setMinimumFractionDigits();
        }
    }
    private boolean isMaxIntegerDigitsSet() {
        return ( != null);
    }
    private boolean isMinIntegerDigitsSet() {
        return ( != null);
    }
    private boolean isMaxFractionDigitsSet() {
        return ( != null);
    }
    private boolean isMinFractionDigitsSet() {
        return ( != null);
    }


    

Return the Locale we will use for localizing our formatting and parsing processing.

Parameters:
context The javax.faces.context.FacesContext for the current request
    private Locale getLocale(FacesContext context) {
        // PENDING(craigmcc) - JSTL localization context?
        Locale locale = this.;
        if (locale == null) {
            locale = context.getViewRoot().getLocale();
        }
        return (locale);
    }


    

Return a NumberFormat instance to use for formatting and parsing in this Converter.

Parameters:
locale The Locale used to select formatting and parsing conventions
Throws:
ConverterException if no instance can be created
    private NumberFormat getNumberFormat(Locale locale) {
        if ( == null &&  == null) {
            throw new IllegalArgumentException("Either pattern or type must" +
                 " be specified.");
        }
        // PENDING(craigmcc) - Implement pooling if needed for performance?
        // If pattern is specified, type is ignored
        if ( != null) {
            DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
            return (new DecimalFormat(symbols));
        }
        // Create an instance based on the specified type
        else if (.equals("currency")) {
            return (NumberFormat.getCurrencyInstance(locale));
        } else if (.equals("number")) {
            return (NumberFormat.getNumberInstance(locale));
        } else if (.equals("percent")) {
            return (NumberFormat.getPercentInstance(locale));
        } else {
            // PENDING(craigmcc) - i18n
            throw new ConverterException
                 (new IllegalArgumentException());
        }
    }
    // ----------------------------------------------------- StateHolder Methods
    public Object saveState(FacesContext context) {
        if (context == null) {
            throw new NullPointerException();
        }
        if (!initialStateMarked()) {
            Object values[] = new Object[11];
            values[0] = ;
            values[1] = ;
            values[2] = ;
            values[3] = ;
            values[4] = ;
            values[5] = ;
            values[6] = ;
            values[7] = ;
            values[8] = ;
            values[9] = ;
            values[10] = ;
            return (values);
        }
        return null;
    }
    public void restoreState(FacesContext contextObject state) {
        if (context == null) {
            throw new NullPointerException();
        }
        if (state != null) {
            Object values[] = (Object[]) state;
             = (Stringvalues[0];
             = (Stringvalues[1];
             = (Booleanvalues[2];
             = (Booleanvalues[3];
             = (Integervalues[4];
             = (Integervalues[5];
             = (Integervalues[6];
             = (Integervalues[7];
             = (Localevalues[8];
             = (Stringvalues[9];
             = (Stringvalues[10];
        }
    }
    private boolean transientFlag = false;
    public boolean isTransient() {
        return ();
    }
    public void setTransient(boolean transientFlag) {
        this. = transientFlag;
    }
    private boolean initialState;
    public void markInitialState() {
         = true;
    }
    public boolean initialStateMarked() {
        return ;
    }
    public void clearInitialState() {
         = false;
    }
New to GrepCode? Check out our FAQ X