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 279cc5b811a..852bc77d900 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 @@ -51,11 +51,11 @@ public class FormattingConversionService extends GenericConversionService private StringValueResolver embeddedValueResolver; - private final Map cachedPrinters = - new ConcurrentHashMap(); + private final Map cachedPrinters = + new ConcurrentHashMap(); - private final Map cachedParsers = - new ConcurrentHashMap(); + private final Map cachedParsers = + new ConcurrentHashMap(); public void setEmbeddedValueResolver(StringValueResolver resolver) { @@ -93,90 +93,13 @@ public class FormattingConversionService extends GenericConversionService if (this.embeddedValueResolver != null && annotationFormatterFactory instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) annotationFormatterFactory).setEmbeddedValueResolver(this.embeddedValueResolver); } - Set> fieldTypes = annotationFormatterFactory.getFieldTypes(); for (final Class fieldType : fieldTypes) { - addConverter(new ConditionalGenericConverter() { - public Set getConvertibleTypes() { - return Collections.singleton(new ConvertiblePair(fieldType, String.class)); - } - public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { - return (sourceType.getAnnotation(annotationType) != null); - } - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - FieldFormatterKey key = new FieldFormatterKey(sourceType.getAnnotation(annotationType), fieldType); - GenericConverter converter = cachedPrinters.get(key); - if (converter == null) { - Printer printer = annotationFormatterFactory.getPrinter(key.getAnnotation(), key.getFieldType()); - converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this); - cachedPrinters.put(key, converter); - } - return converter.convert(source, sourceType, targetType); - } - public String toString() { - return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + - String.class.getName() + ": " + annotationFormatterFactory; - } - }); - addConverter(new ConditionalGenericConverter() { - public Set getConvertibleTypes() { - return Collections.singleton(new ConvertiblePair(String.class, fieldType)); - } - public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { - return (targetType.getAnnotation(annotationType) != null); - } - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - FieldFormatterKey key = new FieldFormatterKey(targetType.getAnnotation(annotationType), fieldType); - GenericConverter converter = cachedParsers.get(key); - if (converter == null) { - Parser printer = annotationFormatterFactory.getParser(key.getAnnotation(), key.getFieldType()); - converter = new ParserConverter(fieldType, printer, FormattingConversionService.this); - cachedParsers.put(key, converter); - } - return converter.convert(source, sourceType, targetType); - } - public String toString() { - return String.class.getName() + " -> @" + annotationType.getName() + " " + - fieldType.getName() + ": " + annotationFormatterFactory; - } - }); + addConverter(new AnnotationPrinterConverter(annotationType, annotationFormatterFactory, fieldType)); + addConverter(new AnnotationParserConverter(annotationType, annotationFormatterFactory, fieldType)); } } - - private static final class FieldFormatterKey { - - private final Annotation annotation; - - private final Class fieldType; - - public FieldFormatterKey(Annotation annotation, Class fieldType) { - this.annotation = annotation; - this.fieldType = fieldType; - } - - public Annotation getAnnotation() { - return annotation; - } - - public Class getFieldType() { - return fieldType; - } - - public boolean equals(Object o) { - if (!(o instanceof FieldFormatterKey)) { - return false; - } - FieldFormatterKey key = (FieldFormatterKey) o; - return this.annotation.equals(key.annotation) && this.fieldType.equals(key.fieldType); - } - - public int hashCode() { - return this.annotation.hashCode() + 29 * this.fieldType.hashCode(); - } - } - - private static class PrinterConverter implements GenericConverter { private Class fieldType; @@ -216,7 +139,6 @@ public class FormattingConversionService extends GenericConversionService } } - private static class ParserConverter implements GenericConverter { private Class fieldType; @@ -259,4 +181,114 @@ public class FormattingConversionService extends GenericConversionService } } + private final class AnnotationPrinterConverter implements ConditionalGenericConverter { + + private Class annotationType; + + private AnnotationFormatterFactory annotationFormatterFactory; + + private Class fieldType; + + public AnnotationPrinterConverter(Class annotationType, + AnnotationFormatterFactory annotationFormatterFactory, Class fieldType) { + this.annotationType = annotationType; + this.annotationFormatterFactory = annotationFormatterFactory; + this.fieldType = fieldType; + } + + public Set getConvertibleTypes() { + return Collections.singleton(new ConvertiblePair(fieldType, String.class)); + } + + public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { + return sourceType.getAnnotation(annotationType) != null; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + AnnotationConverterKey converterKey = new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType()); + GenericConverter converter = cachedPrinters.get(converterKey); + if (converter == null) { + Printer printer = annotationFormatterFactory.getPrinter(converterKey.getAnnotation(), converterKey.getFieldType()); + converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this); + cachedPrinters.put(converterKey, converter); + } + return converter.convert(source, sourceType, targetType); + } + + public String toString() { + return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + String.class.getName() + ": " + annotationFormatterFactory; + } + } + + private final class AnnotationParserConverter implements ConditionalGenericConverter { + + private Class annotationType; + + private AnnotationFormatterFactory annotationFormatterFactory; + + private Class fieldType; + + public AnnotationParserConverter(Class annotationType, + AnnotationFormatterFactory annotationFormatterFactory, Class fieldType) { + this.annotationType = annotationType; + this.annotationFormatterFactory = annotationFormatterFactory; + this.fieldType = fieldType; + } + + public Set getConvertibleTypes() { + return Collections.singleton(new ConvertiblePair(String.class, fieldType)); + } + + public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { + return targetType.getAnnotation(annotationType) != null; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + AnnotationConverterKey converterKey = new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType()); + GenericConverter converter = cachedParsers.get(converterKey); + if (converter == null) { + Parser parser = annotationFormatterFactory.getParser(converterKey.getAnnotation(), converterKey.getFieldType()); + converter = new ParserConverter(fieldType, parser, FormattingConversionService.this); + cachedParsers.put(converterKey, converter); + } + return converter.convert(source, sourceType, targetType); + } + + public String toString() { + return String.class.getName() + " -> @" + annotationType.getName() + " " + fieldType.getName() + ": " + annotationFormatterFactory; + } + } + + private static final class AnnotationConverterKey { + + private final Annotation annotation; + + private final Class fieldType; + + public AnnotationConverterKey(Annotation annotation, Class fieldType) { + this.annotation = annotation; + this.fieldType = fieldType; + } + + public Annotation getAnnotation() { + return annotation; + } + + public Class getFieldType() { + return fieldType; + } + + public boolean equals(Object o) { + if (!(o instanceof AnnotationConverterKey)) { + return false; + } + AnnotationConverterKey key = (AnnotationConverterKey) o; + return this.annotation.equals(key.annotation) && this.fieldType.equals(key.fieldType); + } + + public int hashCode() { + return this.annotation.hashCode() + 29 * this.fieldType.hashCode(); + } + } + }