formatter improvements

This commit is contained in:
Keith Donald
2008-03-18 20:45:30 +00:00
parent 61735958e9
commit 1809e7341a
26 changed files with 471 additions and 588 deletions

View File

@@ -15,34 +15,37 @@
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.format.FormatterFactory;
import org.springframework.binding.convert.ConversionContext;
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 FormatterFactory that is expected to provide us with thread-safe instances as necessary.
* 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 factory.
* The formatter registry.
*/
private FormatterFactory formatterFactory;
private FormatterRegistry formatterRegistry;
/**
* Creates a new converter that delegates to a formatter.
* @param formatterFactory the factory to use
* @param formatterRegistry the formatterRegistry to use
*/
protected AbstractFormattingConverter(FormatterFactory formatterFactory) {
setFormatterFactory(formatterFactory);
protected AbstractFormattingConverter(FormatterRegistry formatterRegistry) {
Assert.notNull(formatterRegistry, "The formatter registry is required");
this.formatterRegistry = formatterRegistry;
}
protected FormatterFactory getFormatterFactory() {
return formatterFactory;
public FormatterRegistry getFormatterRegistry() {
return formatterRegistry;
}
public void setFormatterFactory(FormatterFactory formatterSource) {
this.formatterFactory = formatterSource;
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
return getFormatterRegistry().getFormatter(targetClass).parseValue((String) source);
}
}

View File

@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
* supported. If you need this capability, use a Formatter with a FormatterPropertyEditor adapter.
*
* @see org.springframework.binding.format.Formatter
* @see org.springframework.binding.format.support.FormatterPropertyEditor
* @see org.springframework.binding.format.adapters.FormatterPropertyEditor
*
* @author Keith Donald
*/

View File

@@ -18,7 +18,10 @@ package org.springframework.binding.convert.support;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.springframework.binding.format.support.SimpleFormatterFactory;
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;
import org.springframework.core.enums.LabeledEnum;
/**
@@ -29,10 +32,16 @@ import org.springframework.core.enums.LabeledEnum;
*/
public class DefaultConversionService extends GenericConversionService {
/**
* Returns the formatter registry used by this conversion service
*/
private FormatterRegistry formatterRegistry;
/**
* Creates a new default conversion service, installing the default converters.
*/
public DefaultConversionService() {
formatterRegistry = createDefaultFormatterRegistry();
addDefaultConverters();
}
@@ -41,11 +50,10 @@ public class DefaultConversionService extends GenericConversionService {
*/
protected void addDefaultConverters() {
addConverter(new TextToClass());
addConverter(new TextToNumber(new SimpleFormatterFactory()));
addConverter(new TextToBoolean());
addConverter(new TextToLabeledEnum());
// we're not using addDefaultAlias here for efficiency reasons
addConverter(new TextToNumber(formatterRegistry));
addConverter(new TextToDate(formatterRegistry));
addAlias("string", String.class);
addAlias("short", Short.class);
addAlias("integer", Integer.class);
@@ -60,4 +68,11 @@ public class DefaultConversionService extends GenericConversionService {
addAlias("class", Class.class);
addAlias("labeledEnum", LabeledEnum.class);
}
protected FormatterRegistry createDefaultFormatterRegistry() {
FormatterRegistryImpl registry = new FormatterRegistryImpl();
registry.registerFormatter(new NumberFormatterFactory());
registry.registerFormatter(new DateFormatterFactory());
return registry;
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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.support;
import java.util.Date;
import org.springframework.binding.format.FormatterRegistry;
/**
* Converts textual representations of numbers to a <code>Number</code> 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 };
}
}

View File

@@ -18,9 +18,7 @@ package org.springframework.binding.convert.support;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.binding.format.FormatterFactory;
import org.springframework.binding.format.support.SimpleFormatterFactory;
import org.springframework.binding.format.FormatterRegistry;
/**
* Converts textual representations of numbers to a <code>Number</code> specialization. Delegates to a synchronized
@@ -30,19 +28,12 @@ import org.springframework.binding.format.support.SimpleFormatterFactory;
*/
public class TextToNumber extends AbstractFormattingConverter {
/**
* Default constructor that uses a {@link SimpleFormatterFactory}.
*/
public TextToNumber() {
super(new SimpleFormatterFactory());
}
/**
* Create a string to number converter using given formatter factory.
* @param formatterFactory the factory to use
* @param formatterRegistry the formatter registry to use
*/
public TextToNumber(FormatterFactory formatterFactory) {
super(formatterFactory);
public TextToNumber(FormatterRegistry formatterRegistry) {
super(formatterRegistry);
}
public Class[] getSourceClasses() {
@@ -53,8 +44,4 @@ 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, ConversionContext context) throws Exception {
return getFormatterFactory().getNumberFormatter(targetClass).parseValue((String) source, targetClass);
}
}

View File

@@ -17,7 +17,10 @@ package org.springframework.binding.format;
/**
* A lightweight interface for formatting a value and parsing a value from its formatted form.
*
* <p>
* Note: formatters are typically not thread safe as <code>Format</code> objects aren't thread safe. In general, you
* should not attempt to share formatters between threads.
* </p>
* @author Keith Donald
*/
public interface Formatter {
@@ -33,10 +36,9 @@ public interface Formatter {
/**
* Parse the formatted string representation of a value, restoring the value.
* @param formattedString the formatted string representation
* @param targetClass the target class to convert the formatted value to
* @return the parsed value
* @throws InvalidFormatException the string was in an invalid form
*/
public Object parseValue(String formattedString, Class targetClass) throws InvalidFormatException;
public Object parseValue(String formattedString) throws InvalidFormatException;
}

View File

@@ -0,0 +1,21 @@
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();
}

View File

@@ -0,0 +1,46 @@
/*
* 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;
/**
* Source for shared and commonly used <code>Formatters</code>.
* <p>
* Note: formatters are typically not thread safe as <code>Format</code> objects aren't thread safe. In general, you
* should not attempt to share formatters between threads.
* </p>
* @see java.text.Format
*
* @author Keith Donald
*/
public interface FormatterRegistry {
/**
* Returns the default formatter installed for the given class of object.
* @param clazz the type of object that will be formatted
* @return the formatter
*/
public Formatter getFormatter(Class clazz);
/**
* 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);
}

View File

@@ -0,0 +1,28 @@
package org.springframework.binding.format;
public class NoSuchFormatterException extends RuntimeException {
private Class formatterFormattedClass;
private String formatterId;
public NoSuchFormatterException(Class formatterFormattedClass) {
super("No default formatter for class " + formatterFormattedClass + "; make sure a formatter is registered");
this.formatterFormattedClass = formatterFormattedClass;
}
public NoSuchFormatterException(String formatterId, Class formatterFormattedClass) {
super("No custom formatter could be found with id '" + formatterId + "' for class " + formatterFormattedClass
+ "; check your spelling and make sure the formatter is registered");
this.formatterId = formatterId;
}
public Class getFormatterFormattedClass() {
return formatterFormattedClass;
}
public String getFormatterId() {
return formatterId;
}
}

View File

@@ -1,55 +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;
import java.text.DateFormat;
import org.springframework.core.enums.StaticLabeledEnum;
/**
* Format styles, similar to those defined by {@link java.text.DateFormat}.
*
* @author Keith Donald
*/
public class Style extends StaticLabeledEnum {
/**
* See {@link java.text.DateFormat#FULL}.
*/
public static final Style FULL = new Style(DateFormat.FULL, "Full");
/**
* See {@link java.text.DateFormat#LONG}.
*/
public static final Style LONG = new Style(DateFormat.LONG, "Long");
/**
* See {@link java.text.DateFormat#MEDIUM}.
*/
public static final Style MEDIUM = new Style(DateFormat.MEDIUM, "Medium");
/**
* See {@link java.text.DateFormat#SHORT}.
*/
public static final Style SHORT = new Style(DateFormat.SHORT, "Short");
/**
* Private constructor since this is a type-safe enum.
*/
private Style(int code, String label) {
super(code, label);
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.format.support;
package org.springframework.binding.format.adapters;
import java.beans.PropertyEditorSupport;
@@ -31,11 +31,6 @@ public class FormatterPropertyEditor extends PropertyEditorSupport {
*/
private Formatter formatter;
/**
* The target value class (may be null).
*/
private Class targetClass;
/**
* Creates a formatter property editor.
* @param formatter the formatter to adapt
@@ -44,21 +39,11 @@ public class FormatterPropertyEditor extends PropertyEditorSupport {
this.formatter = formatter;
}
/**
* Creates a formatter property editor.
* @param formatter the formatter to adapt
* @param targetClass the target class for "setAsText" conversions
*/
public FormatterPropertyEditor(Formatter formatter, Class targetClass) {
this.formatter = formatter;
this.targetClass = targetClass;
}
public String getAsText() {
return formatter.formatValue(getValue());
}
public void setAsText(String text) throws IllegalArgumentException {
setValue(formatter.parseValue(text, targetClass));
setValue(formatter.parseValue(text));
}
}

View File

@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.format.support;
package org.springframework.binding.format.adapters;
import java.beans.PropertyEditor;
import org.springframework.binding.format.factories.AbstractFormatter;
import org.springframework.util.Assert;
/**
@@ -48,7 +49,7 @@ public class PropertyEditorFormatter extends AbstractFormatter {
return propertyEditor.getAsText();
}
protected Object doParseValue(String formattedValue, Class targetClass) {
protected Object doParseValue(String formattedValue) {
propertyEditor.setAsText(formattedValue);
return propertyEditor.getValue();
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.format.support;
package org.springframework.binding.format.factories;
import java.text.ParseException;
@@ -42,14 +42,14 @@ public abstract class AbstractFormatter implements Formatter {
}
}
public final Object parseValue(String formattedString, Class targetClass) throws InvalidFormatException {
public final Object parseValue(String formattedString) throws InvalidFormatException {
try {
if (isEmpty(formattedString)) {
return getEmptyValue();
}
return doParseValue(formattedString, targetClass);
return doParseValue(formattedString);
} catch (ParseException ex) {
throw new InvalidFormatException(formattedString, getExpectedFormat(targetClass), ex);
throw new InvalidFormatException(formattedString, getExpectedFormat(), ex);
}
}
@@ -70,13 +70,11 @@ public abstract class AbstractFormatter implements Formatter {
/**
* Template method subclasses should override to encapsulate parsing logic.
* @param formattedString the formatted string to parse
* @param targetClass the target class to convert the formatted value to
* @return the parsed value
* @throws InvalidFormatException an exception occurred parsing
* @throws ParseException when parse exceptions occur
*/
protected abstract Object doParseValue(String formattedString, Class targetClass) throws InvalidFormatException,
ParseException;
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
@@ -89,7 +87,7 @@ public abstract class AbstractFormatter implements Formatter {
/**
* Returns the expected string format for the given target class. The default implementation just returns null.
*/
protected String getExpectedFormat(Class targetClass) {
protected String getExpectedFormat() {
return null;
}

View File

@@ -0,0 +1,59 @@
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;
/**
* 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());
}
private 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);
}
}
}

View File

@@ -0,0 +1,74 @@
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.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());
}
}
private 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);
}
}
}
}

View File

@@ -0,0 +1,29 @@
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;
}
}

View File

@@ -0,0 +1,113 @@
/*
* 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.impl;
import java.util.HashMap;
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.binding.format.NoSuchFormatterException;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.i18n.SimpleLocaleContext;
/**
* Base class for formatter factories. Manages the locale used by the produced formatters using Spring's
* {@link org.springframework.context.i18n.LocaleContext} system.
*
* @author Keith Donald
*/
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) {
FormatterFactory factory = findFormatterFactory(clazz);
if (factory != null) {
FormatterFactoryContextImpl context = new FormatterFactoryContextImpl();
context.setLocale(getLocale());
context.setFormattedClass(clazz);
return factory.createFormatter(context);
} else {
throw new NoSuchFormatterException(clazz);
}
}
public Formatter getFormatter(String id, Class clazz) {
FormatterFactory factory = (FormatterFactory) formattersById.get(id);
if (factory != null) {
FormatterFactoryContextImpl context = new FormatterFactoryContextImpl();
context.setLocale(getLocale());
context.setFormattedClass(clazz);
return factory.createFormatter(context);
} else {
throw new NoSuchFormatterException(id, clazz);
}
}
private FormatterFactory findFormatterFactory(Class clazz) {
FormatterFactory factory = (FormatterFactory) formattersByClass.get(clazz);
if (factory != null) {
return factory;
} else {
if (clazz.getSuperclass() != Object.class) {
return findFormatterFactory(clazz.getSuperclass());
} else {
return null;
}
}
}
public void registerFormatter(String id, FormatterFactory factory) {
formattersById.put(id, factory);
Class formattedClass = factory.getFormattedClass();
if (!formattersByClass.containsKey(formattedClass)) {
formattersByClass.put(formattedClass, factory);
}
}
public void registerFormatter(FormatterFactory factory) {
formattersByClass.put(factory.getFormattedClass(), factory);
}
}

View File

@@ -1,93 +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.support;
import java.util.Locale;
import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.FormatterFactory;
import org.springframework.binding.format.Style;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.SimpleLocaleContext;
/**
* Base class for formatter factories. Manages the locale used by the produced formatters using Spring's
* {@link org.springframework.context.i18n.LocaleContext} system.
*
* @author Keith Donald
*/
public abstract class AbstractFormatterFactory implements FormatterFactory {
private LocaleContext localeContext = new SimpleLocaleContext(Locale.getDefault());
private Style defaultDateStyle = Style.MEDIUM;
private Style defaultTimeStyle = Style.MEDIUM;
/**
* Sets the locale context used. Defaults to a {@link SimpleLocaleContext} holding the system default locale.
*/
public void setLocaleContext(LocaleContext localeContext) {
this.localeContext = localeContext;
}
/**
* Returns the locale in use.
*/
protected Locale getLocale() {
return localeContext.getLocale();
}
/**
* Returns the default date style. Defaults to {@link Style#MEDIUM}.
*/
protected Style getDefaultDateStyle() {
return defaultDateStyle;
}
/**
* Set the default date style.
*/
public void setDefaultDateStyle(Style defaultDateStyle) {
this.defaultDateStyle = defaultDateStyle;
}
/**
* Returns the default time style. Defaults to {@link Style#MEDIUM}.
*/
public Style getDefaultTimeStyle() {
return defaultTimeStyle;
}
/**
* Set the default time style.
*/
public void setDefaultTimeStyle(Style defaultTimeStyle) {
this.defaultTimeStyle = defaultTimeStyle;
}
public Formatter getDateFormatter() {
return getDateFormatter(getDefaultDateStyle());
}
public Formatter getDateTimeFormatter() {
return getDateTimeFormatter(getDefaultDateStyle(), getDefaultTimeStyle());
}
public Formatter getTimeFormatter() {
return getTimeFormatter(getDefaultTimeStyle());
}
}

View File

@@ -1,57 +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.support;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import org.springframework.binding.format.InvalidFormatException;
/**
* Formatter that formats date objects.
*
* @author Keith Donald
*/
public 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, Class targetClass) throws ParseException {
return dateFormat.parse(formattedString);
}
/**
* Convenience method to parse a date.
*/
public Date parseDate(String formattedString) throws InvalidFormatException {
return (Date) parseValue(formattedString, Date.class);
}
}

View File

@@ -1,62 +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.support;
import org.springframework.binding.format.InvalidFormatException;
import org.springframework.core.enums.LabeledEnum;
import org.springframework.core.enums.LabeledEnumResolver;
import org.springframework.core.enums.StaticLabeledEnumResolver;
import org.springframework.util.Assert;
/**
* Converts from string to a <cod>LabeledEnum</code> instance and back.
*
* @author Keith Donald
*/
public class LabeledEnumFormatter extends AbstractFormatter {
private LabeledEnumResolver labeledEnumResolver = StaticLabeledEnumResolver.instance();
/**
* Default constructor.
*/
public LabeledEnumFormatter() {
}
/**
* Set the LabeledEnumResolver used. Defaults to {@link StaticLabeledEnumResolver}.
*/
public void setLabeledEnumResolver(LabeledEnumResolver labeledEnumResolver) {
Assert.notNull(labeledEnumResolver, "The labeled enum resolver is required");
this.labeledEnumResolver = labeledEnumResolver;
}
protected String doFormatValue(Object value) {
LabeledEnum labeledEnum = (LabeledEnum) value;
return labeledEnum.getLabel();
}
protected Object doParseValue(String formattedString, Class targetClass) throws IllegalArgumentException {
return labeledEnumResolver.getLabeledEnumByLabel(targetClass, formattedString);
}
/**
* Convenience method to parse a LabeledEnum.
*/
public LabeledEnum parseLabeledEnum(String formattedString, Class enumClass) throws InvalidFormatException {
return (LabeledEnum) parseValue(formattedString, enumClass);
}
}

View File

@@ -1,95 +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.support;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.NumberFormat;
import org.springframework.binding.format.InvalidFormatException;
import org.springframework.util.NumberUtils;
/**
* Converts from various <code>Number</code> specializations to <code>String</code> and back.
*
* @author Keith Donald
*/
public class NumberFormatter extends AbstractFormatter {
private NumberFormat numberFormat;
/**
* Create a new number formatter.
* @param numberFormat the number format to use
*/
public NumberFormatter(NumberFormat numberFormat) {
this.numberFormat = numberFormat;
}
protected String doFormatValue(Object number) {
if (this.numberFormat != null) {
// use NumberFormat for rendering value
return this.numberFormat.format(number);
} else {
// use toString method for rendering value
return number.toString();
}
}
protected Object doParseValue(String text, Class targetClass) throws IllegalArgumentException {
if (this.numberFormat != null) {
// use given NumberFormat for parsing text
return NumberUtils.parseNumber(text, targetClass, this.numberFormat);
} else {
// use default valueOf methods for parsing text
return NumberUtils.parseNumber(text, targetClass);
}
}
// convenience methods
public Byte parseByte(String formattedString) throws InvalidFormatException {
return (Byte) parseValue(formattedString, Byte.class);
}
public Short parseShort(String formattedString) throws InvalidFormatException {
return (Short) parseValue(formattedString, Short.class);
}
public Integer parseInteger(String formattedString) throws InvalidFormatException {
return (Integer) parseValue(formattedString, Integer.class);
}
public Long parseLong(String formattedString) throws InvalidFormatException {
return (Long) parseValue(formattedString, Long.class);
}
public Float parseFloat(String formattedString) throws InvalidFormatException {
return (Float) parseValue(formattedString, Float.class);
}
public Double parseDouble(String formattedString) throws InvalidFormatException {
return (Double) parseValue(formattedString, Double.class);
}
public BigInteger parseBigInteger(String formattedString) throws InvalidFormatException {
return (BigInteger) parseValue(formattedString, BigInteger.class);
}
public BigDecimal parseBigDecimal(String formattedString) throws InvalidFormatException {
return (BigDecimal) parseValue(formattedString, BigDecimal.class);
}
}

View File

@@ -1,63 +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.support;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.Style;
/**
* Simple FormatterFactory implementation.
*
* @author Keith Donald
*/
public class SimpleFormatterFactory extends AbstractFormatterFactory {
public Formatter getDateFormatter(Style style) {
return new DateFormatter(SimpleDateFormat.getDateInstance(style.shortValue(), getLocale()));
}
public Formatter getDateTimeFormatter(Style dateStyle, Style timeStyle) {
return new DateFormatter(SimpleDateFormat.getDateTimeInstance(dateStyle.shortValue(), timeStyle.shortValue(),
getLocale()));
}
public Formatter getTimeFormatter(Style style) {
return new DateFormatter(SimpleDateFormat.getTimeInstance(style.shortValue(), getLocale()));
}
public Formatter getNumberFormatter(Class numberClass) {
if (numberClass.equals(Integer.class) || numberClass.equals(int.class)) {
return new NumberFormatter(NumberFormat.getIntegerInstance(getLocale()));
} else {
return new NumberFormatter(NumberFormat.getNumberInstance(getLocale()));
}
}
public Formatter getCurrencyFormatter() {
return new NumberFormatter(NumberFormat.getCurrencyInstance(getLocale()));
}
public Formatter getDateFormatter(String encodedFormat) {
return new DateFormatter(new SimpleDateFormat(encodedFormat, getLocale()));
}
public Formatter getPercentFormatter() {
return new NumberFormatter(NumberFormat.getPercentInstance(getLocale()));
}
}