Author: oheger Date: Wed Oct 30 20:17:50 2013 New Revision: 1537267 URL: http://svn.apache.org/r1537267 Log: Generified locale converters.
The locale converters now provide a convert method with a type parameter defining the target conversion type. This commit also fixes [BEANUTILS-448] and [BEANUTILS-449] because the conversion result is now explicitly checked whether it is compatible with the desired target type. This is a change in the behavior of the locale converters; therefore some tests had to be adapted. Modified: commons/proper/beanutils/branches/java5/src/main/java/org/apache/commons/beanutils/locale/BaseLocaleConverter.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigDecimalLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigIntegerLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ByteLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DoubleLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/FloatLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/IntegerLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/LongLocaleConverterTestCase.java commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ShortLocaleConverterTestCase.java Modified: commons/proper/beanutils/branches/java5/src/main/java/org/apache/commons/beanutils/locale/BaseLocaleConverter.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/main/java/org/apache/commons/beanutils/locale/BaseLocaleConverter.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/main/java/org/apache/commons/beanutils/locale/BaseLocaleConverter.java (original) +++ commons/proper/beanutils/branches/java5/src/main/java/org/apache/commons/beanutils/locale/BaseLocaleConverter.java Wed Oct 30 20:17:50 2013 @@ -17,13 +17,14 @@ package org.apache.commons.beanutils.locale; +import java.text.ParseException; +import java.util.Locale; + import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.text.ParseException; -import java.util.Locale; - /** * <p>The base class for all standart type locale-sensitive converters. @@ -158,7 +159,7 @@ public abstract class BaseLocaleConverte /** * Convert the specified locale-sensitive input object into an output object. - * The default pattern is used for the convertion. + * The default pattern is used for the conversion. * * @param value The input object to be converted * @return The converted value @@ -174,7 +175,7 @@ public abstract class BaseLocaleConverte * Convert the specified locale-sensitive input object into an output object. * * @param value The input object to be converted - * @param pattern The pattern is used for the convertion + * @param pattern The pattern is used for the conversion * @return The converted value * * @exception ConversionException if conversion cannot be performed @@ -188,6 +189,7 @@ public abstract class BaseLocaleConverte * Convert the specified locale-sensitive input object into an output object of the * specified type. The default pattern is used for the convertion. * + * @param <T> The desired target type of the conversion * @param type Data type to which this value should be converted * @param value The input object to be converted * @return The converted value @@ -195,7 +197,7 @@ public abstract class BaseLocaleConverte * @exception ConversionException if conversion cannot be performed * successfully */ - public Object convert(Class type, Object value) { + public <T> T convert(Class<T> type, Object value) { return convert(type, value, null); } @@ -203,6 +205,7 @@ public abstract class BaseLocaleConverte * Convert the specified locale-sensitive input object into an output object of the * specified type. * + * @param <T> The desired target type of the conversion * @param type Data is type to which this value should be converted * @param value is the input object to be converted * @param pattern is the pattern is used for the conversion; if null is @@ -213,10 +216,11 @@ public abstract class BaseLocaleConverte * @exception ConversionException if conversion cannot be performed * successfully */ - public Object convert(Class type, Object value, String pattern) { + public <T> T convert(Class<T> type, Object value, String pattern) { + Class<T> targetType = ConvertUtils.primitiveToWrapper(type); if (value == null) { if (useDefault) { - return (defaultValue); + return getDefaultAs(targetType); } else { // symmetric beanutils function allows null // so do not: throw new ConversionException("No value specified"); @@ -227,13 +231,13 @@ public abstract class BaseLocaleConverte try { if (pattern != null) { - return parse(value, pattern); + return checkConversionResult(targetType, parse(value, pattern)); } else { - return parse(value, this.pattern); + return checkConversionResult(targetType, parse(value, this.pattern)); } } catch (Exception e) { if (useDefault) { - return (defaultValue); + return getDefaultAs(targetType); } else { if (e instanceof ConversionException) { throw (ConversionException)e; @@ -242,4 +246,44 @@ public abstract class BaseLocaleConverte } } } + + /** + * Returns the default object specified for this converter cast for the + * given target type. If the default value is not conform to the given type, + * an exception is thrown. + * + * @param <T> the desired target type + * @param type the target class of the conversion + * @return the default value in the given target type + * @throws ConversionException if the default object is not compatible with + * the target type + */ + private <T> T getDefaultAs(Class<T> type) { + return checkConversionResult(type, defaultValue); + } + + /** + * Checks whether the result of a conversion is conform to the specified + * target type. If this is the case, the passed in result object is cast to + * the correct target type. Otherwise, an exception is thrown. + * + * @param <T> the desired result type + * @param type the target class of the conversion + * @param result the conversion result object + * @return the result cast to the target class + * @throws ConversionException if the result object is not compatible with + * the target type + */ + private static <T> T checkConversionResult(Class<T> type, Object result) { + if (type == null) { + // in this case we cannot do much; the result object is returned + @SuppressWarnings("unchecked") + T temp = (T) result; + return temp; + } + if (type.isInstance(result)) { + return type.cast(result); + } + throw new ConversionException("Unsupported target type: " + type); + } } Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigDecimalLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigDecimalLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigDecimalLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigDecimalLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -103,9 +103,9 @@ public class BigDecimalLocaleConverterTe // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a BigDecimal. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Double.class, localizedDecimalValue, localizedDecimalPattern, expectedValue); + //convertValueToType(converter, "(B)", Double.class, localizedDecimalValue, localizedDecimalPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigIntegerLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigIntegerLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigIntegerLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/BigIntegerLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -19,6 +19,8 @@ package org.apache.commons.beanutils.loc import java.math.BigInteger; +import org.apache.commons.beanutils.ConversionException; + /** * Test Case for the BigIntegerLocaleConverter class. * @@ -102,9 +104,9 @@ public class BigIntegerLocaleConverterTe // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a BigInteger. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); + //convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ @@ -259,7 +261,19 @@ public class BigIntegerLocaleConverterTe } - + /** + * Tries to convert to an unsupported type. This tests behavior of the base + * class. All locale converters should react in the same way. + */ + public void testUnsupportedType() { + converter = new BigIntegerLocaleConverter(); + try { + converter.convert(getClass(), "test", null); + fail("Unsupported type not detected!"); + } catch (ConversionException cex) { + // expected result + } + } } Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ByteLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ByteLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ByteLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ByteLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -108,9 +108,9 @@ public class ByteLocaleConverterTestCase // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a Byte. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); + //convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -17,15 +17,14 @@ package org.apache.commons.beanutils.locale.converters; -import java.text.SimpleDateFormat; -import java.text.ParseException; import java.text.DateFormatSymbols; - +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Locale; import org.apache.commons.beanutils.ConversionException; -import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Test Case for the DateLocaleConverter class. @@ -239,9 +238,9 @@ public class DateLocaleConverterTestCase // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a Date. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", String.class, localizedDateValue, localizedDatePattern, expectedValue); + //convertValueToType(converter, "(B)", String.class, localizedDateValue, localizedDatePattern, expectedValue); // ------------- Construct with non-localized pattern ------------ Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DoubleLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DoubleLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DoubleLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/DoubleLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -102,9 +102,9 @@ public class DoubleLocaleConverterTestCa // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a Double. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Integer.class, localizedDecimalValue, localizedDecimalPattern, expectedValue); + //convertValueToType(converter, "(B)", Integer.class, localizedDecimalValue, localizedDecimalPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/FloatLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/FloatLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/FloatLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/FloatLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -107,9 +107,9 @@ public class FloatLocaleConverterTestCas // // BaseLocaleConverter completely ignores the type - so even if we specify // Float.class here it still returns a Float. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Integer.class, localizedDecimalValue, localizedDecimalPattern, expectedValue); + //convertValueToType(converter, "(B)", Integer.class, localizedDecimalValue, localizedDecimalPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/IntegerLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/IntegerLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/IntegerLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/IntegerLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -101,9 +101,9 @@ public class IntegerLocaleConverterTestC // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a Integer. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); + //convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ @@ -272,6 +272,15 @@ public class IntegerLocaleConverterTestC assertEquals("Convert Long", value, converter.convert(new Long(value.intValue()))); } - + /** + * Tests whether a conversion to a primitive type can be performed. + */ + public void testToPrimitiveType() { + converter = new IntegerLocaleConverter(); + Integer value = 20131028; + Class<Integer> target = Integer.TYPE; + int result = converter.convert(target, (Object) value.toString()); + assertEquals("Wrong result", value.intValue(), result); + } } Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/LongLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/LongLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/LongLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/LongLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -101,9 +101,9 @@ public class LongLocaleConverterTestCase // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a Long. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); + //convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); // ------------- Construct with non-localized pattern ------------ Modified: commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ShortLocaleConverterTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ShortLocaleConverterTestCase.java?rev=1537267&r1=1537266&r2=1537267&view=diff ============================================================================== --- commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ShortLocaleConverterTestCase.java (original) +++ commons/proper/beanutils/branches/java5/src/test/java/org/apache/commons/beanutils/locale/converters/ShortLocaleConverterTestCase.java Wed Oct 30 20:17:50 2013 @@ -101,9 +101,9 @@ public class ShortLocaleConverterTestCas // // BaseLocaleConverter completely ignores the type - so even if we specify // Double.class here it still returns a Short. - // **** SHOULD IMPLEMENT THIS BEHAVIOUR **** + // **** This has been changed due to BEANUTILS-449 **** // ************************************************************************** - convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); + //convertValueToType(converter, "(B)", Double.class, localizedIntegerValue, localizedIntegerPattern, expectedValue); // ------------- Construct with non-localized pattern ------------