SPR-7732, SPR-6506, SPR-7191 MVC Namespace improvements to the annotation-driven element - custom message converters, formatters, and message codes resolver.

This commit is contained in:
Rossen Stoyanchev
2011-01-25 17:49:57 +00:00
parent 1ed1c59888
commit f26b499cbd
7 changed files with 426 additions and 46 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -30,7 +30,7 @@ import org.springframework.core.convert.converter.ConverterRegistry;
public interface FormatterRegistry extends ConverterRegistry {
/**
* Adds a Formatter to format fields of a specific type.
* Adds a Formatter to format fields of the given type.
* <p>On print, if the Formatter's type T is declared and <code>fieldType</code> is not assignable to T,
* a coersion to T will be attempted before delegating to <code>formatter</code> to print a field value.
* On parse, if the parsed object returned by <code>formatter</code> is not assignable to the runtime field type,
@@ -40,6 +40,14 @@ public interface FormatterRegistry extends ConverterRegistry {
*/
void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);
/**
* Adds a Formatter to format fields of a specific type.
* The field type is implied by the parameterized Formatter instance.
* @param formatter the formatter to add
* @see #addFormatterForFieldType(Class, Formatter)
*/
void addFormatter(Formatter<?> formatter);
/**
* Adds a Printer/Parser pair to format fields of a specific type.
* The formatter will delegate to the specified <code>printer</code> for printing

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -68,12 +68,21 @@ public class FormattingConversionService extends GenericConversionService
addConverter(new ParserConverter(fieldType, formatter, this));
}
public void addFormatter(Formatter<?> formatter) {
final Class<?> fieldType = GenericTypeResolver.resolveTypeArgument(formatter.getClass(), Formatter.class);
if (fieldType == null) {
throw new IllegalArgumentException("Unable to extract parameterized field type argument from Formatter ["
+ formatter.getClass().getName() + "]; does the formatter parameterize the <T> generic type?");
}
addFormatterForFieldType(fieldType, formatter);
}
public void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser) {
addConverter(new PrinterConverter(fieldType, printer, this));
addConverter(new ParserConverter(fieldType, parser, this));
}
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "rawtypes" })
public void addFormatterForFieldAnnotation(final AnnotationFormatterFactory annotationFormatterFactory) {
final Class<? extends Annotation> annotationType = (Class<? extends Annotation>)
GenericTypeResolver.resolveTypeArgument(annotationFormatterFactory.getClass(), AnnotationFormatterFactory.class);
@@ -174,7 +183,7 @@ public class FormattingConversionService extends GenericConversionService
private TypeDescriptor printerObjectType;
@SuppressWarnings("unchecked")
@SuppressWarnings("rawtypes")
private Printer printer;
private ConversionService conversionService;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
@@ -38,10 +39,8 @@ import org.springframework.util.StringValueResolver;
/**
* A factory for a {@link FormattingConversionService} that installs default
* formatters for common types such as numbers and datetimes.
*
* <p>Subclasses may override {@link #installFormatters(FormatterRegistry)}
* to register custom formatters.
* and custom converters and formatters for common types such as numbers
* and datetimes .
*
* @author Keith Donald
* @author Juergen Hoeller
@@ -55,21 +54,31 @@ public class FormattingConversionServiceFactoryBean
private Set<?> converters;
private Set<?> formatters;
private StringValueResolver embeddedValueResolver;
private FormattingConversionService conversionService;
/**
* Configure the set of custom converter objects that should be added:
* implementing {@link org.springframework.core.convert.converter.Converter},
* {@link org.springframework.core.convert.converter.ConverterFactory},
* or {@link org.springframework.core.convert.converter.GenericConverter}.
* Configure the set of custom converter objects that should be added.
* @param converters instances of
* {@link org.springframework.core.convert.converter.Converter},
* {@link org.springframework.core.convert.converter.ConverterFactory} or
* {@link org.springframework.core.convert.converter.GenericConverter}.
*/
public void setConverters(Set<?> converters) {
this.converters = converters;
}
/**
* Configure the set of custom formatter objects that should be added.
* @param formatters instances of {@link Formatter} or {@link AnnotationFormatterFactory}.
*/
public void setFormatters(Set<?> formatters) {
this.formatters = formatters;
}
public void setEmbeddedValueResolver(StringValueResolver embeddedValueResolver) {
this.embeddedValueResolver = embeddedValueResolver;
}
@@ -112,6 +121,18 @@ public class FormattingConversionServiceFactoryBean
else {
registry.addFormatterForFieldAnnotation(new NoJodaDateTimeFormatAnnotationFormatterFactory());
}
if (this.formatters != null) {
for (Object formatter : this.formatters) {
if (formatter instanceof Formatter<?>) {
this.conversionService.addFormatter((Formatter<?>) formatter);
} else if (formatter instanceof AnnotationFormatterFactory<?>) {
this.conversionService.addFormatterForFieldAnnotation((AnnotationFormatterFactory<?>) formatter);
} else {
throw new IllegalArgumentException(
"Custom formatters must be implementations of Formatter or AnnotationFormatterFactory");
}
}
}
}