Author: niallp Date: Wed May 23 17:18:01 2007 New Revision: 541122 URL: http://svn.apache.org/viewvc?view=rev&rev=541122 Log: Improve exception error messages and add Calendar --> Long conversion
Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/AbstractConverter.java jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/DateTimeConverter.java jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/NumberConverter.java jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/converters/NumberConverterTestBase.java Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/AbstractConverter.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/AbstractConverter.java?view=diff&rev=541122&r1=541121&r2=541122 ============================================================================== --- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/AbstractConverter.java (original) +++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/AbstractConverter.java Wed May 23 17:18:01 2007 @@ -404,7 +404,9 @@ } else { typeName = type.getName(); } - if (typeName.startsWith("java.lang.")) { + if (typeName.startsWith("java.lang.") || + typeName.startsWith("java.util.") || + typeName.startsWith("java.math.")) { typeName = typeName.substring("java.lang.".length()); } else if (typeName.startsWith(PACKAGE)) { typeName = typeName.substring(PACKAGE.length()); Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/DateTimeConverter.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/DateTimeConverter.java?view=diff&rev=541122&r1=541121&r2=541122 ============================================================================== --- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/DateTimeConverter.java (original) +++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/DateTimeConverter.java Wed May 23 17:18:01 2007 @@ -281,12 +281,14 @@ * Otherwise the default <code>DateFormat</code> for the default locale * (and <i>style</i> if configured) will be used. * - * @param type Data type to which this value should be converted. + * @param targetType Data type to which this value should be converted. * @param value The input value to be converted. * @return The converted value. * @throws Exception if conversion cannot be performed successfully */ - protected Object convertToType(Class type, Object value) throws Exception { + protected Object convertToType(Class targetType, Object value) throws Exception { + + Class sourceType = value.getClass(); // Handle java.sql.Timestamp if (value instanceof java.sql.Timestamp) { @@ -299,51 +301,51 @@ long timeInMillis = ((timestamp.getTime() / 1000) * 1000); timeInMillis += timestamp.getNanos() / 1000000; // ---------------------- JDK 1.3 Fix ---------------------- - return toDate(type, timeInMillis); + return toDate(targetType, timeInMillis); } // Handle Date (includes java.sql.Date & java.sql.Time) if (value instanceof Date) { Date date = (Date)value; - return toDate(type, date.getTime()); + return toDate(targetType, date.getTime()); } // Handle Calendar if (value instanceof Calendar) { Calendar calendar = (Calendar)value; - return toDate(type, calendar.getTime().getTime()); + return toDate(targetType, calendar.getTime().getTime()); } // Handle Long if (value instanceof Long) { Long longObj = (Long)value; - return toDate(type, longObj.longValue()); + return toDate(targetType, longObj.longValue()); } // Convert all other types to String & handle String stringValue = value.toString().trim(); if (stringValue.length() == 0) { - return handleMissing(type); + return handleMissing(targetType); } // Parse the Date/Time if (useLocaleFormat) { Calendar calendar = null; if (patterns != null && patterns.length > 0) { - calendar = parse(type, stringValue); + calendar = parse(sourceType, targetType, stringValue); } else { DateFormat format = getFormat(locale, timeZone); - calendar = parse(type, stringValue, format); + calendar = parse(sourceType, targetType, stringValue, format); } - if (Calendar.class.isAssignableFrom(type)) { + if (Calendar.class.isAssignableFrom(targetType)) { return calendar; } else { - return toDate(type, calendar.getTime().getTime()); + return toDate(targetType, calendar.getTime().getTime()); } } // Default String conversion - return toDate(type, stringValue); + return toDate(targetType, stringValue); } @@ -508,18 +510,19 @@ /** * Parse a String date value using the set of patterns. * - * @param type The type to convert the value to + * @param sourceType The type of the value being converted + * @param targetType The type to convert the value to. * @param value The String date value. - * @param type The type to convert the value to. + * * @return The converted Date object. * @throws Exception if an error occurs parsing the date. */ - private Calendar parse(Class type, String value) throws Exception { + private Calendar parse(Class sourceType, Class targetType, String value) throws Exception { Exception firstEx = null; for (int i = 0; i < patterns.length; i++) { try { DateFormat format = getFormat(patterns[i]); - Calendar calendar = parse(type, value, format); + Calendar calendar = parse(sourceType, targetType, value, format); return calendar; } catch (Exception ex) { if (firstEx == null) { @@ -528,7 +531,7 @@ } } if (patterns.length > 1) { - throw new ConversionException("Error converting String to '" + toString(type) + throw new ConversionException("Error converting '" + toString(sourceType) + "' to '" + toString(targetType) + "' using patterns '" + displayPatterns + "'"); } else { throw firstEx; @@ -539,19 +542,21 @@ * Parse a String into a <code>Calendar</code> object * using the specified <code>DateFormat</code>. * - * @param type The type to convert the value to + * @param sourceType The type of the value being converted + * @param targetType The type to convert the value to * @param value The String date value. * @param format The DateFormat to parse the String value. + * * @return The converted Calendar object. * @throws ConversionException if the String cannot be converted. */ - private Calendar parse(Class type, String value, DateFormat format) { + private Calendar parse(Class sourceType, Class targetType, String value, DateFormat format) { logFormat("Parsing", format); format.setLenient(false); ParsePosition pos = new ParsePosition(0); Date parsedDate = format.parse(value, pos); // ignore the result (use the Calendar) if (pos.getErrorIndex() >= 0 || pos.getIndex() != value.length() || parsedDate == null) { - String msg = "Error converting String to '" + toString(type) + "'"; + String msg = "Error converting '" + toString(sourceType) + "' to '" + toString(targetType) + "'"; if (format instanceof SimpleDateFormat) { msg += " using pattern '" + ((SimpleDateFormat)format).toPattern() + "'"; } Modified: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/NumberConverter.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/NumberConverter.java?view=diff&rev=541122&r1=541121&r2=541122 ============================================================================== --- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/NumberConverter.java (original) +++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/converters/NumberConverter.java Wed May 23 17:18:01 2007 @@ -16,6 +16,7 @@ */ package org.apache.commons.beanutils.converters; +import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.math.BigDecimal; @@ -226,48 +227,54 @@ * Convert the input object into a Number object of the * specified type. * - * @param type Data type to which this value should be converted. + * @param targetType Data type to which this value should be converted. * @param value The input value to be converted. * @return The converted value. * @throws Throwable if an error occurs converting to the specified type */ - protected Object convertToType(Class type, Object value) throws Throwable { + protected Object convertToType(Class targetType, Object value) throws Throwable { + Class sourceType = value.getClass(); // Handle Number if (value instanceof Number) { - return toNumber(type, (Number)value); + return toNumber(sourceType, targetType, (Number)value); } // Handle Boolean if (value instanceof Boolean) { - return toNumber(type, ((Boolean)value).booleanValue() ? ONE : ZERO); + return toNumber(sourceType, targetType, ((Boolean)value).booleanValue() ? ONE : ZERO); } // Handle Date --> Long - if (value instanceof Date && Long.class.equals(type)) { + if (value instanceof Date && Long.class.equals(targetType)) { return new Long(((Date)value).getTime()); } + // Handle Calendar --> Long + if (value instanceof Calendar && Long.class.equals(targetType)) { + return new Long(((Calendar)value).getTime().getTime()); + } + // Convert all other types to String & handle String stringValue = value.toString().trim(); if (stringValue.length() == 0) { - return handleMissing(type); + return handleMissing(targetType); } // Convert/Parse a String Number number = null; if (useLocaleFormat) { NumberFormat format = getFormat(); - number = parse(type, stringValue, format); + number = parse(sourceType, targetType, stringValue, format); } else { if (log().isDebugEnabled()) { log().debug(" No NumberFormat, using default conversion"); } - number = toNumber(type, stringValue); + number = toNumber(sourceType, targetType, stringValue); } // Ensure the correct number type is returned - return toNumber(type, number); + return toNumber(sourceType, targetType, number); } @@ -286,81 +293,82 @@ * <li><code>java.math.BigDecimal</code></li> * <li><code>java.math.BigInteger</code></li> * </ul> - * - * @param type The Number type to convert to + * @param sourceType The type being converted from + * @param targetType The Number type to convert to * @param value The Number to convert. + * * @return The converted value. */ - private Number toNumber(Class type, Number value) { + private Number toNumber(Class sourceType, Class targetType, Number value) { // Correct Number type already - if (type.equals(value.getClass())) { + if (targetType.equals(value.getClass())) { return value; } // Byte - if (type.equals(Byte.class)) { + if (targetType.equals(Byte.class)) { long longValue = value.longValue(); if (longValue > Byte.MAX_VALUE) { - throw new ConversionException("Value '" + value + "' is too large for " - + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too large for " + toString(targetType)); } if (longValue < Byte.MIN_VALUE) { - throw new ConversionException("Value '" + value + "' is too small " - + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too small " + toString(targetType)); } return new Byte(value.byteValue()); } // Short - if (type.equals(Short.class)) { + if (targetType.equals(Short.class)) { long longValue = value.longValue(); if (longValue > Short.MAX_VALUE) { - throw new ConversionException("Value '" + value + "' is too large for " - + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too large for " + toString(targetType)); } if (longValue < Short.MIN_VALUE) { - throw new ConversionException("Value '" + value + "' is too small " - + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too small " + toString(targetType)); } return new Short(value.shortValue()); } // Integer - if (type.equals(Integer.class)) { + if (targetType.equals(Integer.class)) { long longValue = value.longValue(); if (longValue > Integer.MAX_VALUE) { - throw new ConversionException("Value '" + value + "' is too large for " - + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too large for " + toString(targetType)); } if (longValue < Integer.MIN_VALUE) { - throw new ConversionException("Value '" + value + "' is too small " - + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too small " + toString(targetType)); } return new Integer(value.intValue()); } // Long - if (type.equals(Long.class)) { + if (targetType.equals(Long.class)) { return new Long(value.longValue()); } // Float - if (type.equals(Float.class)) { + if (targetType.equals(Float.class)) { if (value.doubleValue() > Float.MAX_VALUE) { - throw new ConversionException("Value '" + value - + "' is too large for " + toString(type)); + throw new ConversionException(toString(sourceType) + " value '" + value + + "' is too large for " + toString(targetType)); } return new Float(value.floatValue()); } // Double - if (type.equals(Double.class)) { + if (targetType.equals(Double.class)) { return new Double(value.doubleValue()); } // BigDecimal - if (type.equals(BigDecimal.class)) { + if (targetType.equals(BigDecimal.class)) { if (value instanceof Float || value instanceof Double) { return new BigDecimal(value.toString()); } else if (value instanceof BigInteger) { @@ -371,7 +379,7 @@ } // BigInteger - if (type.equals(BigInteger.class)) { + if (targetType.equals(BigInteger.class)) { if (value instanceof BigDecimal) { return ((BigDecimal)value).toBigInteger(); } else { @@ -380,7 +388,7 @@ } String msg = toString(getClass()) + " cannot handle conversion to '" - + toString(type) + "'"; + + toString(targetType) + "'"; if (log().isWarnEnabled()) { log().warn(" " + msg); } @@ -402,55 +410,56 @@ * <li><code>java.math.BigDecimal</code></li> * <li><code>java.math.BigInteger</code></li> * </ul> - * - * @param type The Number type to convert to + * @param sourceType The type being converted from + * @param targetType The Number type to convert to * @param value The String value to convert. + * * @return The converted Number value. */ - private Number toNumber(Class type, String value) { + private Number toNumber(Class sourceType, Class targetType, String value) { // Byte - if (type.equals(Byte.class)) { + if (targetType.equals(Byte.class)) { return new Byte(value); } // Short - if (type.equals(Short.class)) { + if (targetType.equals(Short.class)) { return new Short(value); } // Integer - if (type.equals(Integer.class)) { + if (targetType.equals(Integer.class)) { return new Integer(value); } // Long - if (type.equals(Long.class)) { + if (targetType.equals(Long.class)) { return new Long(value); } // Float - if (type.equals(Float.class)) { + if (targetType.equals(Float.class)) { return new Float(value); } // Double - if (type.equals(Double.class)) { + if (targetType.equals(Double.class)) { return new Double(value); } // BigDecimal - if (type.equals(BigDecimal.class)) { + if (targetType.equals(BigDecimal.class)) { return new BigDecimal(value); } // BigInteger - if (type.equals(BigInteger.class)) { + if (targetType.equals(BigInteger.class)) { return new BigInteger(value); } - String msg = toString(getClass()) - + " cannot handle conversion from String to '" + toString(type) + "'"; + String msg = toString(getClass()) + " cannot handle conversion from '" + + toString(sourceType) + "' to '" + toString(targetType) + "'"; if (log().isWarnEnabled()) { log().warn(" " + msg); } @@ -499,18 +508,19 @@ /** * Convert a String into a <code>Number</code> object. - * - * @param type The type to convert the value to + * @param sourceType TODO + * @param targetType The type to convert the value to * @param value The String date value. * @param format The NumberFormat to parse the String value. + * * @return The converted Number object. * @throws ConversionException if the String cannot be converted. */ - private Number parse(Class type, String value, NumberFormat format) { + private Number parse(Class sourceType, Class targetType, String value, NumberFormat format) { ParsePosition pos = new ParsePosition(0); Number parsedNumber = (Number)format.parse(value, pos); if (pos.getErrorIndex() >= 0 || pos.getIndex() != value.length() || parsedNumber == null) { - String msg = "Error converting to '" + toString(type) + "'"; + String msg = "Error converting from '" + toString(sourceType) + "' to '" + toString(targetType) + "'"; if (format instanceof DecimalFormat) { msg += " using pattern '" + ((DecimalFormat)format).toPattern() + "'"; } Modified: jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/converters/NumberConverterTestBase.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/converters/NumberConverterTestBase.java?view=diff&rev=541122&r1=541121&r2=541122 ============================================================================== --- jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/converters/NumberConverterTestBase.java (original) +++ jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/converters/NumberConverterTestBase.java Wed May 23 17:18:01 2007 @@ -19,6 +19,7 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Calendar; import java.util.Date; import java.util.Locale; @@ -192,6 +193,19 @@ // expected result } + // Invalid Type (will try via String) + Object obj = new Object() { + public String toString() { + return "dsdgsdsdg"; + } + }; + try { + converter.convert(getExpectedType(), obj); + fail("Expected invalid value to cause ConversionException"); + } catch (Exception e) { + // expected result + } + // Restore the default Locale Locale.setDefault(defaultLocale); } @@ -271,16 +285,49 @@ } /** - * Convert Date --> Long (default conversion) + * Convert Date --> Long */ - public void testDateToLongDefault() { + public void testDateToNumber() { NumberConverter converter = makeConverter(); - // Other type --> String conversion - Date now = new Date(); - assertEquals("Date to long", new Long(now.getTime()), converter.convert(Long.class, now)); - + Date dateValue = new Date(); + long longValue = dateValue.getTime(); + + // Date --> Long conversion + assertEquals("Date to Long", new Long(longValue), converter.convert(Long.class, dateValue)); + + // Date --> Integer + try { + converter.convert(Integer.class, dateValue); + fail("Date to Integer - expected a ConversionException"); + } catch (ConversionException e) { + // expected result - too large for Integer + } + + } + + /** + * Convert Calendar --> Long + */ + public void testCalendarToNumber() { + + NumberConverter converter = makeConverter(); + + Calendar calendarValue = Calendar.getInstance(); + long longValue = calendarValue.getTime().getTime(); + + // Calendar --> Long conversion + assertEquals("Calendar to Long", new Long(longValue), converter.convert(Long.class, calendarValue)); + + // Calendar --> Integer + try { + converter.convert(Integer.class, calendarValue); + fail("Calendar to Integer - expected a ConversionException"); + } catch (ConversionException e) { + // expected result - too large for Integer + } + } /** --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]