diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/AbstractFormattingConverter.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/AbstractFormattingConverter.java deleted file mode 100644 index 689b127b..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/AbstractFormattingConverter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.binding.convert.converters; - -import org.springframework.binding.format.FormatterRegistry; -import org.springframework.util.Assert; - -/** - * A converter that delegates to a formatter to perform the conversion. Formatters are typically not thread safe, so we - * use a FormatterRegistry that is expected to provide us with instances local to the current thread. - * - * @author Keith Donald - */ -public abstract class AbstractFormattingConverter extends AbstractConverter { - - /** - * The formatter registry. - */ - private FormatterRegistry formatterRegistry; - - /** - * Creates a new converter that delegates to a formatter. - * @param formatterRegistry the formatterRegistry to use - */ - protected AbstractFormattingConverter(FormatterRegistry formatterRegistry) { - Assert.notNull(formatterRegistry, "The formatter registry is required"); - this.formatterRegistry = formatterRegistry; - } - - public FormatterRegistry getFormatterRegistry() { - return formatterRegistry; - } - - protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { - return getFormatterRegistry().getFormatter(targetClass).parseValue((String) source); - } -} \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToDate.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToDate.java deleted file mode 100644 index 870e003b..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToDate.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2004-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.binding.convert.converters; - -import java.util.Date; - -import org.springframework.binding.format.FormatterRegistry; - -/** - * Converts textual representations of numbers to a Number specialization. Delegates to a synchronized - * formatter to parse text strings. - * - * @author Keith Donald - */ -public class TextToDate extends AbstractFormattingConverter { - - /** - * Create a string to number converter using given formatter factory. - * @param formatterRegistry the formatter registry to use - */ - public TextToDate(FormatterRegistry formatterRegistry) { - super(formatterRegistry); - } - - public Class[] getSourceClasses() { - return new Class[] { String.class }; - } - - public Class[] getTargetClasses() { - return new Class[] { Date.class }; - } - -} \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java index ed8e54b6..0f798182 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java @@ -18,7 +18,7 @@ package org.springframework.binding.convert.converters; import java.math.BigDecimal; import java.math.BigInteger; -import org.springframework.binding.format.FormatterRegistry; +import org.springframework.util.NumberUtils; /** * Converts textual representations of numbers to a Number specialization. Delegates to a synchronized @@ -26,15 +26,7 @@ import org.springframework.binding.format.FormatterRegistry; * * @author Keith Donald */ -public class TextToNumber extends AbstractFormattingConverter { - - /** - * Create a string to number converter using given formatter factory. - * @param formatterRegistry the formatter registry to use - */ - public TextToNumber(FormatterRegistry formatterRegistry) { - super(formatterRegistry); - } +public class TextToNumber extends AbstractConverter { public Class[] getSourceClasses() { return new Class[] { String.class }; @@ -44,4 +36,9 @@ public class TextToNumber extends AbstractFormattingConverter { return new Class[] { Integer.class, Short.class, Long.class, Float.class, Double.class, Byte.class, BigInteger.class, BigDecimal.class }; } + + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { + return NumberUtils.parseNumber((String) source, targetClass); + } + } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/service/DefaultConversionService.java b/spring-binding/src/main/java/org/springframework/binding/convert/service/DefaultConversionService.java index 0bf17e34..6af773f8 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/service/DefaultConversionService.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/service/DefaultConversionService.java @@ -18,13 +18,8 @@ package org.springframework.binding.convert.service; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.convert.converters.TextToBoolean; import org.springframework.binding.convert.converters.TextToClass; -import org.springframework.binding.convert.converters.TextToDate; import org.springframework.binding.convert.converters.TextToLabeledEnum; import org.springframework.binding.convert.converters.TextToNumber; -import org.springframework.binding.format.FormatterRegistry; -import org.springframework.binding.format.factories.DateFormatterFactory; -import org.springframework.binding.format.factories.NumberFormatterFactory; -import org.springframework.binding.format.impl.FormatterRegistryImpl; /** * Default, local implementation of a conversion service. Will automatically register from string converters for @@ -37,18 +32,12 @@ public class DefaultConversionService extends GenericConversionService { /** * A singleton shared instance. Should never be modified. */ - private static final DefaultConversionService SHARED_INSTANCE = new DefaultConversionService(); - - /** - * Returns the formatter registry used by this conversion service - */ - private FormatterRegistry formatterRegistry; + private static DefaultConversionService SHARED_INSTANCE; /** * Creates a new default conversion service, installing the default converters. */ public DefaultConversionService() { - formatterRegistry = createDefaultFormatterRegistry(); addDefaultConverters(); } @@ -59,21 +48,16 @@ public class DefaultConversionService extends GenericConversionService { addConverter(new TextToClass()); addConverter(new TextToBoolean()); addConverter(new TextToLabeledEnum()); - addConverter(new TextToNumber(formatterRegistry)); - addConverter(new TextToDate(formatterRegistry)); - } - - protected FormatterRegistry createDefaultFormatterRegistry() { - FormatterRegistryImpl registry = new FormatterRegistryImpl(); - registry.registerFormatter(new NumberFormatterFactory()); - registry.registerFormatter(new DateFormatterFactory()); - return registry; + addConverter(new TextToNumber()); } /** * Returns the shared {@link DefaultConversionService} instance. */ - public static ConversionService getSharedInstance() { + public synchronized static ConversionService getSharedInstance() { + if (SHARED_INSTANCE == null) { + SHARED_INSTANCE = new DefaultConversionService(); + } return SHARED_INSTANCE; } } \ No newline at end of file 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 37285f52..f9d7300a 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,29 +16,26 @@ package org.springframework.binding.format; /** - * A lightweight interface for formatting a value and parsing a value from its formatted form. - *

- * 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. - *

+ * Formats objects for display. + * * @author Keith Donald */ public interface Formatter { /** - * Format the value. - * @param value the value to format + * Format the object for display. + * @param object the object to format * @return the formatted string, fit for display in a UI - * @throws IllegalArgumentException the value could not be formatted + * @throws IllegalArgumentException if the object could not be formatted */ - public String formatValue(Object value) throws IllegalArgumentException; + public String format(Object object) throws IllegalArgumentException; /** - * Parse the formatted string representation of a value, restoring the value. + * Parse the formatted string representation of an object and return the object. * @param formattedString the formatted string representation - * @return the parsed value - * @throws InvalidFormatException the string was in an invalid form + * @return the parsed object + * @throws InvalidFormatException the formatted string was in an invalid form */ - public Object parseValue(String formattedString) throws InvalidFormatException; + public Object parse(String formattedString) throws InvalidFormatException; } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/FormatterFactory.java b/spring-binding/src/main/java/org/springframework/binding/format/FormatterFactory.java deleted file mode 100644 index 0cf11e83..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/FormatterFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.binding.format; - -/** - * A factory for creating stateful formatter instances. - * - * @author Keith Donald - */ -public interface FormatterFactory { - - /** - * The type of object the returned formatters are capable of formatting. This is the most general type supported, - * some formatters may apply specific formatting rules to subclasses of this general type. - * @return the formatted class - */ - public Class getFormattedClass(); - - /** - * Create a new formatter. - * @param context context for formatter creation - * @return the new formatter - */ - public Formatter createFormatter(FormatterFactoryContext context); - -} \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/FormatterFactoryContext.java b/spring-binding/src/main/java/org/springframework/binding/format/FormatterFactoryContext.java deleted file mode 100644 index 6cc12e44..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/FormatterFactoryContext.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.springframework.binding.format; - -import java.util.Locale; - -/** - * A context for creating a formatter instance. - * - * @author Keith Donald - */ -public interface FormatterFactoryContext { - - /** - * The current locale. - */ - public Locale getLocale(); - - /** - * The type of object of which formatting is desired. - */ - public Class getFormattedClass(); -} 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 83aa31c5..dd6890d2 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 @@ -38,9 +38,8 @@ public interface FormatterRegistry { * Returns the formatter for the given class of object with the given id. Use this method to query a custom * formatter instance for a given class of object. * @param id the id of the custom formatter instance; typically descriptive like "localDate" - * @param clazz the class being formatted e.g. Date.class. * @return the formatter */ - public Formatter getFormatter(String id, Class clazz); + public Formatter getFormatter(String id); } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/adapters/FormatterPropertyEditor.java b/spring-binding/src/main/java/org/springframework/binding/format/adapters/FormatterPropertyEditor.java index 569e6788..8f1d9f20 100644 --- a/spring-binding/src/main/java/org/springframework/binding/format/adapters/FormatterPropertyEditor.java +++ b/spring-binding/src/main/java/org/springframework/binding/format/adapters/FormatterPropertyEditor.java @@ -40,10 +40,10 @@ public class FormatterPropertyEditor extends PropertyEditorSupport { } public String getAsText() { - return formatter.formatValue(getValue()); + return formatter.format(getValue()); } public void setAsText(String text) throws IllegalArgumentException { - setValue(formatter.parseValue(text)); + setValue(formatter.parse(text)); } } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/adapters/PropertyEditorFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/adapters/PropertyEditorFormatter.java index a5af3c38..c91d0791 100644 --- a/spring-binding/src/main/java/org/springframework/binding/format/adapters/PropertyEditorFormatter.java +++ b/spring-binding/src/main/java/org/springframework/binding/format/adapters/PropertyEditorFormatter.java @@ -17,20 +17,19 @@ package org.springframework.binding.format.adapters; import java.beans.PropertyEditor; -import org.springframework.binding.format.factories.AbstractFormatter; +import org.springframework.binding.format.Formatter; import org.springframework.util.Assert; /** * Adapts a property editor to the formatter interface. - * * @author Keith Donald */ -public class PropertyEditorFormatter extends AbstractFormatter { +public class PropertyEditorFormatter implements Formatter { private PropertyEditor propertyEditor; /** - * Wrap given property editor in a formatter. + * Wrap the given property editor in a formatter. */ public PropertyEditorFormatter(PropertyEditor propertyEditor) { Assert.notNull(propertyEditor, "Property editor is required"); @@ -44,18 +43,13 @@ public class PropertyEditorFormatter extends AbstractFormatter { return propertyEditor; } - protected String doFormatValue(Object value) { + public String format(Object value) { propertyEditor.setValue(value); return propertyEditor.getAsText(); } - protected Object doParseValue(String formattedValue) { + public Object parse(String formattedValue) { propertyEditor.setAsText(formattedValue); return propertyEditor.getValue(); } - - protected String getExpectedFormat() { - return null; - } - } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/factories/AbstractFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/factories/AbstractFormatter.java deleted file mode 100644 index d14d7fc1..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/factories/AbstractFormatter.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2004-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.binding.format.factories; - -import java.text.ParseException; - -import org.springframework.binding.format.Formatter; -import org.springframework.binding.format.InvalidFormatException; -import org.springframework.util.StringUtils; - -/** - * Abstract base class for all formatters. - * - * @author Keith Donald - */ -public abstract class AbstractFormatter implements Formatter { - - /** - * Constructs a formatter. - */ - protected AbstractFormatter() { - } - - public final String formatValue(Object value) { - if (isEmpty(value)) { - return getEmptyFormattedValue(); - } else { - return doFormatValue(value); - } - } - - public final Object parseValue(String formattedString) throws InvalidFormatException { - try { - if (isEmpty(formattedString)) { - return getEmptyValue(); - } - return doParseValue(formattedString); - } catch (ParseException ex) { - throw new InvalidFormatException(formattedString, getExpectedFormat(), ex); - } - } - - /** - * Template method subclasses should override to encapsulate formatting logic. - * @param value the value to format - * @return the formatted string representation - */ - protected abstract String doFormatValue(Object value); - - /** - * Returns the formatted form of an empty value. Default implementation just returns the empty string. - */ - protected String getEmptyFormattedValue() { - return ""; - } - - /** - * Template method subclasses should override to encapsulate parsing logic. - * @param formattedString the formatted string to parse - * @return the parsed value - * @throws InvalidFormatException an exception occurred parsing - * @throws ParseException when parse exceptions occur - */ - protected abstract Object doParseValue(String formattedString) throws InvalidFormatException, ParseException; - - /** - * Returns the empty value (resulting from parsing an empty input string). This default implementation just returns - * null. - */ - protected Object getEmptyValue() { - return null; - } - - /** - * Returns the expected string format for the given target class. - */ - protected abstract String getExpectedFormat(); - - /** - * Is given object empty (null or empty string)? - */ - protected boolean isEmpty(Object o) { - if (o == null) { - return true; - } else if (o instanceof String) { - return !StringUtils.hasText((String) o); - } else { - return false; - } - } -} \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/factories/BooleanFormatterFactory.java b/spring-binding/src/main/java/org/springframework/binding/format/factories/BooleanFormatterFactory.java deleted file mode 100644 index b4f77605..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/factories/BooleanFormatterFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.springframework.binding.format.factories; - -import org.springframework.binding.format.Formatter; -import org.springframework.binding.format.FormatterFactory; -import org.springframework.binding.format.FormatterFactoryContext; -import org.springframework.binding.format.InvalidFormatException; -import org.springframework.util.StringUtils; - -public class BooleanFormatterFactory implements FormatterFactory { - - public Class getFormattedClass() { - return Boolean.class; - } - - public Formatter createFormatter(FormatterFactoryContext context) { - return new BooleanFormatter(); - } - - public static class BooleanFormatter implements Formatter { - - public String formatValue(Object value) throws IllegalArgumentException { - if (value == null) { - return ""; - } - if (Boolean.TRUE.equals(value)) { - return "true"; - } else if (Boolean.FALSE.equals(value)) { - return "false"; - } else { - throw new IllegalArgumentException("Must be a Boolean " + value); - } - } - - public Object parseValue(String formattedString) throws InvalidFormatException { - formattedString = (formattedString != null ? formattedString.trim() : null); - if (!StringUtils.hasText(formattedString)) { - return null; - } - if (formattedString.equals("true")) { - return Boolean.TRUE; - } else if (formattedString.equals("false")) { - return Boolean.FALSE; - } else { - throw new InvalidFormatException(formattedString, "true | false"); - } - } - } - -} diff --git a/spring-binding/src/main/java/org/springframework/binding/format/factories/DateFormatterFactory.java b/spring-binding/src/main/java/org/springframework/binding/format/factories/DateFormatterFactory.java deleted file mode 100644 index 9176d1e7..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/factories/DateFormatterFactory.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.binding.format.factories; - -import java.text.DateFormat; -import java.text.ParseException; -import java.util.Date; - -import org.springframework.binding.format.Formatter; -import org.springframework.binding.format.FormatterFactory; -import org.springframework.binding.format.FormatterFactoryContext; -import org.springframework.core.style.ToStringCreator; - -/** - * Factory for date formatters. - * - * @author Keith Donald - */ -public class DateFormatterFactory implements FormatterFactory { - - public Class getFormattedClass() { - return Date.class; - } - - public Formatter createFormatter(FormatterFactoryContext context) { - return new DateFormatter(getDateFormat(context)); - } - - /** - * Returns the date format to use with the formatter being created. Subclasses may override. - * @param context the factory context - * @return the date format - */ - protected DateFormat getDateFormat(FormatterFactoryContext context) { - return DateFormat.getDateInstance(DateFormat.SHORT, context.getLocale()); - } - - public static class DateFormatter extends AbstractFormatter { - - private DateFormat dateFormat; - - /** - * Constructs a date formatter that will delegate to the specified date format. - * @param dateFormat the date format to use - */ - public DateFormatter(DateFormat dateFormat) { - this.dateFormat = dateFormat; - } - - // convert from date to string - protected String doFormatValue(Object date) { - return dateFormat.format((Date) date); - } - - // convert back from string to date - protected Object doParseValue(String formattedString) throws ParseException { - return dateFormat.parse(formattedString); - } - - protected String getExpectedFormat() { - return dateFormat.toString(); - } - - public String toString() { - return new ToStringCreator(this).append("format", dateFormat).toString(); - } - - } - -} diff --git a/spring-binding/src/main/java/org/springframework/binding/format/factories/NumberFormatterFactory.java b/spring-binding/src/main/java/org/springframework/binding/format/factories/NumberFormatterFactory.java deleted file mode 100644 index dc3fd8c4..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/factories/NumberFormatterFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.springframework.binding.format.factories; - -import java.text.NumberFormat; - -import org.springframework.binding.format.Formatter; -import org.springframework.binding.format.FormatterFactory; -import org.springframework.binding.format.FormatterFactoryContext; -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.NumberUtils; - -/** - * Factory for number formatters. - * - * @author Keith Donald - */ -public class NumberFormatterFactory implements FormatterFactory { - - public Class getFormattedClass() { - return Number.class; - } - - public Formatter createFormatter(FormatterFactoryContext context) { - return new NumberFormatter(getNumberFormat(context), context.getFormattedClass()); - } - - /** - * Returns the number format to use with the formatter being created. Subclasses may override. - * @param context the factory context - * @return the number format - */ - protected NumberFormat getNumberFormat(FormatterFactoryContext context) { - if (context.getFormattedClass().equals(Integer.class)) { - return NumberFormat.getIntegerInstance(context.getLocale()); - } else { - return NumberFormat.getNumberInstance(context.getLocale()); - } - } - - public static class NumberFormatter extends AbstractFormatter { - - private NumberFormat numberFormat; - - private Class targetClass; - - /** - * Create a new number formatter. - * @param numberFormat the number format to use - * @param targetClass the number class to parse into - */ - public NumberFormatter(NumberFormat numberFormat, Class targetClass) { - this.numberFormat = numberFormat; - this.targetClass = targetClass; - } - - protected String doFormatValue(Object number) { - if (numberFormat != null) { - // use NumberFormat for rendering value - return numberFormat.format(number); - } else { - // use toString method for rendering value - return number.toString(); - } - } - - protected Object doParseValue(String text) throws IllegalArgumentException { - if (numberFormat != null) { - // use given NumberFormat for parsing text - return NumberUtils.parseNumber(text, targetClass, numberFormat); - } else { - // use default valueOf methods for parsing text - return NumberUtils.parseNumber(text, targetClass); - } - } - - protected String getExpectedFormat() { - return numberFormat.toString(); - } - - public String toString() { - return new ToStringCreator(this).append("format", numberFormat).append("targetClass", targetClass) - .toString(); - } - } -} 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 new file mode 100644 index 00000000..4df84c42 --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2004-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.binding.format.formatters; + +import org.springframework.binding.format.Formatter; +import org.springframework.binding.format.InvalidFormatException; +import org.springframework.util.StringUtils; + +public class BooleanFormatter implements Formatter { + + public String format(Object value) throws IllegalArgumentException { + if (value == null) { + return ""; + } + if (Boolean.TRUE.equals(value)) { + return "true"; + } else if (Boolean.FALSE.equals(value)) { + return "false"; + } else { + throw new IllegalArgumentException("Must be a Boolean " + value); + } + } + + public Object parse(String formattedString) throws InvalidFormatException { + formattedString = (formattedString != null ? formattedString.trim() : null); + if (!StringUtils.hasText(formattedString)) { + return null; + } + if (formattedString.equals("true")) { + return Boolean.TRUE; + } else if (formattedString.equals("false")) { + return Boolean.FALSE; + } else { + throw new InvalidFormatException(formattedString, "true | false"); + } + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..2e6d5493 --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java @@ -0,0 +1,70 @@ +/* + * Copyright 2004-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.binding.format.formatters; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import org.springframework.binding.format.Formatter; +import org.springframework.binding.format.InvalidFormatException; + +public class DateFormatter implements Formatter { + + private String pattern; + + private Locale locale; + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public String format(Object date) { + return getDateFormat().format((Date) date); + } + + public Object parse(String formattedString) throws InvalidFormatException { + DateFormat dateFormat = getDateFormat(); + try { + return dateFormat.parse(formattedString); + } catch (ParseException e) { + throw new InvalidFormatException(formattedString, dateFormat.toString()); + } + } + + protected DateFormat getDateFormat() { + if (pattern != null) { + return new SimpleDateFormat(pattern, locale); + } else { + return DateFormat.getDateInstance(); + } + } + +} \ No newline at end of file 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 new file mode 100644 index 00000000..9f7c0504 --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java @@ -0,0 +1,60 @@ +/* + * Copyright 2004-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.binding.format.formatters; + +import java.text.DecimalFormat; +import java.text.NumberFormat; + +import org.springframework.binding.format.Formatter; +import org.springframework.binding.format.InvalidFormatException; +import org.springframework.util.Assert; +import org.springframework.util.NumberUtils; + +public class NumberFormatter implements Formatter { + + private String pattern; + + private Class numberClass; + + public NumberFormatter(Class numberClass) { + Assert.notNull(numberClass, "The number class is required"); + this.numberClass = numberClass; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String format(Object number) { + if (pattern != null) { + return getNumberFormat().format(number); + } else { + return number.toString(); + } + } + + public Object parse(String text) throws InvalidFormatException { + if (pattern != null) { + return NumberUtils.parseNumber(text, numberClass, getNumberFormat()); + } else { + return NumberUtils.parseNumber(text, numberClass); + } + } + + private NumberFormat getNumberFormat() { + return new DecimalFormat(pattern); + } +} \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/format/impl/FormatterFactoryContextImpl.java b/spring-binding/src/main/java/org/springframework/binding/format/impl/FormatterFactoryContextImpl.java deleted file mode 100644 index dcd3eeb6..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/format/impl/FormatterFactoryContextImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.springframework.binding.format.impl; - -import java.util.Locale; - -import org.springframework.binding.format.FormatterFactoryContext; - -public class FormatterFactoryContextImpl implements FormatterFactoryContext { - - private Class formattedClass; - - private Locale locale; - - public Class getFormattedClass() { - return formattedClass; - } - - public Locale getLocale() { - return locale; - } - - public void setFormattedClass(Class formattedClass) { - this.formattedClass = formattedClass; - } - - public void setLocale(Locale locale) { - this.locale = locale; - } - -} 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 new file mode 100644 index 00000000..8e869a66 --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/format/registry/DefaultFormatterRegistry.java @@ -0,0 +1,46 @@ +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.NumberFormatter; + +public class DefaultFormatterRegistry extends FormatterRegistryImpl { + + /** + * A singleton shared instance. Should never be modified. + */ + private static DefaultFormatterRegistry SHARED_INSTANCE; + + public DefaultFormatterRegistry() { + registerDefaultFormatters(); + } + + 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()); + } + + /** + * Returns the shared {@link DefaultConversionService} instance. + */ + public synchronized static FormatterRegistry getSharedInstance() { + if (SHARED_INSTANCE == null) { + SHARED_INSTANCE = new DefaultFormatterRegistry(); + } + return SHARED_INSTANCE; + } +} diff --git a/spring-binding/src/main/java/org/springframework/binding/format/impl/FormatterRegistryImpl.java b/spring-binding/src/main/java/org/springframework/binding/format/registry/FormatterRegistryImpl.java similarity index 55% rename from spring-binding/src/main/java/org/springframework/binding/format/impl/FormatterRegistryImpl.java rename to spring-binding/src/main/java/org/springframework/binding/format/registry/FormatterRegistryImpl.java index 13cc040d..d34d0754 100644 --- a/spring-binding/src/main/java/org/springframework/binding/format/impl/FormatterRegistryImpl.java +++ b/spring-binding/src/main/java/org/springframework/binding/format/registry/FormatterRegistryImpl.java @@ -13,19 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.binding.format.impl; +package org.springframework.binding.format.registry; import java.util.HashMap; import java.util.LinkedList; -import java.util.Locale; import java.util.Map; import org.springframework.binding.format.Formatter; -import org.springframework.binding.format.FormatterFactory; import org.springframework.binding.format.FormatterRegistry; -import org.springframework.context.i18n.LocaleContext; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.util.Assert; /** @@ -36,81 +31,42 @@ import org.springframework.util.Assert; */ public class FormatterRegistryImpl implements FormatterRegistry { - private LocaleContext localeContext = new SimpleLocaleContext(Locale.getDefault()); - private Map formattersById = new HashMap(); private Map formattersByClass = new HashMap(); - /** - * Sets the locale context to use if no locale has been bound to the current thread. Optional. Defaults to a - * {@link SimpleLocaleContext} holding the system default locale. - * @param localeContext the locale context - */ - public void setLocaleContext(LocaleContext localeContext) { - this.localeContext = localeContext; - } - - /** - * Returns the locale in use. - */ - protected Locale getLocale() { - Locale currentLocale = LocaleContextHolder.getLocale(); - if (currentLocale != null) { - return currentLocale; - } else { - return localeContext.getLocale(); - } - } - public Formatter getFormatter(Class clazz) { Assert.notNull(clazz, "The formatted class argument is required"); clazz = convertToWrapperClassIfNecessary(clazz); - FormatterFactory factory = findFormatterFactory(clazz); - if (factory != null) { - FormatterFactoryContextImpl context = new FormatterFactoryContextImpl(); - context.setLocale(getLocale()); - context.setFormattedClass(clazz); - return factory.createFormatter(context); - } else { - return null; - } + return findFormatter(clazz); } - public Formatter getFormatter(String id, Class clazz) { + public Formatter getFormatter(String id) { Assert.hasText(id, "The id of the custom formatter is required"); - FormatterFactory factory = (FormatterFactory) formattersById.get(id); - if (factory != null) { - FormatterFactoryContextImpl context = new FormatterFactoryContextImpl(); - context.setLocale(getLocale()); - context.setFormattedClass(clazz); - return factory.createFormatter(context); - } else { - return null; - } + return (Formatter) formattersById.get(id); } - public void registerFormatter(String id, FormatterFactory factory) { + // impl + + public void registerFormatter(Class clazz, Formatter formatter) { + Assert.notNull(formatter, "The formatter to register is required"); + formattersByClass.put(clazz, formatter); + } + + public void registerFormatter(String id, Formatter formatter) { Assert.hasText(id, "The id of the custom formatter is required"); - Assert.notNull(factory, "The formatter factory is required"); - formattersById.put(id, factory); - Class formattedClass = factory.getFormattedClass(); - if (!formattersByClass.containsKey(formattedClass)) { - formattersByClass.put(formattedClass, factory); - } + Assert.notNull(formatter, "The formatter to register is required"); + formattersById.put(id, formatter); } - public void registerFormatter(FormatterFactory factory) { - Assert.notNull(factory, "The formatter factory is required"); - formattersByClass.put(factory.getFormattedClass(), factory); - } + // helpers - private FormatterFactory findFormatterFactory(Class clazz) { + private Formatter findFormatter(Class clazz) { LinkedList classQueue = new LinkedList(); classQueue.addFirst(clazz); while (!classQueue.isEmpty()) { clazz = (Class) classQueue.removeLast(); - FormatterFactory factory = (FormatterFactory) formattersByClass.get(clazz); + Formatter factory = (Formatter) formattersByClass.get(clazz); if (factory != null) { return factory; } diff --git a/spring-binding/src/main/java/org/springframework/binding/format/impl/package.html b/spring-binding/src/main/java/org/springframework/binding/format/registry/package.html similarity index 100% rename from spring-binding/src/main/java/org/springframework/binding/format/impl/package.html rename to spring-binding/src/main/java/org/springframework/binding/format/registry/package.html diff --git a/spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java b/spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java index 7813eb82..92c2fd57 100644 --- a/spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java +++ b/spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java @@ -1,78 +1,64 @@ package org.springframework.binding.format.impl; import java.math.BigDecimal; -import java.text.NumberFormat; import junit.framework.TestCase; import org.springframework.binding.format.Formatter; -import org.springframework.binding.format.FormatterFactory; -import org.springframework.binding.format.FormatterFactoryContext; import org.springframework.binding.format.InvalidFormatException; -import org.springframework.binding.format.factories.NumberFormatterFactory; +import org.springframework.binding.format.formatters.NumberFormatter; +import org.springframework.binding.format.registry.FormatterRegistryImpl; public class FormatterRegistryImplTests extends TestCase { FormatterRegistryImpl registry = new FormatterRegistryImpl(); public void testRegisterAndGetFormatter() { - registry.registerFormatter(new NumberFormatterFactory()); + registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class)); Formatter formatter = registry.getFormatter(Integer.class); - Integer value = (Integer) formatter.parseValue("3"); + Integer value = (Integer) formatter.parse("3"); assertEquals(new Integer(3), value); } public void testRegisterAndGetFormatterAbstractClass() { - registry.registerFormatter(new NumberFormatterFactory()); - Formatter formatter = registry.getFormatter(Number.class); - Long value = (Long) formatter.parseValue("3"); - assertEquals(new Long(3), value); + registry.registerFormatter(Number.class, new NumberFormatter(Long.class)); + Formatter formatter = registry.getFormatter(Long.class); + Number value = (Number) formatter.parse("3"); + assertEquals(3L, value.longValue()); } public void testRegisterAndGetFormatterPrimitive() { - registry.registerFormatter(new NumberFormatterFactory()); + registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class)); Formatter formatter = registry.getFormatter(int.class); - Integer value = (Integer) formatter.parseValue("3"); + Integer value = (Integer) formatter.parse("3"); assertEquals(new Integer(3), value); } public void testRegisterAndGetFormatterInterface() { - registry.registerFormatter(new CustomTypeFormatterFactory()); + registry.registerFormatter(CustomType.class, new CustomTypeFormatter()); Formatter formatter = registry.getFormatter(DefaultCustomType.class); - assertEquals("12345", formatter.formatValue(new DefaultCustomType("12345"))); - assertEquals(new DefaultCustomType("12345"), formatter.parseValue("12345")); + assertEquals("12345", formatter.format(new DefaultCustomType("12345"))); + assertEquals(new DefaultCustomType("12345"), formatter.parse("12345")); } public void testRegisterCustomFormatter() { - registry.registerFormatter(new NumberFormatterFactory()); - registry.registerFormatter("percentNumberFormat", new PercentNumberFormatterFactory()); - Formatter formatter = registry.getFormatter("percentNumberFormat", BigDecimal.class); - assertEquals("35%", formatter.formatValue(new BigDecimal(".35"))); - BigDecimal value = (BigDecimal) formatter.parseValue("35%"); + registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class)); + NumberFormatter percentFormatter = new NumberFormatter(BigDecimal.class); + percentFormatter.setPattern("00%"); + registry.registerFormatter("percent", percentFormatter); + Formatter formatter = registry.getFormatter("percent"); + assertEquals("35%", formatter.format(new BigDecimal(".35"))); + BigDecimal value = (BigDecimal) formatter.parse("35%"); assertEquals(new BigDecimal(".35"), value); } public void testRegisterCustomFormatterBogusLookupId() { - registry.registerFormatter(new NumberFormatterFactory()); - registry.registerFormatter("percentNumberFormat", new PercentNumberFormatterFactory()); - Formatter formatter = registry.getFormatter("bogusFormat", BigDecimal.class); + registry.registerFormatter(Integer.class, new NumberFormatter(Integer.class)); + registry.registerFormatter("double", new NumberFormatter(Double.class)); + Formatter formatter = registry.getFormatter("bogusFormat"); assertNull(formatter); - formatter = registry.getFormatter(BigDecimal.class); + formatter = registry.getFormatter("double"); assertNotNull(formatter); - assertEquals("0.35", formatter.formatValue(new BigDecimal(".35"))); - BigDecimal value = (BigDecimal) formatter.parseValue("0.35"); - assertEquals(new BigDecimal(".35"), value); - - formatter = registry.getFormatter("percentNumberFormat", BigDecimal.class); - assertEquals("35%", formatter.formatValue(new BigDecimal(".35"))); - value = (BigDecimal) formatter.parseValue("35%"); - assertEquals(new BigDecimal(".35"), value); - } - - public class PercentNumberFormatterFactory extends NumberFormatterFactory implements FormatterFactory { - protected NumberFormat getNumberFormat(FormatterFactoryContext context) { - return NumberFormat.getPercentInstance(); - } } public interface CustomType { @@ -97,27 +83,15 @@ public class FormatterRegistryImplTests extends TestCase { } } - private class CustomTypeFormatterFactory implements FormatterFactory { + private class CustomTypeFormatter implements Formatter { - public Formatter createFormatter(FormatterFactoryContext context) { - return new CustomTypeFormatter(); + public String format(Object value) throws IllegalArgumentException { + CustomType type = (CustomType) value; + return type.getText(); } - public Class getFormattedClass() { - return CustomType.class; - } - - private class CustomTypeFormatter implements Formatter { - - public String formatValue(Object value) throws IllegalArgumentException { - CustomType type = (CustomType) value; - return type.getText(); - } - - public Object parseValue(String formattedString) throws InvalidFormatException { - return new DefaultCustomType(formattedString); - } - + public Object parse(String formattedString) throws InvalidFormatException { + return new DefaultCustomType(formattedString); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java b/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java index dd90bbd0..a75645e5 100644 --- a/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java +++ b/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java @@ -19,11 +19,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils; -import org.springframework.binding.format.FormatterRegistry; -import org.springframework.binding.format.factories.BooleanFormatterFactory; -import org.springframework.binding.format.factories.DateFormatterFactory; -import org.springframework.binding.format.factories.NumberFormatterFactory; -import org.springframework.binding.format.impl.FormatterRegistryImpl; +import org.springframework.binding.format.registry.DefaultFormatterRegistry; import org.springframework.faces.model.converter.FacesConversionService; import org.springframework.faces.webflow.JsfManagedBeanAwareELExpressionParser; import org.springframework.faces.webflow.JsfViewFactoryCreator; @@ -87,7 +83,8 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle if (StringUtils.hasText(formatterRegistry)) { definitionBuilder.addPropertyReference(FORMATTER_REGISTRY_PROPERTY, formatterRegistry); } else { - definitionBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, createDefaultFormatterRegistry()); + definitionBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, DefaultFormatterRegistry + .getSharedInstance()); } } @@ -119,12 +116,4 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle } } - private static FormatterRegistry createDefaultFormatterRegistry() { - FormatterRegistryImpl registry = new FormatterRegistryImpl(); - registry.registerFormatter(new NumberFormatterFactory()); - registry.registerFormatter(new DateFormatterFactory()); - registry.registerFormatter(new BooleanFormatterFactory()); - return registry; - } - } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java index 9ad2406f..1dea37b7 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java @@ -7,11 +7,7 @@ import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.binding.convert.service.DefaultConversionService; -import org.springframework.binding.format.FormatterRegistry; -import org.springframework.binding.format.factories.BooleanFormatterFactory; -import org.springframework.binding.format.factories.DateFormatterFactory; -import org.springframework.binding.format.factories.NumberFormatterFactory; -import org.springframework.binding.format.impl.FormatterRegistryImpl; +import org.springframework.binding.format.registry.DefaultFormatterRegistry; import org.springframework.util.StringUtils; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import org.springframework.webflow.expression.DefaultExpressionParserFactory; @@ -57,7 +53,8 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti if (StringUtils.hasText(formatterRegistry)) { definitionBuilder.addPropertyReference(FORMATTER_REGISTRY_PROPERTY, formatterRegistry); } else { - definitionBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, createDefaultFormatterRegistry()); + definitionBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, DefaultFormatterRegistry + .getSharedInstance()); } } @@ -102,8 +99,8 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti public static BeanDefinitionHolder registerDefaultFlowBuilderServicesBeanDefinition(ParserContext context) { FlowBuilderServicesBeanDefinitionParser parser = new FlowBuilderServicesBeanDefinitionParser(); BeanDefinitionBuilder defaultBuilder = BeanDefinitionBuilder.genericBeanDefinition(FlowBuilderServices.class); - defaultBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, createDefaultFormatterRegistry()); - defaultBuilder.addPropertyValue(CONVERSION_SERVICE_PROPERTY, new DefaultConversionService()); + defaultBuilder.addPropertyValue(FORMATTER_REGISTRY_PROPERTY, DefaultFormatterRegistry.getSharedInstance()); + defaultBuilder.addPropertyValue(CONVERSION_SERVICE_PROPERTY, DefaultConversionService.getSharedInstance()); defaultBuilder.addPropertyValue(EXPRESSION_PARSER_PROPERTY, DefaultExpressionParserFactory .getExpressionParser()); defaultBuilder.addPropertyReference(VIEW_FACTORY_CREATOR_PROPERTY, parser.createBeanDefinitionForClass( @@ -114,12 +111,4 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti return holder; } - private static FormatterRegistry createDefaultFormatterRegistry() { - FormatterRegistryImpl registry = new FormatterRegistryImpl(); - registry.registerFormatter(new NumberFormatterFactory()); - registry.registerFormatter(new DateFormatterFactory()); - registry.registerFormatter(new BooleanFormatterFactory()); - return registry; - } - } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java b/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java index 2bdd4756..18f61b47 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java @@ -305,7 +305,7 @@ public class LocalParameterMap implements ParameterMap, Serializable { private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); parameterAccessor = new MapAccessor(parameters); - conversionService = new DefaultConversionService(); + conversionService = DefaultConversionService.getSharedInstance(); } public String toString() { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java index 383a2a6f..6030a491 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java @@ -72,7 +72,7 @@ public class BindingModel extends ViewRenderingErrors { Expression fieldExpression = parseFieldExpression(field); Formatter formatter = getFormatter(fieldExpression); if (formatter != null) { - return formatter.formatValue(fieldExpression.getValue(boundObject)); + return formatter.format(fieldExpression.getValue(boundObject)); } else { return fieldExpression.getValue(boundObject); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java index 0c622075..c05c74fa 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java @@ -176,9 +176,10 @@ class MvcView implements View { private void addDefaultMappings(DefaultMapper mapper, ParameterMap requestParameters, Object model) { for (Iterator it = requestParameters.asMap().keySet().iterator(); it.hasNext();) { String name = (String) it.next(); - Expression source = expressionParser - .parseExpression(name, new FluentParserContext().evaluate(MapAdaptable.class)); - Expression target = expressionParser.parseExpression(name, new FluentParserContext().evaluate(model.getClass())); + Expression source = expressionParser.parseExpression(name, new FluentParserContext() + .evaluate(MapAdaptable.class)); + Expression target = expressionParser.parseExpression(name, new FluentParserContext().evaluate(model + .getClass())); DefaultMapping mapping = new DefaultMapping(source, target); mapping.setTypeConverter(new FormatterBackedMappingConversionExecutor(formatterRegistry)); mapper.addMapping(mapping); @@ -273,7 +274,7 @@ class MvcView implements View { Formatter formatter = getFormatter(target, targetClass); if (formatter != null) { try { - return formatter.parseValue(formattedValue); + return formatter.parse(formattedValue); } catch (InvalidFormatException e) { throw new ConversionException(String.class, targetClass, e); } @@ -284,7 +285,7 @@ class MvcView implements View { private Formatter getFormatter(Expression target, Class targetClass) { if (formatterRegistry != null) { - Formatter formatter = formatterRegistry.getFormatter(target.getExpressionString(), targetClass); + Formatter formatter = formatterRegistry.getFormatter(target.getExpressionString()); if (formatter != null) { return formatter; } else { diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java index 3b3f194c..cd86a7fb 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java @@ -11,9 +11,8 @@ import javax.servlet.http.HttpServletResponse; import junit.framework.TestCase; import org.springframework.binding.expression.support.StaticExpression; -import org.springframework.binding.format.factories.DateFormatterFactory; -import org.springframework.binding.format.factories.NumberFormatterFactory; -import org.springframework.binding.format.impl.FormatterRegistryImpl; +import org.springframework.binding.format.FormatterRegistry; +import org.springframework.binding.format.registry.DefaultFormatterRegistry; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletContext; @@ -28,12 +27,7 @@ public class MvcViewTests extends TestCase { private Map model; - private FormatterRegistryImpl formatterRegistry = new FormatterRegistryImpl(); - - public void setUp() { - formatterRegistry.registerFormatter(new NumberFormatterFactory()); - formatterRegistry.registerFormatter(new DateFormatterFactory()); - } + private FormatterRegistry formatterRegistry = DefaultFormatterRegistry.getSharedInstance(); public void testRender() throws Exception { MockRequestContext context = new MockRequestContext(); @@ -83,7 +77,7 @@ public class MvcViewTests extends TestCase { assertNotNull(bm); assertEquals(null, bm.getFieldValue("stringProperty")); assertEquals("3", bm.getFieldValue("integerProperty")); - assertEquals("1/1/08", bm.getFieldValue("dateProperty")); + assertEquals("Jan 1, 2008", bm.getFieldValue("dateProperty")); } public void testResumeNoEvent() throws Exception { @@ -119,7 +113,7 @@ public class MvcViewTests extends TestCase { context.putRequestParameter("_eventId", "submit"); context.putRequestParameter("stringProperty", "foo"); context.putRequestParameter("integerProperty", "5"); - context.putRequestParameter("dateProperty", "1/1/07"); + context.putRequestParameter("dateProperty", "Jan 1, 2007"); BindBean bindBean = new BindBean(); StaticExpression modelObject = new StaticExpression(bindBean); modelObject.setExpressionString("bindBean");