Need help with localed converter for BigDecimal
bussard Oct 21, 2010 11:20 AMI 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 ?