19 changed files with 449 additions and 482 deletions
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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 java.util.Locale; |
||||
|
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
|
||||
/** |
||||
* A service interface for formatting localized field values. |
||||
* This is the entry point into the <code>ui.format</code> system. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public interface FormattingService { |
||||
|
||||
/** |
||||
* Print the field value for display in the locale. |
||||
* @param fieldValue the field value |
||||
* @param fieldType the field type |
||||
* @param locale the user's locale |
||||
* @return the printed string |
||||
*/ |
||||
String print(Object fieldValue, TypeDescriptor fieldType, Locale locale); |
||||
|
||||
/** |
||||
* Parse the the value submitted by the user. |
||||
* @param submittedValue the submitted field value |
||||
* @param fieldType the field type |
||||
* @param locale the user's locale |
||||
* @return the parsed field value |
||||
*/ |
||||
Object parse(String submittedValue, TypeDescriptor fieldType, Locale locale) throws ParseException; |
||||
|
||||
} |
||||
@ -0,0 +1,200 @@
@@ -0,0 +1,200 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.text.ParseException; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
import org.springframework.core.GenericTypeResolver; |
||||
import org.springframework.core.convert.ConversionFailedException; |
||||
import org.springframework.core.convert.ConversionService; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConverterRegistry; |
||||
import org.springframework.core.convert.support.ConditionalGenericConverter; |
||||
import org.springframework.core.convert.support.DefaultConversionService; |
||||
import org.springframework.core.convert.support.GenericConversionService; |
||||
import org.springframework.core.convert.support.GenericConverter; |
||||
import org.springframework.ui.format.AnnotationFormatterFactory; |
||||
import org.springframework.ui.format.Formatter; |
||||
import org.springframework.ui.format.FormatterRegistry; |
||||
import org.springframework.ui.format.Parser; |
||||
import org.springframework.ui.format.Printer; |
||||
|
||||
/** |
||||
* A ConversionService implementation designed to be configured as a {@link FormatterRegistry}.. |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public class FormattingConversionService implements FormatterRegistry, ConversionService { |
||||
|
||||
private GenericConversionService conversionService = new GenericConversionService(); |
||||
|
||||
/** |
||||
* Creates a new FormattingConversionService, initially with no Formatters registered. |
||||
* A {@link DefaultConversionService} is configured as the parent conversion service to support primitive type conversion. |
||||
*/ |
||||
public FormattingConversionService() { |
||||
this.conversionService.setParent(new DefaultConversionService()); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new FormattingConversionService, initially with no Formatters registered. |
||||
* The conversion logic contained in the parent is merged with this service. |
||||
*/ |
||||
public FormattingConversionService(ConversionService parent) { |
||||
this.conversionService.setParent(parent); |
||||
} |
||||
|
||||
// implementing FormattingRegistry
|
||||
|
||||
public void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser) { |
||||
this.conversionService.addGenericConverter(fieldType, String.class, new PrinterConverter(printer, this.conversionService)); |
||||
this.conversionService.addGenericConverter(String.class, fieldType, new ParserConverter(parser, this.conversionService)); |
||||
} |
||||
|
||||
public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) { |
||||
this.conversionService.addGenericConverter(fieldType, String.class, new PrinterConverter(formatter, this.conversionService)); |
||||
this.conversionService.addGenericConverter(String.class, fieldType, new ParserConverter(formatter, this.conversionService)); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public void addFormatterForFieldAnnotation(final AnnotationFormatterFactory annotationFormatterFactory) { |
||||
final Class<? extends Annotation> annotationType = resolveAnnotationType(annotationFormatterFactory); |
||||
if (annotationType == null) { |
||||
throw new IllegalArgumentException( |
||||
"Unable to extract parameterized Annotation type argument from AnnotationFormatterFactory [" |
||||
+ annotationFormatterFactory.getClass().getName() |
||||
+ "]; does the factory parameterize the <A extends Annotation> generic type?"); |
||||
} |
||||
Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes(); |
||||
for (Class<?> fieldType : fieldTypes) { |
||||
this.conversionService.addGenericConverter(fieldType, String.class, new ConditionalGenericConverter() { |
||||
public boolean matches(TypeDescriptor sourceFieldType, TypeDescriptor targetFieldType) { |
||||
return sourceFieldType.getAnnotation(annotationType) != null; |
||||
} |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
Printer<?> printer = annotationFormatterFactory.getPrinter(sourceType.getAnnotation(annotationType), targetType.getType()); |
||||
return new PrinterConverter(printer, conversionService).convert(source, sourceType, targetType); |
||||
} |
||||
}); |
||||
this.conversionService.addGenericConverter(String.class, fieldType, new ConditionalGenericConverter() { |
||||
public boolean matches(TypeDescriptor sourceFieldType, TypeDescriptor targetFieldType) { |
||||
return targetFieldType.getAnnotation(annotationType) != null; |
||||
} |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
Parser<?> parser = annotationFormatterFactory.getParser(targetType.getAnnotation(annotationType), targetType.getType()); |
||||
return new ParserConverter(parser, conversionService).convert(source, sourceType, targetType); |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
|
||||
public ConverterRegistry getConverterRegistry() { |
||||
return this.conversionService; |
||||
} |
||||
|
||||
// implementing ConverisonService
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) { |
||||
return canConvert(TypeDescriptor.valueOf(sourceType), TypeDescriptor.valueOf(targetType)); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public <T> T convert(Object source, Class<T> targetType) { |
||||
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType)); |
||||
} |
||||
|
||||
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.conversionService.canConvert(sourceType, targetType); |
||||
} |
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.conversionService.convert(source, sourceType, targetType); |
||||
} |
||||
|
||||
// internal helpers
|
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private Class<? extends Annotation> resolveAnnotationType(AnnotationFormatterFactory<?> annotationFormatterFactory) { |
||||
return (Class<? extends Annotation>) GenericTypeResolver.resolveTypeArgument(annotationFormatterFactory.getClass(), AnnotationFormatterFactory.class); |
||||
} |
||||
|
||||
private static class PrinterConverter implements GenericConverter { |
||||
|
||||
private TypeDescriptor printerObjectType; |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private Printer printer; |
||||
|
||||
private ConversionService conversionService; |
||||
|
||||
public PrinterConverter(Printer<?> printer, ConversionService conversionService) { |
||||
this.printerObjectType = TypeDescriptor.valueOf(resolvePrinterObjectType(printer)); |
||||
this.printer = printer; |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (!sourceType.isAssignableTo(this.printerObjectType)) { |
||||
source = this.conversionService.convert(source, sourceType, this.printerObjectType); |
||||
} |
||||
return source != null ? this.printer.print(source, LocaleContextHolder.getLocale()) : ""; |
||||
} |
||||
|
||||
private Class<?> resolvePrinterObjectType(Printer<?> printer) { |
||||
return GenericTypeResolver.resolveTypeArgument(printer.getClass(), Printer.class); |
||||
} |
||||
} |
||||
|
||||
private static class ParserConverter implements GenericConverter { |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private Parser parser; |
||||
|
||||
private ConversionService conversionService; |
||||
|
||||
public ParserConverter(Parser<?> parser, ConversionService conversionService) { |
||||
this.parser = parser; |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
String submittedValue = (String) source; |
||||
if (submittedValue.isEmpty()) { |
||||
return null; |
||||
} |
||||
Object parsedValue; |
||||
try { |
||||
parsedValue = this.parser.parse(submittedValue, LocaleContextHolder.getLocale()); |
||||
} catch (ParseException e) { |
||||
throw new ConversionFailedException(sourceType, targetType, source, e); |
||||
} |
||||
TypeDescriptor parsedObjectType = TypeDescriptor.valueOf(parsedValue.getClass()); |
||||
if (!parsedObjectType.isAssignableTo(targetType)) { |
||||
try { |
||||
parsedValue = this.conversionService.convert(parsedValue, parsedObjectType, targetType); |
||||
} catch (ConversionFailedException e) { |
||||
throw new ConversionFailedException(sourceType, targetType, source, e); |
||||
} |
||||
} |
||||
return parsedValue; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,58 +0,0 @@
@@ -1,58 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.text.ParseException; |
||||
|
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
import org.springframework.core.convert.ConversionFailedException; |
||||
import org.springframework.core.convert.ConversionService; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.support.GenericConversionService; |
||||
import org.springframework.core.convert.support.GenericConverter; |
||||
import org.springframework.ui.format.FormattingService; |
||||
|
||||
/** |
||||
* Adapter that exposes a {@link ConversionService} reference for a given {@link FormattingService}, |
||||
* retrieving the current Locale from {@link LocaleContextHolder}. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 3.0 |
||||
*/ |
||||
public class FormattingConversionServiceAdapter extends GenericConversionService { |
||||
|
||||
private final FormattingService formattingService; |
||||
|
||||
public FormattingConversionServiceAdapter(FormattingService formattingService) { |
||||
this.formattingService = formattingService; |
||||
addGenericConverter(String.class, Object.class, new GenericConverter() { |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
try { |
||||
return FormattingConversionServiceAdapter.this.formattingService.parse((String) source, targetType, LocaleContextHolder.getLocale()); |
||||
} catch (ParseException e) { |
||||
throw new ConversionFailedException(sourceType, targetType, source, e); |
||||
} |
||||
} |
||||
}); |
||||
addGenericConverter(Object.class, String.class, new GenericConverter() { |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return FormattingConversionServiceAdapter.this.formattingService.print(source, targetType, LocaleContextHolder.getLocale()); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
} |
||||
@ -1,234 +0,0 @@
@@ -1,234 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.text.ParseException; |
||||
import java.util.LinkedList; |
||||
import java.util.Locale; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import org.springframework.core.GenericTypeResolver; |
||||
import org.springframework.core.convert.ConversionService; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConverterRegistry; |
||||
import org.springframework.core.convert.support.GenericConversionService; |
||||
import org.springframework.ui.format.AnnotationFormatterFactory; |
||||
import org.springframework.ui.format.Formatter; |
||||
import org.springframework.ui.format.FormatterRegistry; |
||||
import org.springframework.ui.format.FormattingService; |
||||
import org.springframework.ui.format.Parser; |
||||
import org.springframework.ui.format.Printer; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* A generic implementation of {@link FormattingService} suitable for use in most environments. |
||||
* Is a {@link FormatterRegistry} to allow for registration of field formatting logic. |
||||
* |
||||
* @author Keith Donald |
||||
* @author Juergen Hoeller |
||||
* @since 3.0 |
||||
*/ |
||||
public class GenericFormattingService implements FormattingService, FormatterRegistry { |
||||
|
||||
private final Map<Class<?>, GenericFormatter> typeFormatters = new ConcurrentHashMap<Class<?>, GenericFormatter>(); |
||||
|
||||
private final Map<Class<? extends Annotation>, GenericAnnotationFormatterFactory> annotationFormatters = new ConcurrentHashMap<Class<? extends Annotation>, GenericAnnotationFormatterFactory>(); |
||||
|
||||
private GenericConversionService conversionService = new GenericConversionService(); |
||||
|
||||
/** |
||||
* Configure a parent of the type conversion service that will be used to coerce objects to types required for formatting. |
||||
*/ |
||||
public void setParentConversionService(ConversionService parentConversionService) { |
||||
this.conversionService.setParent(parentConversionService); |
||||
} |
||||
|
||||
// implementing FormattingService
|
||||
|
||||
public String print(Object fieldValue, TypeDescriptor fieldType, Locale locale) { |
||||
return getFormatter(fieldType).print(fieldValue, fieldType, locale); |
||||
} |
||||
|
||||
public Object parse(String submittedValue, TypeDescriptor fieldType, Locale locale) throws ParseException { |
||||
return getFormatter(fieldType).parse(submittedValue, fieldType, locale); |
||||
} |
||||
|
||||
// implementing FormatterRegistry
|
||||
|
||||
public void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser) { |
||||
Class<?> printerObjectType = resolvePrinterObjectType(printer); |
||||
Class<?> parserObjectType = resolveParserObjectType(parser); |
||||
this.typeFormatters.put(fieldType, new GenericFormatter(printerObjectType, printer, parserObjectType, parser)); |
||||
} |
||||
|
||||
public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) { |
||||
Class<?> formatterObjectType = resolveFormatterObjectType(formatter); |
||||
this.typeFormatters.put(fieldType, new GenericFormatter(formatterObjectType, formatter, formatterObjectType, formatter)); |
||||
} |
||||
|
||||
public void addFormatterForFieldAnnotation(AnnotationFormatterFactory<?> annotationFormatterFactory) { |
||||
Class<? extends Annotation> annotationType = resolveAnnotationType(annotationFormatterFactory); |
||||
if (annotationType == null) { |
||||
throw new IllegalArgumentException( |
||||
"Unable to extract parameterized Annotation type argument from AnnotationFormatterFactory [" |
||||
+ annotationFormatterFactory.getClass().getName() |
||||
+ "]; does the factory parameterize the <A extends Annotation> generic type?"); |
||||
} |
||||
this.annotationFormatters.put(annotationType, new GenericAnnotationFormatterFactory(annotationFormatterFactory)); |
||||
} |
||||
|
||||
public ConverterRegistry getConverterRegistry() { |
||||
return this.conversionService; |
||||
} |
||||
|
||||
// internal helpers
|
||||
|
||||
private Class<?> resolveParserObjectType(Parser<?> parser) { |
||||
return GenericTypeResolver.resolveTypeArgument(parser.getClass(), Parser.class); |
||||
} |
||||
|
||||
private Class<?> resolvePrinterObjectType(Printer<?> printer) { |
||||
return GenericTypeResolver.resolveTypeArgument(printer.getClass(), Printer.class); |
||||
} |
||||
|
||||
private Class<?> resolveFormatterObjectType(Formatter<?> formatter) { |
||||
return GenericTypeResolver.resolveTypeArgument(formatter.getClass(), Formatter.class); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private Class<? extends Annotation> resolveAnnotationType(AnnotationFormatterFactory<?> annotationFormatterFactory) { |
||||
return (Class<? extends Annotation>) GenericTypeResolver.resolveTypeArgument(annotationFormatterFactory.getClass(), AnnotationFormatterFactory.class); |
||||
} |
||||
|
||||
private GenericFormatter getFormatter(TypeDescriptor fieldType) { |
||||
Assert.notNull(fieldType, "Field TypeDescriptor is required"); |
||||
GenericFormatter formatter = findFormatterForAnnotatedField(fieldType); |
||||
Class<?> fieldObjectType = fieldType.getObjectType(); |
||||
if (formatter == null) { |
||||
formatter = findFormatterForFieldType(fieldObjectType); |
||||
} |
||||
return formatter; |
||||
} |
||||
|
||||
private GenericFormatter findFormatterForAnnotatedField(TypeDescriptor fieldType) { |
||||
for (Annotation annotation : fieldType.getAnnotations()) { |
||||
GenericFormatter formatter = findFormatterForAnnotation(annotation, fieldType.getObjectType()); |
||||
if (formatter != null) { |
||||
return formatter; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private GenericFormatter findFormatterForAnnotation(Annotation annotation, Class<?> fieldType) { |
||||
Class<? extends Annotation> annotationType = annotation.annotationType(); |
||||
GenericAnnotationFormatterFactory factory = this.annotationFormatters.get(annotationType); |
||||
if (factory != null) { |
||||
return factory.getFormatter(annotation, fieldType); |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
private GenericFormatter findFormatterForFieldType(Class<?> fieldType) { |
||||
LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>(); |
||||
classQueue.addFirst(fieldType); |
||||
while (!classQueue.isEmpty()) { |
||||
Class<?> currentClass = classQueue.removeLast(); |
||||
GenericFormatter formatter = this.typeFormatters.get(currentClass); |
||||
if (formatter != null) { |
||||
return formatter; |
||||
} |
||||
if (currentClass.getSuperclass() != null) { |
||||
classQueue.addFirst(currentClass.getSuperclass()); |
||||
} |
||||
Class<?>[] interfaces = currentClass.getInterfaces(); |
||||
for (Class<?> ifc : interfaces) { |
||||
classQueue.addFirst(ifc); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private class GenericFormatter { |
||||
|
||||
private TypeDescriptor printerObjectType; |
||||
|
||||
private Printer printer; |
||||
|
||||
private Parser parser; |
||||
|
||||
public GenericFormatter(Class<?> printerObjectType, Printer<?> printer, Class<?> parserObjectType, Parser<?> parser) { |
||||
this.printerObjectType = TypeDescriptor.valueOf(printerObjectType); |
||||
this.printer = printer; |
||||
this.parser = parser; |
||||
} |
||||
|
||||
public String print(Object fieldValue, TypeDescriptor fieldType, Locale locale) { |
||||
if (!fieldType.isAssignableTo(this.printerObjectType)) { |
||||
fieldValue = GenericFormattingService.this.conversionService.convert(fieldValue, fieldType, this.printerObjectType); |
||||
} |
||||
return fieldType != null ? this.printer.print(fieldValue, locale) : ""; |
||||
} |
||||
|
||||
public Object parse(String submittedValue, TypeDescriptor fieldType, Locale locale) throws ParseException { |
||||
if (submittedValue.isEmpty()) { |
||||
return null; |
||||
} |
||||
Object parsedValue = this.parser.parse(submittedValue, locale); |
||||
TypeDescriptor parsedObjectType = TypeDescriptor.valueOf(parsedValue.getClass()); |
||||
if (!parsedObjectType.isAssignableTo(fieldType)) { |
||||
parsedValue = GenericFormattingService.this.conversionService.convert(parsedValue, parsedObjectType, fieldType); |
||||
} |
||||
return parsedValue; |
||||
} |
||||
|
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private class GenericAnnotationFormatterFactory { |
||||
|
||||
private AnnotationFormatterFactory annotationFormatterFactory; |
||||
|
||||
public GenericAnnotationFormatterFactory(AnnotationFormatterFactory<?> annotationFormatterFactory) { |
||||
this.annotationFormatterFactory = annotationFormatterFactory; |
||||
} |
||||
|
||||
public GenericFormatter getFormatter(Annotation annotation, Class<?> fieldType) { |
||||
Printer<?> printer = this.annotationFormatterFactory.getPrinter(annotation, fieldType); |
||||
Parser<?> parser = this.annotationFormatterFactory.getParser(annotation, fieldType); |
||||
return new GenericFormatter(getPrinterObjectType(printer, fieldType), printer, getParserObjectType(parser, fieldType), parser); |
||||
} |
||||
|
||||
// internal helpers
|
||||
|
||||
private Class<?> getPrinterObjectType(Printer<?> printer, Class<?> fieldType) { |
||||
// TODO cache
|
||||
return resolvePrinterObjectType(printer); |
||||
} |
||||
|
||||
private Class<?> getParserObjectType(Parser<?> parser, Class<?> fieldType) { |
||||
// TODO cache
|
||||
return resolveParserObjectType(parser); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* Copyright 2002-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.core.convert.support; |
||||
|
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
|
||||
/** |
||||
* A generic converter that conditionally executes. |
||||
* Often used when selectively matching custom conversion logic based on the presence of a field or class-level annotation. |
||||
* For example, when converting from a String to a Date field, an implementation might return true if the target field has also been annotated with <code>@DateTimeFormat</code>. |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public interface ConditionalGenericConverter extends GenericConverter { |
||||
|
||||
/** |
||||
* Should the conversion between <code>sourceFieldType</code> and <code>targetFieldType</code> be performed? |
||||
* @param sourceFieldType the type descriptor of the field we are converting from |
||||
* @param targetFieldType the type descriptor of the field we are converting to |
||||
* @return true if conversion should be performed, false otherwise |
||||
*/ |
||||
boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType); |
||||
|
||||
} |
||||
Loading…
Reference in new issue