Uploaded image for project: 'Commons BeanUtils'
  1. Commons BeanUtils
  2. BEANUTILS-282

BigDecimalLocaleConverter returns Long object

    XMLWordPrintableJSON

Details

    Description

      BigDecimalLocaleConverter returns Long object instead of BigDecimal when no decimal places are in the parsed number.
      Problem is in the method DecimalLocaleConverter.parse(Object, String) which uses DecimalFormat.getInstance(locale).parse(String). The getInstance method is factory method from NumberFormat and not DecimalFormat, so there is no guarantee of returned type.

      Here is the sample which shows the problem:

      import java.math.BigDecimal;
      import java.text.NumberFormat;
      import java.util.Locale;

      import org.apache.commons.beanutils.locale.converters.BigDecimalLocaleConverter;

      public class Test {

      public static void main(String args[])

      { Locale tmpLoc = new Locale("de","AT"); NumberFormat nf = NumberFormat.getNumberInstance(tmpLoc); String tmpNr = nf.format(new BigDecimal("5")); BigDecimalLocaleConverter tmpBdlc = new BigDecimalLocaleConverter(tmpLoc); Object tmpConverted = tmpBdlc.convert(tmpNr); System.out.println("String value: " + tmpNr); System.out.println("Number value: " + tmpConverted); System.out.println(tmpConverted==null?"No class":"Class: " + tmpConverted.getClass()); }

      }

      Output is:
      String value: 5
      Number value: 5
      Class: class java.lang.Long

      Correct handling is implemented e.g. in BigDecimalValidator class of commons-validator package. It uses an additional method processParsedValue to convert number to the right type:

      /**

      • Convert the parsed value to a <code>BigDecimal</code>.
      • @param value The parsed <code>Number</code> object created.
      • @param formatter The Format used to parse the value with.
      • @return The parsed <code>Number</code> converted to a
      • <code>BigDecimal</code>.
        */
        protected Object processParsedValue(Object value, Format formatter) {
        BigDecimal decimal = null;
        if (value instanceof Long) { decimal = BigDecimal.valueOf(((Long)value).longValue()); }

        else

        { decimal = new BigDecimal(value.toString()); }

      int scale = determineScale((NumberFormat)formatter);
      if (scale >= 0)

      { decimal = decimal.setScale(scale, BigDecimal.ROUND_DOWN); }

      return decimal;
      }

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              kwart Josef Cacek
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: