diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java b/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java
index 40f01aba..f535d95b 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java
@@ -75,7 +75,9 @@ public class GenericConversionService implements ConversionService {
}
for (int j = 0; j < targetClasses.length; j++) {
Class targetClass = targetClasses[j];
- sourceMap.put(targetClass, converter);
+ if (!targetClass.equals(sourceClass)) {
+ sourceMap.put(targetClass, converter);
+ }
}
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/Formatter.java b/spring-binding/src/main/java/org/springframework/binding/format/Formatter.java
index da3e36b0..3dbbb9b4 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/Formatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/Formatter.java
@@ -16,17 +16,24 @@
package org.springframework.binding.format;
/**
- * Formats objects for display.
+ * Formats objects of a certain class for display.
*
* @author Keith Donald
*/
public interface Formatter {
+ /**
+ * Returns the type of object this Formatter formats. Successful {@link #parse(String) parse calls} will return
+ * instances of this type. {@link #format(Object)} callers must provide an instance of this type.
+ * @return the type of object being formatted
+ */
+ public Class getObjectType();
+
/**
* Format the object for display.
* @param object the object to format
* @return the formatted string, fit for display in a UI
- * @throws IllegalArgumentException if the object could not be formatted
+ * @throws IllegalArgumentException if the object is of the wrong type
*/
public String format(Object object) throws IllegalArgumentException;
@@ -34,7 +41,7 @@ public interface Formatter {
* Parse the formatted string representation of an object and return the object.
* @param formattedString the formatted string representation
* @return the parsed object
- * @throws InvalidFormatException the formatted string was in an invalid form
+ * @throws InvalidFormatException the formatted string was in an invalid form, often due to user input error
*/
public Object parse(String formattedString) throws InvalidFormatException;
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/FormatterRegistry.java b/spring-binding/src/main/java/org/springframework/binding/format/FormatterRegistry.java
index 42a14eeb..33ed92c4 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/FormatterRegistry.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/FormatterRegistry.java
@@ -16,12 +16,7 @@
package org.springframework.binding.format;
/**
- * Source for shared and commonly used Formatters.
- *
- * Note: formatters are typically not thread safe as Format objects aren't thread safe. In general, you
- * should not attempt to share formatters between threads.
- *
Formatters.
*
* @author Keith Donald
*/
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java
index 799ab973..bc97f087 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java
@@ -17,6 +17,7 @@ package org.springframework.binding.format.formatters;
import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.InvalidFormatException;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -26,16 +27,19 @@ import org.springframework.util.StringUtils;
*/
public class BooleanFormatter implements Formatter {
+ public Class getObjectType() {
+ return Boolean.class;
+ }
+
public String format(Object value) throws IllegalArgumentException {
if (value == null) {
return "";
}
+ Assert.isInstanceOf(Boolean.class, value, "Object is not a [java.lang.Boolean]");
if (Boolean.TRUE.equals(value)) {
return "true";
- } else if (Boolean.FALSE.equals(value)) {
- return "false";
} else {
- throw new IllegalArgumentException("Not a Boolean: " + value);
+ return "false";
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java
index 70359f52..dba05850 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java
@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.InvalidFormatException;
import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -79,10 +80,17 @@ public class DateFormatter implements Formatter {
this.locale = locale;
}
+ // implementing Formatter
+
+ public Class getObjectType() {
+ return Date.class;
+ }
+
public String format(Object date) {
if (date == null) {
return "";
}
+ Assert.isInstanceOf(Date.class, date, "Object is not a [java.util.Date]");
return getDateFormat().format((Date) date);
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java
index d98dd78a..039b2b9d 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java
@@ -30,9 +30,19 @@ import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
/**
- * A formatter for common number types such as integers and big decimals. Allows the configuration of an explicit number
- * pattern and locale.
+ * A general formatter for common number types such as integers and big decimals. Allows the configuration of an
+ * explicit number pattern and locale.
+ *
+ * Works with a general purpose {@link DecimalFormat} instance returned by calling
+ * {@link NumberFormat#getInstance(Locale)} by default. This instance supports parsing any number type generally and
+ * will not perform special type-specific logic such as rounding or truncation. Subclasses may override.
+ *
+ * Will coerse parsed Numbers to the desired numberClass as necessary. If type-coersion results in an overflow
+ * condition; for example, what can occur with a Long being coersed to a Short, an exception will be thrown.
+ *
+ * @see NumberFormat
* @see DecimalFormat
+ *
* @author Keith Donald
*/
public class NumberFormatter implements Formatter {
@@ -45,12 +55,15 @@ public class NumberFormatter implements Formatter {
private Locale locale;
+ private boolean lenient;
+
/**
* Creates a number formatter for the specified number type.
* @param numberClass the number type, a class extending from {@link Number}.
*/
public NumberFormatter(Class numberClass) {
Assert.notNull(numberClass, "The number class is required");
+ Assert.isTrue(Number.class.isAssignableFrom(numberClass), "The class must extend from Number");
this.numberClass = numberClass;
}
@@ -88,10 +101,37 @@ public class NumberFormatter implements Formatter {
this.locale = locale;
}
+ /**
+ * If this Formatter is "lenient" in parsing number strings. A lenient formatter does not require that all
+ * characters in the String be parsed successfully. Default is false.
+ * @return the lenient flag
+ */
+ public boolean getLenient() {
+ return lenient;
+ }
+
+ /**
+ * Sets if this Formatter should parse leniently.
+ * @param lenient the lenient flag
+ */
+ public void setLenient(boolean lenient) {
+ this.lenient = lenient;
+ }
+
+ // implementing Formatter
+
+ public Class getObjectType() {
+ return numberClass;
+ }
+
public String format(Object number) {
if (number == null) {
return "";
}
+ if (!numberClass.isInstance(number)) {
+ throw new IllegalArgumentException("Object is not a [" + numberClass.getName() + "]; it is a ["
+ + number.getClass().getName() + "]");
+ }
return getNumberFormat().format(number);
}
@@ -102,18 +142,28 @@ public class NumberFormatter implements Formatter {
ParsePosition parsePosition = new ParsePosition(0);
NumberFormat format = getNumberFormat();
Number number = format.parse(formattedString, parsePosition);
- if (number == null || formattedString.length() != parsePosition.getIndex()) {
+ if (number == null) {
+ // no object could be parsed
throw new InvalidFormatException(formattedString, getPattern(format));
- } else {
- return NumberUtils.convertNumberToTargetClass(number, numberClass);
}
+ if (!lenient) {
+ if (formattedString.length() != parsePosition.getIndex()) {
+ // indicates a part of the string that was not parsed; e.g. ".5" in 1234.5 when parsing an Integer
+ throw new InvalidFormatException(formattedString, getPattern(format));
+ }
+ }
+ return convertToNumberClass(number);
}
// subclassing hookings
+ /**
+ * Factory method that returns a fully-configured {@link NumberFormat} instance to use to format an object for
+ * display. Applies the locale and pattern properties if configured. Subclasses may override.
+ */
protected NumberFormat getNumberFormat() {
Locale locale = determineLocale(this.locale);
- NumberFormat format = NumberFormat.getInstance(locale);
+ NumberFormat format = createNumberFormat(locale);
if (pattern != null) {
if (format instanceof DecimalFormat) {
((DecimalFormat) format).applyPattern(pattern);
@@ -125,6 +175,27 @@ public class NumberFormatter implements Formatter {
return format;
}
+ /**
+ * Delegates to the {@link NumberFormat java.text.NumberFormat API} to construct the new NumberFormat instance.
+ * Called by {@link #getNumberFormat()} after calculating the Locale. Subclasses may override to control how the
+ * Format instance is constructed.
+ * @param locale the calculated Locale
+ * @return the new NumberFormat instance
+ */
+ protected NumberFormat createNumberFormat(Locale locale) {
+ return NumberFormat.getInstance(locale);
+ }
+
+ /**
+ * Coerces the Number object returned by NumberFormat to the desired numberClass. Subclasses may override.
+ * @param number the parsed number
+ * @return the coersed number
+ * @throws IllegalArgumentException when an overflow condition occurs during coersion
+ */
+ protected Number convertToNumberClass(Number number) throws IllegalArgumentException {
+ return NumberUtils.convertNumberToTargetClass(number, numberClass);
+ }
+
// internal helpers
private Locale determineLocale(Locale locale) {
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java
index 8e3745ee..ea4bb9f7 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java
@@ -21,20 +21,27 @@ import org.springframework.binding.format.Formatter;
import org.springframework.util.Assert;
/**
- * Adapts a {@link PropertyEditor} to the formatter interface.
+ * Adapts a {@link PropertyEditor} to the formatter interface. Useful for re-using pre-existing PropertyEditors as
+ * Formatters.
+ *
+ * Note: this class synchronizes calls into the configured PropertyEditor instance to ensure thread safety.
*
* @author Keith Donald
*/
public class PropertyEditorFormatter implements Formatter {
+ private Class objectType;
+
private PropertyEditor propertyEditor;
/**
* Wrap the given property editor in a formatter.
*/
- public PropertyEditorFormatter(PropertyEditor propertyEditor) {
+ public PropertyEditorFormatter(PropertyEditor propertyEditor, Class objectType) {
Assert.notNull(propertyEditor, "The PropertyEditor is required");
+ Assert.notNull(objectType, "The object type is required");
this.propertyEditor = propertyEditor;
+ this.objectType = objectType;
}
/**
@@ -44,13 +51,27 @@ public class PropertyEditorFormatter implements Formatter {
return propertyEditor;
}
+ // implementing Formatter
+
+ public Class getObjectType() {
+ return objectType;
+ }
+
public String format(Object value) {
- propertyEditor.setValue(value);
- return propertyEditor.getAsText();
+ synchronized (propertyEditor) {
+ propertyEditor.setValue(value);
+ String text = propertyEditor.getAsText();
+ propertyEditor.setValue(null);
+ return text;
+ }
}
public Object parse(String formattedValue) {
- propertyEditor.setAsText(formattedValue);
- return propertyEditor.getValue();
+ synchronized (propertyEditor) {
+ propertyEditor.setAsText(formattedValue);
+ Object value = propertyEditor.getValue();
+ propertyEditor.setValue(null);
+ return value;
+ }
}
}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/registry/DefaultFormatterRegistry.java b/spring-binding/src/main/java/org/springframework/binding/format/registry/DefaultFormatterRegistry.java
index 5a7d8524..3da13f07 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/registry/DefaultFormatterRegistry.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/registry/DefaultFormatterRegistry.java
@@ -17,12 +17,12 @@ package org.springframework.binding.format.registry;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Date;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.binding.format.FormatterRegistry;
import org.springframework.binding.format.formatters.BooleanFormatter;
import org.springframework.binding.format.formatters.DateFormatter;
+import org.springframework.binding.format.formatters.IntegerFormatter;
import org.springframework.binding.format.formatters.NumberFormatter;
public class DefaultFormatterRegistry extends GenericFormatterRegistry {
@@ -43,16 +43,16 @@ public class DefaultFormatterRegistry extends GenericFormatterRegistry {
* Registers the default formatters. Subclasses may override.
*/
protected void registerDefaultFormatters() {
- registerFormatter(Integer.class, new NumberFormatter(Integer.class));
- registerFormatter(Long.class, new NumberFormatter(Long.class));
- registerFormatter(Short.class, new NumberFormatter(Short.class));
- registerFormatter(Float.class, new NumberFormatter(Float.class));
- registerFormatter(Double.class, new NumberFormatter(Double.class));
- registerFormatter(Byte.class, new NumberFormatter(Byte.class));
- registerFormatter(BigInteger.class, new NumberFormatter(BigInteger.class));
- registerFormatter(BigDecimal.class, new NumberFormatter(BigDecimal.class));
- registerFormatter(Boolean.class, new BooleanFormatter());
- registerFormatter(Date.class, new DateFormatter());
+ registerFormatter(new IntegerFormatter(Integer.class));
+ registerFormatter(new IntegerFormatter(BigInteger.class));
+ registerFormatter(new IntegerFormatter(Long.class));
+ registerFormatter(new IntegerFormatter(Short.class));
+ registerFormatter(new NumberFormatter(Float.class));
+ registerFormatter(new NumberFormatter(Double.class));
+ registerFormatter(new NumberFormatter(BigDecimal.class));
+ registerFormatter(new NumberFormatter(Byte.class));
+ registerFormatter(new BooleanFormatter());
+ registerFormatter(new DateFormatter());
}
/**
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/registry/GenericFormatterRegistry.java b/spring-binding/src/main/java/org/springframework/binding/format/registry/GenericFormatterRegistry.java
index 2c5ac964..707ed4a8 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/registry/GenericFormatterRegistry.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/registry/GenericFormatterRegistry.java
@@ -16,7 +16,6 @@
package org.springframework.binding.format.registry;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.Map;
import org.springframework.binding.format.Formatter;
@@ -24,8 +23,10 @@ import org.springframework.binding.format.FormatterRegistry;
import org.springframework.util.Assert;
/**
- * Base class for formatter factories. Manages the locale used by the produced formatters using Spring's
- * {@link org.springframework.context.i18n.LocaleContext} system.
+ * A general-purpose {@link FormatterRegistry} implementation allows formatters to be registered programatically.
+ *
+ * @see #registerFormatter(Class, Formatter)
+ * @see #registerFormatter(String, Formatter)
*
* @author Keith Donald
*/
@@ -38,7 +39,7 @@ public class GenericFormatterRegistry implements FormatterRegistry {
public Formatter getFormatter(Class clazz) {
Assert.notNull(clazz, "The formatted class argument is required");
clazz = convertToWrapperClassIfNecessary(clazz);
- return findFormatter(clazz);
+ return (Formatter) formattersByClass.get(clazz);
}
public Formatter getFormatter(String id) {
@@ -48,9 +49,9 @@ public class GenericFormatterRegistry implements FormatterRegistry {
// impl
- public void registerFormatter(Class clazz, Formatter formatter) {
+ public void registerFormatter(Formatter formatter) {
Assert.notNull(formatter, "The formatter to register is required");
- formattersByClass.put(clazz, formatter);
+ formattersByClass.put(formatter.getObjectType(), formatter);
}
public void registerFormatter(String id, Formatter formatter) {
@@ -61,26 +62,6 @@ public class GenericFormatterRegistry implements FormatterRegistry {
// helpers
- private Formatter findFormatter(Class clazz) {
- LinkedList classQueue = new LinkedList();
- classQueue.addFirst(clazz);
- while (!classQueue.isEmpty()) {
- clazz = (Class) classQueue.removeLast();
- Formatter factory = (Formatter) formattersByClass.get(clazz);
- if (factory != null) {
- return factory;
- }
- if (!clazz.isInterface() && clazz.getSuperclass() != null) {
- classQueue.add(clazz.getSuperclass());
- }
- Class[] interfaces = clazz.getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- classQueue.addFirst(interfaces[i]);
- }
- }
- return null;
- }
-
private Class convertToWrapperClassIfNecessary(Class targetType) {
if (targetType.isPrimitive()) {
if (targetType.equals(int.class)) {
diff --git a/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java b/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java
index e4da6b19..56c200d2 100644
--- a/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java
@@ -18,6 +18,7 @@ package org.springframework.binding.convert.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import junit.framework.TestCase;
@@ -25,7 +26,9 @@ import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionExecutorNotFoundException;
import org.springframework.binding.convert.Converter;
+import org.springframework.binding.convert.converters.FormatterConverter;
import org.springframework.binding.convert.converters.TextToBoolean;
+import org.springframework.binding.format.formatters.IntegerFormatter;
/**
* Test case for the default conversion service.
@@ -85,4 +88,20 @@ public class DefaultConversionServiceTests extends TestCase {
Integer three = (Integer) executor.execute("3");
assertEquals(3, three.intValue());
}
+
+ public void testRegisterConverter() {
+ GenericConversionService service = new GenericConversionService();
+ IntegerFormatter formatter = new IntegerFormatter(Integer.class);
+ formatter.setLocale(Locale.US);
+ FormatterConverter converter = new FormatterConverter(formatter);
+ service.addConverter(converter);
+ ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class);
+ Integer three = (Integer) executor.execute("3,000");
+ assertEquals(3000, three.intValue());
+
+ ConversionExecutor executor2 = service.getConversionExecutor(Integer.class, String.class);
+ String string = (String) executor2.execute(new Integer(3000));
+ assertEquals("3,000", string);
+
+ }
}
\ No newline at end of file
diff --git a/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java b/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java
index ffb53884..c4038b45 100644
--- a/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java
@@ -13,7 +13,7 @@ public class NumberFormatterTests extends TestCase {
public void testFormatIntegerDefaultPattern() {
formatter = new NumberFormatter(Integer.class);
- formatter.setLocale(Locale.ENGLISH);
+ formatter.setLocale(Locale.US);
String value = formatter.format(new Integer(12345));
assertEquals("12,345", value);
}
@@ -21,7 +21,7 @@ public class NumberFormatterTests extends TestCase {
public void testFormatBigDecimalCustomPattern() {
formatter = new NumberFormatter(BigDecimal.class);
formatter.setPattern("000.00");
- formatter.setLocale(Locale.ENGLISH);
+ formatter.setLocale(Locale.US);
BigDecimal dec = new BigDecimal("123.45");
String value = formatter.format(dec);
assertEquals("123.45", value);
@@ -34,7 +34,7 @@ public class NumberFormatterTests extends TestCase {
public void testParseIntegerDefaultPattern() {
formatter = new NumberFormatter(Integer.class);
- formatter.setLocale(Locale.ENGLISH);
+ formatter.setLocale(Locale.US);
Integer integer = (Integer) formatter.parse("123,450");
assertEquals(Integer.valueOf(123450), integer);
}
@@ -42,7 +42,7 @@ public class NumberFormatterTests extends TestCase {
public void testParseBigDecimalCustomPattern() {
formatter = new NumberFormatter(BigDecimal.class);
formatter.setPattern("000.00");
- formatter.setLocale(Locale.ENGLISH);
+ formatter.setLocale(Locale.US);
BigDecimal dec = (BigDecimal) formatter.parse("123.45");
assertEquals(new BigDecimal("123.45"), dec);
}
@@ -50,12 +50,32 @@ public class NumberFormatterTests extends TestCase {
public void testParseInvalidFormatPatternTruncation() {
try {
formatter = new NumberFormatter(Integer.class);
+ formatter.setLocale(Locale.US);
formatter.parse("123,450b");
fail("Should have failed");
} catch (InvalidFormatException e) {
}
}
+ public void testParseInvalidFormatPatternTruncationInteger() {
+ try {
+ formatter = new IntegerFormatter(Integer.class);
+ formatter.setLocale(Locale.US);
+ formatter.parse("123,450.00");
+ fail("Should have failed");
+ } catch (InvalidFormatException e) {
+
+ }
+ }
+
+ public void testParseInvalidFormatPatternLenient() {
+ formatter = new NumberFormatter(Integer.class);
+ formatter.setLocale(Locale.US);
+ formatter.setLenient(true);
+ Integer integer = (Integer) formatter.parse("123,450b");
+ assertEquals(Integer.valueOf(123450), integer);
+ }
+
public void testParseInvalidFormatPattern() {
try {
formatter = new NumberFormatter(BigDecimal.class);
diff --git a/spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java b/spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java
index 7ca7f03d..4a779148 100644
--- a/spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java
@@ -14,35 +14,34 @@ public class GenericFormatterRegistryTests extends TestCase {
GenericFormatterRegistry registry = new GenericFormatterRegistry();
public void testRegisterAndGetFormatter() {
- registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class));
+ registry.registerFormatter(new NumberFormatter(Integer.class));
Formatter formatter = registry.getFormatter(Integer.class);
Integer value = (Integer) formatter.parse("3");
assertEquals(new Integer(3), value);
}
public void testRegisterAndGetFormatterAbstractClass() {
- registry.registerFormatter(Number.class, new NumberFormatter(Long.class));
+ registry.registerFormatter(new NumberFormatter(Number.class));
Formatter formatter = registry.getFormatter(Long.class);
- Number value = (Number) formatter.parse("3");
- assertEquals(3L, value.longValue());
+ assertNull(formatter);
}
public void testRegisterAndGetFormatterPrimitive() {
- registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class));
+ registry.registerFormatter(new NumberFormatter(Integer.class));
Formatter formatter = registry.getFormatter(int.class);
Integer value = (Integer) formatter.parse("3");
assertEquals(new Integer(3), value);
}
public void testRegisterAndGetFormatterInterface() {
- registry.registerFormatter(CustomType.class, new CustomTypeFormatter());
- Formatter formatter = registry.getFormatter(DefaultCustomType.class);
+ registry.registerFormatter(new CustomTypeFormatter());
+ Formatter formatter = registry.getFormatter(CustomType.class);
assertEquals("12345", formatter.format(new DefaultCustomType("12345")));
assertEquals(new DefaultCustomType("12345"), formatter.parse("12345"));
}
public void testRegisterCustomFormatter() {
- registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class));
+ registry.registerFormatter(new NumberFormatter(Integer.class));
NumberFormatter percentFormatter = new NumberFormatter(BigDecimal.class);
percentFormatter.setPattern("00%");
registry.registerFormatter("percent", percentFormatter);
@@ -53,7 +52,7 @@ public class GenericFormatterRegistryTests extends TestCase {
}
public void testRegisterCustomFormatterBogusLookupId() {
- registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class));
+ registry.registerFormatter(new NumberFormatter(Integer.class));
registry.registerFormatter("double", new NumberFormatter(Double.class));
Formatter formatter = registry.getFormatter("bogusFormat");
assertNull(formatter);
@@ -85,6 +84,10 @@ public class GenericFormatterRegistryTests extends TestCase {
private class CustomTypeFormatter implements Formatter {
+ public Class getObjectType() {
+ return CustomType.class;
+ }
+
public String format(Object value) throws IllegalArgumentException {
CustomType type = (CustomType) value;
return type.getText();