StringToBigDecimal converter bug

Hello, I’m trying to use the
StringToBigDecimalConverter
that was added in Vaadin 7.2 but it seems that is bugged.

It takes a
String
as input and should return a
BigDecimal
as output.
Looking at the code I see that it extends from
AbstractStringToNumberConverter
.
It calls the parent method
convertToNumber
with as targetType
BigDecimal
.

I see that the targetType that is given is not even used in the method at all, which makes no sense.
Next I see that the
String
that is passed is converted to a
Number
using the default Java NumberFormat parse method.
This correctly returns a
Number
, which is the passed to the subclass that
tries to cast that Number to a BigDecimal
and return that. This of course will never work, as a Number cannot always be casted to BigDecimal and so it throws a ClassCastException when used in some cases (when the NumberFormat.parse() returns a Long or a Double for example)

Instead of doing this:

@Override
public BigDecimal convertToModel(String value, Class<? extends BigDecimal> targetType, Locale locale) throws com.vaadin.data.util.converter.Converter.ConversionException {
    return (BigDecimal) convertToNumber(value, BigDecimal.class, locale);
}

StringToBigDecimalConverter should instead do something like this:

@Override
public BigDecimal convertToModel(String value, Class<? extends BigDecimal> targetType, Locale locale) throws ConversionException {
    return new BigDecimal(convertToNumber(value, BigDecimal.class, locale).doubleValue());
}

Hi,

The overridden getFormat() method in StringToBigDecimalConverter sets setParseBigDecimal() for the NumberFormat if it is an instance of DecimalFormat. This makes the parse() method always return a BigDecimal instance which makes the cast in convertToModel work.

However, it is true that if super.getFormat() (which is to say, NumberFormat.getNumberInstance()) returns something else than a DecimalFormat then indeed the cast may fail. It is quite fragile design to count on this not happening and it should probably be fixed to be more robust, but out of interest, did you stumble upon a real-world scenario where this failed?

Your proposed fix has the problem that it truncates precision to ~16 significant digits which is, admittedly, probably never a problem in the real world.