Added AnnotatioFormatterFactory allowing Formatters to be created from property @Annotation values; polish
This commit is contained in:
parent
534871e6f6
commit
65c90c56c0
|
|
@ -2,6 +2,9 @@ package org.springframework.ui.binding;
|
|||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -10,8 +13,11 @@ import java.util.Map;
|
|||
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.TypeConverter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.core.convert.support.DefaultTypeConverter;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
|
|
@ -22,6 +28,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|||
import org.springframework.expression.spel.standard.SpelExpressionParserConfiguration;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
import org.springframework.ui.format.AnnotationFormatterFactory;
|
||||
import org.springframework.ui.format.Formatter;
|
||||
|
||||
public class Binder<T> {
|
||||
|
|
@ -32,9 +39,9 @@ public class Binder<T> {
|
|||
|
||||
private Map<String, Binding> bindings;
|
||||
|
||||
private Map<Class<?>, Formatter<?>> typeFormatters = new HashMap<Class<?>, Formatter<?>>();
|
||||
private Map<Class, Formatter> typeFormatters = new HashMap<Class, Formatter>();
|
||||
|
||||
private Map<Class<?>, Formatter<?>> annotationFormatters = new HashMap<Class<?>, Formatter<?>>();
|
||||
private Map<Class, AnnotationFormatterFactory> annotationFormatters = new HashMap<Class, AnnotationFormatterFactory>();
|
||||
|
||||
private ExpressionParser expressionParser;
|
||||
|
||||
|
|
@ -43,11 +50,7 @@ public class Binder<T> {
|
|||
private boolean strict = false;
|
||||
|
||||
private static Formatter defaultFormatter = new Formatter() {
|
||||
|
||||
public Class<?> getFormattedObjectType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
|
||||
public String format(Object object, Locale locale) {
|
||||
if (object == null) {
|
||||
return "";
|
||||
|
|
@ -92,15 +95,17 @@ public class Binder<T> {
|
|||
}
|
||||
|
||||
public void add(Formatter<?> formatter, Class<?> propertyType) {
|
||||
if (propertyType == null) {
|
||||
propertyType = formatter.getFormattedObjectType();
|
||||
}
|
||||
if (propertyType.isAnnotation()) {
|
||||
annotationFormatters.put(propertyType, formatter);
|
||||
annotationFormatters.put(propertyType, new SimpleAnnotationFormatterFactory(formatter));
|
||||
} else {
|
||||
typeFormatters.put(propertyType, formatter);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO determine Annotation type from factory using reflection
|
||||
public void add(AnnotationFormatterFactory<?, ?> factory) {
|
||||
annotationFormatters.put(getAnnotationType(factory), factory);
|
||||
}
|
||||
|
||||
public T getModel() {
|
||||
return model;
|
||||
|
|
@ -152,12 +157,13 @@ public class Binder<T> {
|
|||
}
|
||||
|
||||
public void setValue(String formatted) {
|
||||
setValue(parse(formatted));
|
||||
setValue(parse(formatted, getFormatter()));
|
||||
}
|
||||
|
||||
public String format(Object selectableValue) {
|
||||
Formatter formatter = getFormatter();
|
||||
selectableValue = typeConverter.convert(selectableValue, formatter.getFormattedObjectType());
|
||||
Class<?> formattedType = getFormattedObjectType(formatter);
|
||||
selectableValue = typeConverter.convert(selectableValue, formattedType);
|
||||
return formatter.format(selectableValue, LocaleContextHolder.getLocale());
|
||||
}
|
||||
|
||||
|
|
@ -192,9 +198,14 @@ public class Binder<T> {
|
|||
}
|
||||
|
||||
public void setValues(String[] formattedValues) {
|
||||
Object values = Array.newInstance(getFormatter().getFormattedObjectType(), formattedValues.length);
|
||||
Formatter formatter = getFormatter();
|
||||
Class parsedType = getFormattedObjectType(formatter);
|
||||
if (parsedType == null) {
|
||||
parsedType = String.class;
|
||||
}
|
||||
Object values = Array.newInstance(parsedType, formattedValues.length);
|
||||
for (int i = 0; i < formattedValues.length; i++) {
|
||||
Array.set(values, i, parse(formattedValues[i]));
|
||||
Array.set(values, i, parse(formattedValues[i], formatter));
|
||||
}
|
||||
setValue(values);
|
||||
}
|
||||
|
|
@ -205,14 +216,15 @@ public class Binder<T> {
|
|||
|
||||
// internal helpers
|
||||
|
||||
private Object parse(String formatted) {
|
||||
private Object parse(String formatted, Formatter formatter) {
|
||||
try {
|
||||
return getFormatter().parse(formatted, LocaleContextHolder.getLocale());
|
||||
return formatter.parse(formatted, LocaleContextHolder.getLocale());
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("Invalid format " + formatted, e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Formatter getFormatter() {
|
||||
if (formatter != null) {
|
||||
return formatter;
|
||||
|
|
@ -224,9 +236,9 @@ public class Binder<T> {
|
|||
} else {
|
||||
Annotation[] annotations = getAnnotations();
|
||||
for (Annotation a : annotations) {
|
||||
formatter = annotationFormatters.get(a.annotationType());
|
||||
if (formatter != null) {
|
||||
return formatter;
|
||||
AnnotationFormatterFactory factory = annotationFormatters.get(a.annotationType());
|
||||
if (factory != null) {
|
||||
return factory.getFormatter(a);
|
||||
}
|
||||
}
|
||||
return defaultFormatter;
|
||||
|
|
@ -276,4 +288,66 @@ public class Binder<T> {
|
|||
context.setTypeConverter(new StandardTypeConverter(typeConverter));
|
||||
return context;
|
||||
}
|
||||
|
||||
private Class getAnnotationType(AnnotationFormatterFactory factory) {
|
||||
Class classToIntrospect = factory.getClass();
|
||||
while (classToIntrospect != null) {
|
||||
Type[] genericInterfaces = classToIntrospect.getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
if (genericInterface instanceof ParameterizedType) {
|
||||
ParameterizedType pInterface = (ParameterizedType) genericInterface;
|
||||
if (AnnotationFormatterFactory.class.isAssignableFrom((Class) pInterface.getRawType())) {
|
||||
return getParameterClass(pInterface.getActualTypeArguments()[0], factory.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
classToIntrospect = classToIntrospect.getSuperclass();
|
||||
}
|
||||
throw new IllegalArgumentException("Unable to extract Annotation type A argument from AnnotationFormatterFactory ["
|
||||
+ factory.getClass().getName() + "]; does the factory parameterize the <A> generic type?");
|
||||
}
|
||||
|
||||
private Class getFormattedObjectType(Formatter formatter) {
|
||||
// TODO consider caching this info
|
||||
Class classToIntrospect = formatter.getClass();
|
||||
while (classToIntrospect != null) {
|
||||
Type[] genericInterfaces = classToIntrospect.getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
if (genericInterface instanceof ParameterizedType) {
|
||||
ParameterizedType pInterface = (ParameterizedType) genericInterface;
|
||||
if (Formatter.class.isAssignableFrom((Class) pInterface.getRawType())) {
|
||||
return getParameterClass(pInterface.getActualTypeArguments()[0], formatter.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
classToIntrospect = classToIntrospect.getSuperclass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Class getParameterClass(Type parameterType, Class converterClass) {
|
||||
if (parameterType instanceof TypeVariable) {
|
||||
parameterType = GenericTypeResolver.resolveTypeVariable((TypeVariable) parameterType, converterClass);
|
||||
}
|
||||
if (parameterType instanceof Class) {
|
||||
return (Class) parameterType;
|
||||
}
|
||||
throw new IllegalArgumentException("Unable to obtain the java.lang.Class for parameterType [" + parameterType
|
||||
+ "] on Formatter [" + converterClass.getName() + "]");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static class SimpleAnnotationFormatterFactory implements AnnotationFormatterFactory {
|
||||
|
||||
private Formatter formatter;
|
||||
|
||||
public SimpleAnnotationFormatterFactory(Formatter formatter) {
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
public Formatter getFormatter(Annotation annotation) {
|
||||
return formatter;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package org.springframework.ui.format;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
public interface AnnotationFormatterFactory<A extends Annotation, T> {
|
||||
Formatter<T> getFormatter(A annotation);
|
||||
}
|
||||
|
|
@ -50,10 +50,6 @@ public class DateFormatter implements Formatter<Date> {
|
|||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public Class<Date> getFormattedObjectType() {
|
||||
return Date.class;
|
||||
}
|
||||
|
||||
public String format(Date date, Locale locale) {
|
||||
if (date == null) {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -25,12 +25,6 @@ import java.util.Locale;
|
|||
*/
|
||||
public interface Formatter<T> {
|
||||
|
||||
/**
|
||||
* Returns the type of object this formatter can format.
|
||||
* @return the formatted object type
|
||||
*/
|
||||
Class<T> getFormattedObjectType();
|
||||
|
||||
/**
|
||||
* Format the object of type T for display.
|
||||
* @param object the object to format
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2004-2009 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.ui.format;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
|
||||
/**
|
||||
* A factory for adapting formatting and parsing logic in a {@link Formatter} to the {@link Converter} contract.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class FormatterConverterFactory {
|
||||
|
||||
/**
|
||||
* Register converter adapters for the formatter.
|
||||
* An adapter will be registered for formatting to String as well as parsing from String.
|
||||
* @param <T> The type of formatter
|
||||
* @param formatter the formatter
|
||||
* @param registry the converter registry
|
||||
*/
|
||||
public static <T> void add(Formatter<T> formatter,
|
||||
ConverterRegistry registry) {
|
||||
registry.add(new FormattingConverter<T>(formatter));
|
||||
registry.add(new ParsingConverter<T>(formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the Formatter/converter adapters previously registered for the formatted type.
|
||||
* @param <T> the formatted type
|
||||
* @param formattedType the formatted type
|
||||
* @param registry the converter registry
|
||||
*/
|
||||
public static <T> void remove(Class<T> formattedType,
|
||||
ConverterRegistry registry) {
|
||||
registry.removeConverter(formattedType, String.class);
|
||||
registry.removeConverter(String.class, formattedType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright 2004-2009 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.ui.format;
|
||||
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
class FormattingConverter<T> implements Converter<T, String> {
|
||||
|
||||
private Formatter<T> formatter;
|
||||
|
||||
public FormattingConverter(Formatter<T> formatter) {
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
public Class<T> getSourceType() {
|
||||
return formatter.getFormattedObjectType();
|
||||
}
|
||||
|
||||
public Class<String> getTargetType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public String convert(T source) {
|
||||
return formatter.format(source, LocaleContextHolder.getLocale());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright 2004-2009 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.ui.format;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
class ParsingConverter<T> implements Converter<String, T> {
|
||||
|
||||
private Formatter<T> formatter;
|
||||
|
||||
public ParsingConverter(Formatter<T> formatter) {
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
public T convert(String source) throws ParseException {
|
||||
return formatter.parse(source, LocaleContextHolder.getLocale());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package org.springframework.ui.format.number;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.ui.format.AnnotationFormatterFactory;
|
||||
import org.springframework.ui.format.Formatter;
|
||||
|
||||
public class CurrencyAnnotationFormatterFactory implements AnnotationFormatterFactory<CurrencyFormat, BigDecimal> {
|
||||
public Formatter<BigDecimal> getFormatter(CurrencyFormat annotation) {
|
||||
return new CurrencyFormatter();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.springframework.ui.format.number;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* A annotation to apply to a BigDecimal property to have property values formatted as currency using a {@link CurrencyFormatter}.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
@Target( { ElementType.METHOD, ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface CurrencyFormat {
|
||||
|
||||
}
|
||||
|
|
@ -38,10 +38,6 @@ public class CurrencyFormatter implements Formatter<BigDecimal> {
|
|||
|
||||
private boolean lenient;
|
||||
|
||||
public Class<BigDecimal> getFormattedObjectType() {
|
||||
return BigDecimal.class;
|
||||
}
|
||||
|
||||
public String format(BigDecimal decimal, Locale locale) {
|
||||
if (decimal == null) {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import java.util.Locale;
|
|||
|
||||
/**
|
||||
* Produces NumberFormat instances that format currency values.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see NumberFormat
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -40,10 +40,6 @@ public class DecimalFormatter implements Formatter<BigDecimal> {
|
|||
initDefaults();
|
||||
}
|
||||
|
||||
public Class<BigDecimal> getFormattedObjectType() {
|
||||
return BigDecimal.class;
|
||||
}
|
||||
|
||||
public DecimalFormatter(String pattern) {
|
||||
initDefaults();
|
||||
formatFactory.setPattern(pattern);
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ public class IntegerFormatter implements Formatter<Long> {
|
|||
|
||||
private boolean lenient;
|
||||
|
||||
public Class<Long> getFormattedObjectType() {
|
||||
return Long.class;
|
||||
}
|
||||
|
||||
public String format(Long integer, Locale locale) {
|
||||
if (integer == null) {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@ public class PercentFormatter implements Formatter<BigDecimal> {
|
|||
|
||||
private boolean lenient;
|
||||
|
||||
public Class<BigDecimal> getFormattedObjectType() {
|
||||
return BigDecimal.class;
|
||||
}
|
||||
|
||||
public String format(BigDecimal decimal, Locale locale) {
|
||||
if (decimal == null) {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import static org.junit.Assert.assertFalse;
|
|||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
|
@ -22,6 +20,8 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.ui.format.DateFormatter;
|
||||
import org.springframework.ui.format.number.CurrencyAnnotationFormatterFactory;
|
||||
import org.springframework.ui.format.number.CurrencyFormat;
|
||||
import org.springframework.ui.format.number.CurrencyFormatter;
|
||||
import org.springframework.ui.format.number.IntegerFormatter;
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ public class BinderTests {
|
|||
|
||||
// TODO should update error context, not throw exception
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void bindSingleValuesWithDefaultTypeCoversionFailures() {
|
||||
public void bindSingleValuesWithDefaultTypeCoversionFailure() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
Map<String, String> propertyValues = new HashMap<String, String>();
|
||||
propertyValues.put("string", "test");
|
||||
|
|
@ -62,7 +62,7 @@ public class BinderTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void bindSingleValuePropertyFormatterParsing() throws ParseException {
|
||||
public void bindSingleValuePropertyFormatter() throws ParseException {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new BindingConfiguration("date", new DateFormatter()));
|
||||
Map<String, String> propertyValues = new HashMap<String, String>();
|
||||
|
|
@ -82,7 +82,7 @@ public class BinderTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void bindSingleValueTypeFormatterParsing() throws ParseException {
|
||||
public void bindSingleValueWithFormatterRegistedByType() throws ParseException {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new DateFormatter(), Date.class);
|
||||
Map<String, String> propertyValues = new HashMap<String, String>();
|
||||
|
|
@ -92,9 +92,19 @@ public class BinderTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void bindSingleValueAnnotationFormatterParsing() throws ParseException {
|
||||
public void bindSingleValueWithFormatterRegisteredByAnnotation() throws ParseException {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new CurrencyFormatter(), Currency.class);
|
||||
binder.add(new CurrencyFormatter(), CurrencyFormat.class);
|
||||
Map<String, String> propertyValues = new HashMap<String, String>();
|
||||
propertyValues.put("currency", "$23.56");
|
||||
binder.bind(propertyValues);
|
||||
assertEquals(new BigDecimal("23.56"), binder.getModel().getCurrency());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindSingleValueWithnAnnotationFormatterFactoryRegistered() throws ParseException {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new CurrencyAnnotationFormatterFactory());
|
||||
Map<String, String> propertyValues = new HashMap<String, String>();
|
||||
propertyValues.put("currency", "$23.56");
|
||||
binder.bind(propertyValues);
|
||||
|
|
@ -261,7 +271,7 @@ public class BinderTests {
|
|||
this.foo = foo;
|
||||
}
|
||||
|
||||
@Currency
|
||||
@CurrencyFormat
|
||||
public BigDecimal getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
|
@ -288,11 +298,6 @@ public class BinderTests {
|
|||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Currency {
|
||||
|
||||
}
|
||||
|
||||
public static class Address {
|
||||
private String street;
|
||||
private String city;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
package org.springframework.ui.message.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.context.support.StaticMessageSource;
|
||||
import org.springframework.ui.message.Message;
|
||||
import org.springframework.ui.message.MessageBuilder;
|
||||
|
|
@ -24,6 +26,12 @@ public class DefaultMessageContextTests {
|
|||
messageSource.addMessage("invalidFormat", Locale.US, "{0} must be in format {1}");
|
||||
messageSource.addMessage("mathForm.decimalField", Locale.US, "Decimal Field");
|
||||
context = new DefaultMessageContext(messageSource);
|
||||
LocaleContextHolder.setLocale(Locale.US);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
LocaleContextHolder.setLocale(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue