Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,9 @@ protected Object parse(final Object value, final String pattern) throws ParseExc
throw new ConversionException("Suplied number is not of type BigDecimal: " + result);
}
}

@Override
protected boolean isParseBigDecimal() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.commons.beanutils.locale.converters;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.Locale;
Expand Down Expand Up @@ -176,6 +177,9 @@ protected Object parse(final Object value, final String pattern) throws ParseExc
if (result == null || result instanceof BigInteger) {
return result;
}
if (result instanceof BigDecimal) {
return ((BigDecimal) result).toBigInteger();
}
if (result instanceof Number) {
return BigInteger.valueOf(((Number) result).longValue());
}
Expand All @@ -185,4 +189,9 @@ protected Object parse(final Object value, final String pattern) throws ParseExc
throw new ConversionException("Suplied number is not of type BigInteger: " + result);
}
}

@Override
protected boolean isParseBigDecimal() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ public DecimalLocaleConverter(final Object defaultValue, final Locale locale, fi
* @throws org.apache.commons.beanutils.ConversionException if conversion cannot be performed successfully.
* @throws ParseException if an error occurs parsing a String to a Number.
*/
/**
* Tests whether the underlying {@link DecimalFormat} should parse into a {@link java.math.BigDecimal} so that magnitude and precision are preserved.
* Subclasses that build {@link java.math.BigInteger} or {@link java.math.BigDecimal} values override this to return {@code true}; the narrowing converters
* keep the default {@code Long} / {@code Double} result.
*
* @return {@code true} to parse into a {@link java.math.BigDecimal}, {@code false} otherwise.
* @since 1.11.1
*/
protected boolean isParseBigDecimal() {
return false;
}

@Override
protected Object parse(final Object value, final String pattern) throws ParseException {
if (value instanceof Number) {
Expand All @@ -188,6 +200,7 @@ protected Object parse(final Object value, final String pattern) throws ParseExc
// representation, each call to getInstance actually returns a new
// object.
final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(locale);
formatter.setParseBigDecimal(isParseBigDecimal());
// if some constructors default pattern to null, it makes only sense
// to handle null pattern gracefully
if (pattern != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,13 @@ public void testConstructorMain() {

}

/**
* Test that a value beyond {@code double} precision is preserved instead of being rounded to a lossy {@code 1.0E+19}.
*/
public void testConvertLargeValueKeepsPrecision() {
converter = new BigDecimalLocaleConverter();
convertValueNoPattern(converter, "9999999999999999999", new BigDecimal("9999999999999999999"));
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ public void testConstructorMain() {

}

/**
* Test that a value beyond {@code long} range keeps its full magnitude instead of being clamped to {@code Long.MAX_VALUE}.
*/
public void testConvertLargeValueKeepsMagnitude() {
converter = new BigIntegerLocaleConverter();
convertValueNoPattern(converter, "9999999999999999999", new BigInteger("9999999999999999999"));
convertValueNoPattern(converter, "123456789012345678901234567890", new BigInteger("123456789012345678901234567890"));
}

/**
* Tries to convert to an unsupported type. This tests behavior of the base
* class. All locale converters should react in the same way.
Expand Down
Loading