diff --git a/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java b/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java
new file mode 100644
index 00000000000..7749230f676
--- /dev/null
+++ b/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2010 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.context;
+
+import org.springframework.util.StringValueResolver;
+
+/**
+ * Interface to be implemented by any object that wishes to be notified of a
+ * StringValueResolver for the resolution of embedded definition values.
+ *
+ *
This is an alternative to a full ConfigurableBeanFactory dependency via the
+ * ApplicationContextAware/BeanFactoryAware interfaces.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0.3
+ * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
+ */
+public interface EmbeddedValueResolverAware {
+
+ /**
+ * Set the StringValueResolver to use for resolving embedded definition values.
+ */
+ void setEmbeddedValueResolver(StringValueResolver resolver);
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java b/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java
index 7e1da6a5e56..d40ca72323d 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java
@@ -22,11 +22,14 @@ import java.security.PrivilegedAction;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
+import org.springframework.util.StringValueResolver;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
@@ -86,6 +89,10 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
}
private void invokeAwareInterfaces(Object bean) {
+ if (bean instanceof EmbeddedValueResolverAware) {
+ ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
+ new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
+ }
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
@@ -104,4 +111,18 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
return bean;
}
+
+ private static class EmbeddedValueResolver implements StringValueResolver {
+
+ private final ConfigurableBeanFactory beanFactory;
+
+ public EmbeddedValueResolver(ConfigurableBeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+ public String resolveStringValue(String strVal) {
+ return this.beanFactory.resolveEmbeddedValue(strVal);
+ }
+ }
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java b/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java
index 51eeeddae2d..227729ad52b 100644
--- a/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java
+++ b/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2010 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.
@@ -31,12 +31,14 @@ import org.joda.time.ReadableInstant;
import org.joda.time.ReadablePartial;
import org.joda.time.format.DateTimeFormatter;
+import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.util.StringUtils;
+import org.springframework.util.StringValueResolver;
/**
* Formats fields annotated with the {@link DateTimeFormat} annotation.
@@ -46,9 +48,12 @@ import org.springframework.util.StringUtils;
* @since 3.0
* @see DateTimeFormat
*/
-public final class JodaDateTimeFormatAnnotationFormatterFactory implements AnnotationFormatterFactory {
+public class JodaDateTimeFormatAnnotationFormatterFactory
+ implements AnnotationFormatterFactory, EmbeddedValueResolverAware {
private final Set> fieldTypes;
+
+ private StringValueResolver embeddedValueResolver;
public JodaDateTimeFormatAnnotationFormatterFactory() {
@@ -64,11 +69,20 @@ public final class JodaDateTimeFormatAnnotationFormatterFactory implements Annot
this.fieldTypes = Collections.unmodifiableSet(rawFieldTypes);
}
- public Set> getFieldTypes() {
+ public final Set> getFieldTypes() {
return this.fieldTypes;
}
+ public void setEmbeddedValueResolver(StringValueResolver resolver) {
+ this.embeddedValueResolver = resolver;
+ }
+
+ protected String resolveEmbeddedValue(String value) {
+ return (this.embeddedValueResolver != null ? this.embeddedValueResolver.resolveStringValue(value) : value);
+ }
+
+
public Printer> getPrinter(DateTimeFormat annotation, Class> fieldType) {
DateTimeFormatter formatter = configureDateTimeFormatterFrom(annotation);
if (ReadableInstant.class.isAssignableFrom(fieldType)) {
@@ -92,24 +106,26 @@ public final class JodaDateTimeFormatAnnotationFormatterFactory implements Annot
}
- // internal helpers
-
private DateTimeFormatter configureDateTimeFormatterFrom(DateTimeFormat annotation) {
if (StringUtils.hasLength(annotation.pattern())) {
- return forPattern(annotation.pattern());
+ return forPattern(resolveEmbeddedValue(annotation.pattern()));
}
else if (annotation.iso() != ISO.NONE) {
return forIso(annotation.iso());
}
else {
- return forStyle(annotation.style());
+ return forStyle(resolveEmbeddedValue(annotation.style()));
}
}
private DateTimeFormatter forPattern(String pattern) {
return org.joda.time.format.DateTimeFormat.forPattern(pattern);
}
-
+
+ private DateTimeFormatter forStyle(String style) {
+ return org.joda.time.format.DateTimeFormat.forStyle(style);
+ }
+
private DateTimeFormatter forIso(ISO iso) {
if (iso == ISO.DATE) {
return org.joda.time.format.ISODateTimeFormat.date();
@@ -122,8 +138,4 @@ public final class JodaDateTimeFormatAnnotationFormatterFactory implements Annot
}
}
- private DateTimeFormatter forStyle(String style) {
- return org.joda.time.format.DateTimeFormat.forStyle(style);
- }
-
}
diff --git a/org.springframework.context/src/main/java/org/springframework/format/number/NumberFormatAnnotationFormatterFactory.java b/org.springframework.context/src/main/java/org/springframework/format/number/NumberFormatAnnotationFormatterFactory.java
index 09da26668b6..7ae4021945a 100644
--- a/org.springframework.context/src/main/java/org/springframework/format/number/NumberFormatAnnotationFormatterFactory.java
+++ b/org.springframework.context/src/main/java/org/springframework/format/number/NumberFormatAnnotationFormatterFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2010 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.
@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Formatter;
import org.springframework.format.Parser;
@@ -29,6 +30,7 @@ import org.springframework.format.Printer;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;
import org.springframework.util.StringUtils;
+import org.springframework.util.StringValueResolver;
/**
* Formats fields annotated with the {@link NumberFormat} annotation.
@@ -37,46 +39,52 @@ import org.springframework.util.StringUtils;
* @since 3.0
* @see NumberFormat
*/
-public final class NumberFormatAnnotationFormatterFactory implements AnnotationFormatterFactory {
+public class NumberFormatAnnotationFormatterFactory
+ implements AnnotationFormatterFactory, EmbeddedValueResolverAware {
private final Set> fieldTypes;
+ private StringValueResolver embeddedValueResolver;
+
public NumberFormatAnnotationFormatterFactory() {
- this.fieldTypes = Collections.unmodifiableSet(createFieldTypes());
+ Set> rawFieldTypes = new HashSet>(7);
+ rawFieldTypes.add(Short.class);
+ rawFieldTypes.add(Integer.class);
+ rawFieldTypes.add(Long.class);
+ rawFieldTypes.add(Float.class);
+ rawFieldTypes.add(Double.class);
+ rawFieldTypes.add(BigDecimal.class);
+ rawFieldTypes.add(BigInteger.class);
+ this.fieldTypes = Collections.unmodifiableSet(rawFieldTypes);
}
-
- public Set> getFieldTypes() {
+ public final Set> getFieldTypes() {
return this.fieldTypes;
}
- public Printer getPrinter(NumberFormat annotation, Class> fieldType) {
- return configureFormatterFrom(annotation, fieldType);
+
+ public void setEmbeddedValueResolver(StringValueResolver resolver) {
+ this.embeddedValueResolver = resolver;
}
-
- public Parser getParser(NumberFormat annotation, Class> fieldType) {
- return configureFormatterFrom(annotation, fieldType);
+
+ protected String resolveEmbeddedValue(String value) {
+ return (this.embeddedValueResolver != null ? this.embeddedValueResolver.resolveStringValue(value) : value);
}
- // internal helpers
+ public Printer getPrinter(NumberFormat annotation, Class> fieldType) {
+ return configureFormatterFrom(annotation);
+ }
- private Set> createFieldTypes() {
- Set> fieldTypes = new HashSet>(7);
- fieldTypes.add(Short.class);
- fieldTypes.add(Integer.class);
- fieldTypes.add(Long.class);
- fieldTypes.add(Float.class);
- fieldTypes.add(Double.class);
- fieldTypes.add(BigDecimal.class);
- fieldTypes.add(BigInteger.class);
- return fieldTypes;
+ public Parser getParser(NumberFormat annotation, Class> fieldType) {
+ return configureFormatterFrom(annotation);
}
- private Formatter configureFormatterFrom(NumberFormat annotation, Class> fieldType) {
+
+ private Formatter configureFormatterFrom(NumberFormat annotation) {
if (StringUtils.hasLength(annotation.pattern())) {
- return new NumberFormatter(annotation.pattern());
+ return new NumberFormatter(resolveEmbeddedValue(annotation.pattern()));
}
else {
Style style = annotation.style();
diff --git a/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java b/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java
index 1830ef212e2..3e3ad01e3b8 100644
--- a/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java
+++ b/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2010 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.
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.convert.ConversionService;
@@ -35,6 +36,7 @@ import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
+import org.springframework.util.StringValueResolver;
/**
* A {@link org.springframework.core.convert.ConversionService} implementation
@@ -44,7 +46,22 @@ import org.springframework.format.Printer;
* @author Juergen Hoeller
* @since 3.0
*/
-public class FormattingConversionService extends GenericConversionService implements FormatterRegistry {
+public class FormattingConversionService extends GenericConversionService
+ implements FormatterRegistry, EmbeddedValueResolverAware {
+
+ private StringValueResolver embeddedValueResolver;
+
+ private final Map cachedPrinters =
+ new ConcurrentHashMap();
+
+ private final Map cachedParsers =
+ new ConcurrentHashMap();
+
+
+ public void setEmbeddedValueResolver(StringValueResolver resolver) {
+ this.embeddedValueResolver = resolver;
+ }
+
public void addFormatterForFieldType(Class> fieldType, Formatter> formatter) {
addConverter(new PrinterConverter(fieldType, formatter, this));
@@ -61,16 +78,14 @@ public class FormattingConversionService extends GenericConversionService implem
final Class extends Annotation> annotationType = (Class extends Annotation>)
GenericTypeResolver.resolveTypeArgument(annotationFormatterFactory.getClass(), AnnotationFormatterFactory.class);
if (annotationType == null) {
- throw new IllegalArgumentException(
- "Unable to extract parameterized Annotation type argument from AnnotationFormatterFactory ["
- + annotationFormatterFactory.getClass().getName()
- + "]; does the factory parameterize the generic type?");
- }
- Set> fieldTypes = annotationFormatterFactory.getFieldTypes();
+ throw new IllegalArgumentException("Unable to extract parameterized Annotation type argument from AnnotationFormatterFactory [" +
+ annotationFormatterFactory.getClass().getName() + "]; does the factory parameterize the generic type?");
+ }
+ if (this.embeddedValueResolver != null && annotationFormatterFactory instanceof EmbeddedValueResolverAware) {
+ ((EmbeddedValueResolverAware) annotationFormatterFactory).setEmbeddedValueResolver(this.embeddedValueResolver);
+ }
- final Map cachedPrinters = new ConcurrentHashMap();
- final Map cachedParsers = new ConcurrentHashMap();
-
+ Set> fieldTypes = annotationFormatterFactory.getFieldTypes();
for (final Class> fieldType : fieldTypes) {
addConverter(new ConditionalGenericConverter() {
public Set getConvertibleTypes() {
@@ -119,6 +134,7 @@ public class FormattingConversionService extends GenericConversionService implem
}
}
+
private static final class FieldFormatterKey {
private final Annotation annotation;
@@ -147,11 +163,11 @@ public class FormattingConversionService extends GenericConversionService implem
}
public int hashCode() {
- return this.annotation.hashCode() + this.fieldType.hashCode();
+ return this.annotation.hashCode() + 29 * this.fieldType.hashCode();
}
-
}
+
private static class PrinterConverter implements GenericConverter {
private Class> fieldType;
@@ -191,6 +207,7 @@ public class FormattingConversionService extends GenericConversionService implem
}
}
+
private static class ParserConverter implements GenericConverter {
private Class> fieldType;
@@ -230,7 +247,6 @@ public class FormattingConversionService extends GenericConversionService implem
public String toString() {
return String.class.getName() + " -> " + this.fieldType.getName() + ": " + this.parser;
}
-
}
}
diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
index f76c9973515..74ced65a7ea 100644
--- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
+++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
@@ -26,7 +26,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
@@ -35,6 +35,7 @@ import org.springframework.scheduling.support.MethodInvokingRunnable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
+import org.springframework.util.StringValueResolver;
/**
* Bean post-processor that registers methods annotated with {@link Scheduled @Scheduled}
@@ -47,11 +48,14 @@ import org.springframework.util.ReflectionUtils.MethodCallback;
* @see Scheduled
* @see org.springframework.scheduling.TaskScheduler
*/
-public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered,
- ApplicationContextAware, ApplicationListener, DisposableBean {
+public class ScheduledAnnotationBeanPostProcessor
+ implements BeanPostProcessor, Ordered, EmbeddedValueResolverAware, ApplicationContextAware,
+ ApplicationListener, DisposableBean {
private Object scheduler;
+ private StringValueResolver embeddedValueResolver;
+
private ApplicationContext applicationContext;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
@@ -72,6 +76,10 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
this.scheduler = scheduler;
}
+ public void setEmbeddedValueResolver(StringValueResolver resolver) {
+ this.embeddedValueResolver = resolver;
+ }
+
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@@ -102,17 +110,16 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
try {
runnable.prepare();
}
- catch (Exception e) {
- throw new IllegalStateException("failed to prepare task", e);
+ catch (Exception ex) {
+ throw new IllegalStateException("failed to prepare task", ex);
}
boolean processedSchedule = false;
String errorMessage = "Exactly one of 'cron', 'fixedDelay', or 'fixedRate' is required.";
String cron = annotation.cron();
if (!"".equals(cron)) {
processedSchedule = true;
- if (applicationContext instanceof ConfigurableApplicationContext) {
- cron = ((ConfigurableApplicationContext) applicationContext)
- .getBeanFactory().resolveEmbeddedValue(cron);
+ if (embeddedValueResolver != null) {
+ cron = embeddedValueResolver.resolveStringValue(cron);
}
cronTasks.put(runnable, cron);
}
diff --git a/org.springframework.context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java b/org.springframework.context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java
index dd5610d0199..44d324e567a 100644
--- a/org.springframework.context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java
+++ b/org.springframework.context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java
@@ -335,7 +335,6 @@ public class JodaTimeFormattingTests {
@DateTimeFormat
private DateTime dateTimeAnnotatedDefault;
- @DateTimeFormat(style="S-")
private Long millisAnnotated;
@DateTimeFormat(pattern="M/d/yy h:mm a")
@@ -480,11 +479,12 @@ public class JodaTimeFormattingTests {
this.millis = millis;
}
+ @DateTimeFormat(style="S-")
public Long getMillisAnnotated() {
return millisAnnotated;
}
- public void setMillisAnnotated(Long millisAnnotated) {
+ public void setMillisAnnotated(@DateTimeFormat(style="S-") Long millisAnnotated) {
this.millisAnnotated = millisAnnotated;
}
diff --git a/org.springframework.context/src/test/java/org/springframework/format/number/NumberFormattingTests.java b/org.springframework.context/src/test/java/org/springframework/format/number/NumberFormattingTests.java
index 6fae27fd36c..ceeb262c074 100644
--- a/org.springframework.context/src/test/java/org/springframework/format/number/NumberFormattingTests.java
+++ b/org.springframework.context/src/test/java/org/springframework/format/number/NumberFormattingTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2010 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.
@@ -17,8 +17,8 @@
package org.springframework.format.number;
import java.math.BigDecimal;
-import java.util.Locale;
import java.util.List;
+import java.util.Locale;
import org.junit.After;
import static org.junit.Assert.*;
@@ -31,6 +31,7 @@ import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;
import org.springframework.format.support.FormattingConversionService;
+import org.springframework.util.StringValueResolver;
import org.springframework.validation.DataBinder;
/**
@@ -46,6 +47,16 @@ public class NumberFormattingTests {
@Before
public void setUp() {
ConversionServiceFactory.addDefaultConverters(conversionService);
+ conversionService.setEmbeddedValueResolver(new StringValueResolver() {
+ public String resolveStringValue(String strVal) {
+ if ("${pattern}".equals(strVal)) {
+ return "#,##.00";
+ }
+ else {
+ return strVal;
+ }
+ }
+ });
conversionService.addFormatterForFieldType(Number.class, new NumberFormatter());
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
LocaleContextHolder.setLocale(Locale.US);
@@ -154,7 +165,7 @@ public class NumberFormattingTests {
@NumberFormat(style=Style.PERCENT)
private BigDecimal percent;
- @NumberFormat(pattern="#,##.00")
+ @NumberFormat(pattern="${pattern}")
private BigDecimal pattern;
@NumberFormat(pattern="#,##.00")
diff --git a/org.springframework.context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java b/org.springframework.context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java
index e187e7d2e06..144db168ff2 100644
--- a/org.springframework.context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java
+++ b/org.springframework.context/src/test/java/org/springframework/format/support/FormattingConversionServiceTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2010 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.
@@ -16,22 +16,24 @@
package org.springframework.format.support;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
+import java.util.Properties;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.junit.After;
+import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
+
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory;
@@ -70,7 +72,7 @@ public class FormattingConversionServiceTests {
}
@Test
- public void testFormatFieldForTypeWithPrinterParserWithCoersion() throws ParseException {
+ public void testFormatFieldForTypeWithPrinterParserWithCoercion() throws ParseException {
formattingService.addConverter(new Converter() {
public LocalDate convert(DateTime source) {
return source.toLocalDate();
@@ -86,6 +88,24 @@ public class FormattingConversionServiceTests {
@Test
public void testFormatFieldForAnnotation() throws Exception {
+ doTestFormatFieldForAnnotation(Model.class);
+ }
+
+ @Test
+ public void testFormatFieldForAnnotationWithPlaceholders() throws Exception {
+ GenericApplicationContext context = new GenericApplicationContext();
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ Properties props = new Properties();
+ props.setProperty("dateStyle", "S-");
+ props.setProperty("datePattern", "M/d/yy");
+ ppc.setProperties(props);
+ context.getBeanFactory().registerSingleton("ppc", ppc);
+ context.refresh();
+ context.getBeanFactory().initializeBean(formattingService, "formattingService");
+ doTestFormatFieldForAnnotation(ModelWithPlaceholders.class);
+ }
+
+ private void doTestFormatFieldForAnnotation(Class> modelClass) throws Exception {
formattingService.addConverter(new Converter() {
public Long convert(Date source) {
return source.getTime();
@@ -97,34 +117,23 @@ public class FormattingConversionServiceTests {
}
});
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
+
String formatted = (String) formattingService.convert(new LocalDate(2009, 10, 31).toDateTimeAtCurrentTime()
- .toDate(), new TypeDescriptor(Model.class.getField("date")), TypeDescriptor.valueOf(String.class));
+ .toDate(), new TypeDescriptor(modelClass.getField("date")), TypeDescriptor.valueOf(String.class));
assertEquals("10/31/09", formatted);
LocalDate date = new LocalDate(formattingService.convert("10/31/09", TypeDescriptor.valueOf(String.class),
- new TypeDescriptor(Model.class.getField("date"))));
+ new TypeDescriptor(modelClass.getField("date"))));
assertEquals(new LocalDate(2009, 10, 31), date);
- }
-
- @Test
- public void testFormatCollectionFieldForAnnotation() throws Exception {
- formattingService.addConverter(new Converter() {
- public Long convert(Date source) {
- return source.getTime();
- }
- });
- formattingService.addConverter(new Converter() {
- public Date convert(DateTime source) {
- return source.toDate();
- }
- });
- formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
+
List dates = new ArrayList();
dates.add(new LocalDate(2009, 10, 31).toDateTimeAtCurrentTime().toDate());
dates.add(new LocalDate(2009, 11, 1).toDateTimeAtCurrentTime().toDate());
dates.add(new LocalDate(2009, 11, 2).toDateTimeAtCurrentTime().toDate());
- String formatted = (String) formattingService.convert(dates, new TypeDescriptor(Model.class.getField("dates")), TypeDescriptor.valueOf(String.class));
+ formatted = (String) formattingService.convert(dates,
+ new TypeDescriptor(modelClass.getField("dates")), TypeDescriptor.valueOf(String.class));
assertEquals("10/31/09,11/1/09,11/2/09", formatted);
- dates = (List) formattingService.convert("10/31/09,11/1/09,11/2/09", TypeDescriptor.valueOf(String.class), new TypeDescriptor(Model.class.getField("dates")));
+ dates = (List) formattingService.convert("10/31/09,11/1/09,11/2/09",
+ TypeDescriptor.valueOf(String.class), new TypeDescriptor(modelClass.getField("dates")));
assertEquals(new LocalDate(2009, 10, 31), new LocalDate(dates.get(0)));
assertEquals(new LocalDate(2009, 11, 1), new LocalDate(dates.get(1)));
assertEquals(new LocalDate(2009, 11, 2), new LocalDate(dates.get(2)));
@@ -163,6 +172,7 @@ public class FormattingConversionServiceTests {
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
}
+
private static class Model {
@SuppressWarnings("unused")
@@ -170,7 +180,20 @@ public class FormattingConversionServiceTests {
public Date date;
@SuppressWarnings("unused")
- @org.springframework.format.annotation.DateTimeFormat(style="S-")
+ @org.springframework.format.annotation.DateTimeFormat(pattern="M/d/yy")
+ public List dates;
+
+ }
+
+
+ private static class ModelWithPlaceholders {
+
+ @SuppressWarnings("unused")
+ @org.springframework.format.annotation.DateTimeFormat(style="${dateStyle}")
+ public Date date;
+
+ @SuppressWarnings("unused")
+ @org.springframework.format.annotation.DateTimeFormat(pattern="${datePattern}")
public List dates;
}