|
|
|
|
@@ -32,7 +32,7 @@ import org.junit.After;
|
|
|
|
|
import org.junit.Before;
|
|
|
|
|
import org.junit.Test;
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
|
|
import org.springframework.aop.framework.ProxyFactory;
|
|
|
|
|
import org.springframework.beans.ConfigurablePropertyAccessor;
|
|
|
|
|
import org.springframework.beans.PropertyAccessorFactory;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
@@ -45,6 +45,7 @@ import org.springframework.context.support.GenericApplicationContext;
|
|
|
|
|
import org.springframework.core.convert.ConversionFailedException;
|
|
|
|
|
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.DefaultConversionService;
|
|
|
|
|
import org.springframework.format.Formatter;
|
|
|
|
|
import org.springframework.format.Printer;
|
|
|
|
|
@@ -81,7 +82,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testFormatFieldForTypeWithFormatter() throws ParseException {
|
|
|
|
|
public void formatFieldForTypeWithFormatter() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
|
|
|
|
String formatted = formattingService.convert(3, String.class);
|
|
|
|
|
assertEquals("3", formatted);
|
|
|
|
|
@@ -90,7 +91,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testFormatFieldForTypeWithPrinterParserWithCoercion() throws ParseException {
|
|
|
|
|
public void formatFieldForTypeWithPrinterParserWithCoercion() throws ParseException {
|
|
|
|
|
formattingService.addConverter(new Converter<DateTime, LocalDate>() {
|
|
|
|
|
@Override
|
|
|
|
|
public LocalDate convert(DateTime source) {
|
|
|
|
|
@@ -107,7 +108,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@SuppressWarnings("resource")
|
|
|
|
|
public void testFormatFieldForValueInjection() {
|
|
|
|
|
public void formatFieldForValueInjection() {
|
|
|
|
|
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
|
|
|
|
|
ac.registerBeanDefinition("valueBean", new RootBeanDefinition(ValueBean.class));
|
|
|
|
|
ac.registerBeanDefinition("conversionService", new RootBeanDefinition(FormattingConversionServiceFactoryBean.class));
|
|
|
|
|
@@ -118,7 +119,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@SuppressWarnings("resource")
|
|
|
|
|
public void testFormatFieldForValueInjectionUsingMetaAnnotations() {
|
|
|
|
|
public void formatFieldForValueInjectionUsingMetaAnnotations() {
|
|
|
|
|
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
|
|
|
|
|
RootBeanDefinition bd = new RootBeanDefinition(MetaValueBean.class);
|
|
|
|
|
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
|
|
|
|
@@ -140,20 +141,20 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testFormatFieldForAnnotation() throws Exception {
|
|
|
|
|
public void formatFieldForAnnotation() throws Exception {
|
|
|
|
|
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
|
|
|
|
|
doTestFormatFieldForAnnotation(Model.class, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testFormatFieldForAnnotationWithDirectFieldAccess() throws Exception {
|
|
|
|
|
public void formatFieldForAnnotationWithDirectFieldAccess() throws Exception {
|
|
|
|
|
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
|
|
|
|
|
doTestFormatFieldForAnnotation(Model.class, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@SuppressWarnings("resource")
|
|
|
|
|
public void testFormatFieldForAnnotationWithPlaceholders() throws Exception {
|
|
|
|
|
public void formatFieldForAnnotationWithPlaceholders() throws Exception {
|
|
|
|
|
GenericApplicationContext context = new GenericApplicationContext();
|
|
|
|
|
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
|
|
|
|
Properties props = new Properties();
|
|
|
|
|
@@ -169,7 +170,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@SuppressWarnings("resource")
|
|
|
|
|
public void testFormatFieldForAnnotationWithPlaceholdersAndFactoryBean() throws Exception {
|
|
|
|
|
public void formatFieldForAnnotationWithPlaceholdersAndFactoryBean() throws Exception {
|
|
|
|
|
GenericApplicationContext context = new GenericApplicationContext();
|
|
|
|
|
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
|
|
|
|
Properties props = new Properties();
|
|
|
|
|
@@ -239,61 +240,61 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testPrintNull() throws ParseException {
|
|
|
|
|
public void printNull() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
|
|
|
|
assertEquals("", formattingService.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testParseNull() throws ParseException {
|
|
|
|
|
public void parseNull() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
|
|
|
|
assertNull(formattingService
|
|
|
|
|
.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testParseEmptyString() throws ParseException {
|
|
|
|
|
public void parseEmptyString() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
|
|
|
|
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testParseBlankString() throws ParseException {
|
|
|
|
|
public void parseBlankString() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
|
|
|
|
assertNull(formattingService.convert(" ", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test(expected = ConversionFailedException.class)
|
|
|
|
|
public void testParseParserReturnsNull() throws ParseException {
|
|
|
|
|
public void parseParserReturnsNull() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Integer.class, new NullReturningFormatter());
|
|
|
|
|
assertNull(formattingService.convert("1", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test(expected = ConversionFailedException.class)
|
|
|
|
|
public void testParseNullPrimitiveProperty() throws ParseException {
|
|
|
|
|
public void parseNullPrimitiveProperty() throws ParseException {
|
|
|
|
|
formattingService.addFormatterForFieldType(Integer.class, new NumberStyleFormatter());
|
|
|
|
|
assertNull(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(int.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testPrintNullDefault() throws ParseException {
|
|
|
|
|
public void printNullDefault() throws ParseException {
|
|
|
|
|
assertEquals(null, formattingService
|
|
|
|
|
.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testParseNullDefault() throws ParseException {
|
|
|
|
|
public void parseNullDefault() throws ParseException {
|
|
|
|
|
assertNull(formattingService
|
|
|
|
|
.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testParseEmptyStringDefault() throws ParseException {
|
|
|
|
|
public void parseEmptyStringDefault() throws ParseException {
|
|
|
|
|
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testFormatFieldForAnnotationWithSubclassAsFieldType() throws Exception {
|
|
|
|
|
public void formatFieldForAnnotationWithSubclassAsFieldType() throws Exception {
|
|
|
|
|
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory() {
|
|
|
|
|
@Override
|
|
|
|
|
public Printer<?> getPrinter(org.springframework.format.annotation.DateTimeFormat annotation, Class<?> fieldType) {
|
|
|
|
|
@@ -319,7 +320,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testRegisterDefaultValueViaFormatter() {
|
|
|
|
|
public void registerDefaultValueViaFormatter() {
|
|
|
|
|
registerDefaultValue(Date.class, new Date());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -340,6 +341,45 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void introspectedFormatter() throws ParseException {
|
|
|
|
|
formattingService.addFormatter(new NumberStyleFormatter());
|
|
|
|
|
assertNull(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void proxiedFormatter() throws ParseException {
|
|
|
|
|
Formatter<?> formatter = new NumberStyleFormatter();
|
|
|
|
|
formattingService.addFormatter((Formatter<?>) new ProxyFactory(formatter).getProxy());
|
|
|
|
|
assertNull(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void introspectedConverter() {
|
|
|
|
|
formattingService.addConverter(new IntegerConverter());
|
|
|
|
|
assertEquals(Integer.valueOf(1), formattingService.convert("1", Integer.class));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void proxiedConverter() {
|
|
|
|
|
Converter<?, ?> converter = new IntegerConverter();
|
|
|
|
|
formattingService.addConverter((Converter<?, ?>) new ProxyFactory(converter).getProxy());
|
|
|
|
|
assertEquals(Integer.valueOf(1), formattingService.convert("1", Integer.class));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void introspectedConverterFactory() {
|
|
|
|
|
formattingService.addConverterFactory(new IntegerConverterFactory());
|
|
|
|
|
assertEquals(Integer.valueOf(1), formattingService.convert("1", Integer.class));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void proxiedConverterFactory() {
|
|
|
|
|
ConverterFactory<?, ?> converterFactory = new IntegerConverterFactory();
|
|
|
|
|
formattingService.addConverterFactory((ConverterFactory<?, ?>) new ProxyFactory(converterFactory).getProxy());
|
|
|
|
|
assertEquals(Integer.valueOf(1), formattingService.convert("1", Integer.class));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class ValueBean {
|
|
|
|
|
|
|
|
|
|
@@ -348,6 +388,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
public Date date;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class MetaValueBean {
|
|
|
|
|
|
|
|
|
|
@MyDateAnn
|
|
|
|
|
@@ -357,18 +398,21 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
public Double number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Value("${myDate}")
|
|
|
|
|
@org.springframework.format.annotation.DateTimeFormat(pattern="MM-d-yy")
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
|
|
public static @interface MyDateAnn {
|
|
|
|
|
public @interface MyDateAnn {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Value("${myNumber}")
|
|
|
|
|
@NumberFormat(style = NumberFormat.Style.PERCENT)
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
|
|
public static @interface MyNumberAnn {
|
|
|
|
|
public @interface MyNumberAnn {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class Model {
|
|
|
|
|
|
|
|
|
|
@org.springframework.format.annotation.DateTimeFormat(style="S-")
|
|
|
|
|
@@ -386,6 +430,7 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class ModelWithPlaceholders {
|
|
|
|
|
|
|
|
|
|
@org.springframework.format.annotation.DateTimeFormat(style="${dateStyle}")
|
|
|
|
|
@@ -403,11 +448,13 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@org.springframework.format.annotation.DateTimeFormat(pattern="${datePattern}")
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
|
|
|
public static @interface MyDatePattern {
|
|
|
|
|
public @interface MyDatePattern {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class NullReturningFormatter implements Formatter<Integer> {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -419,17 +466,42 @@ public class FormattingConversionServiceTests {
|
|
|
|
|
public Integer parse(String text, Locale locale) throws ParseException {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("serial")
|
|
|
|
|
public static class MyDate extends Date {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ModelWithSubclassField {
|
|
|
|
|
|
|
|
|
|
@org.springframework.format.annotation.DateTimeFormat(style = "S-")
|
|
|
|
|
public MyDate date;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class IntegerConverter implements Converter<String, Integer> {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Integer convert(String source) {
|
|
|
|
|
return Integer.parseInt(source);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class IntegerConverterFactory implements ConverterFactory<String, Number> {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) {
|
|
|
|
|
if (Integer.class == targetType) {
|
|
|
|
|
return (Converter<String, T>) new IntegerConverter();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
throw new IllegalStateException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|