0 Replies Latest reply on Oct 21, 2010 11:20 AM by bussard

    Need help with localed converter for BigDecimal

    bussard

      I was searching in many forums for I way to use localed <f:convertNumber> with BigDecimal and choose this old topic's approach.


      After some work I created this:


      import java.math.BigDecimal;
      import java.util.Locale;
      
      import javax.faces.component.UIComponent;
      import javax.faces.context.FacesContext;
      import javax.faces.convert.NumberConverter;
      
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.faces.Converter;
      import org.jboss.seam.annotations.intercept.BypassInterceptors;
      
      /**
       * Converts a Double or Long value provided by standard jsf number converter to
       * a BigDecimal value
       * 
       * To get a locale-sensitive converter, java.text.NumberFormat is used (through
       * javax.faces.convert.NumberConverter). The parsing done by
       * java.math.BigDecimal is not affected by locale. See
       * javax.faces.convert.BigDecimalConverter
       * 
       */
      @Name("bigDecimalConverter")
      @BypassInterceptors
      @Converter
      public class BigDecimalConverter extends NumberConverter {
           private static final String MIN_FRACTION_DIGITS = "minFractionDigits";
           private static final String MAX_FRACTION_DIGITS = "maxFractionDigits";
           private static final String LOCALE = "locale";
      
           @Override
           public Object getAsObject(FacesContext context, UIComponent component,
                     String string) {
      
                Object ret = super.getAsObject(context, component, string);
                if (ret != null) {
                     return new BigDecimal(ret.toString());
                }
                return null;
           }
      
           public String getAsString(FacesContext context, UIComponent component,
                     Object value) {
      
                this.setMinFractionDigits(getMinFractionDigits(component));
                this.setMaxFractionDigits(getMaxFractionDigits(component));
                this.setLocale(getLocale(component));
      
                return super.getAsString(context, component, value);
           }
      
           private int getMinFractionDigits(UIComponent component) {
                Object att = component.getAttributes().get(MIN_FRACTION_DIGITS);
                if (att == null) {
                     return 0;
                } else {
                     return Integer.parseInt((String) component.getAttributes().get(
                               MIN_FRACTION_DIGITS));
                }
           }
      
           private int getMaxFractionDigits(UIComponent component) {
                Object att = component.getAttributes().get(MAX_FRACTION_DIGITS);
                if (att == null) {
                     return 0;
                } else {
                     return Integer.parseInt((String) component.getAttributes().get(
                               MAX_FRACTION_DIGITS));
                }
           }
      
           private Locale getLocale(UIComponent component) {
                Object att = component.getAttributes().get(LOCALE);
                if (att == null) {
                     return null;
                } else {
                     String language;
                     String country = "";
      
                     String strLocale = (String) component.getAttributes().get(LOCALE);
      
                     if (strLocale.indexOf("_") > 0) {
                          String[] fld = strLocale.split("_");
                          language = fld[0];
                          country = fld[1];
                     } else
                          language = strLocale;
      
                     return new Locale(language, country);
                }
           }
      
      }
      


      It's supposed to be used like this :


      <h:inputText id="idImputText" 
             value="#{entityHome.instance.instanceValue}"
              size="25"
              style="text-align: right;" >
          <f:converter converterId="bigDecimalConverter"/>
          <f:attribute name="minFractionDigits" value="2"/>
          <f:attribute name="maxFractionDigits" value="2"/>
          <f:attribute name="locale" value="pt_BR"/>
          
          <a:support event="onblur" reRender="valorOrcadoField" bypassUpdates="true" ajaxSingle="true"/>
      </h:inputText>
      


      Are there other less verbose and more elegant ways to do this ?