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 ?