Add FormatterRegistry addPrinter/addParser methods

Update `FormatterRegistry` with `addPrinter` and `addParser` methods
that can be used to register Printer or Parser implementations in a
similar way to the existing `addFormatter` method.

Closes gh-23110
This commit is contained in:
Phillip Webb
2019-06-11 14:45:04 -07:00
parent a89bfffd8c
commit 5e505ce3a9
3 changed files with 61 additions and 9 deletions

View File

@@ -29,6 +29,24 @@ import org.springframework.core.convert.converter.ConverterRegistry;
*/
public interface FormatterRegistry extends ConverterRegistry {
/**
* Adds a Printer to print fields of a specific type.
* The field type is implied by the parameterized Printer instance.
* @param printer the printer to add
* @since 5.2
* @see #addFormatter(Formatter)
*/
void addPrinter(Printer<?> printer);
/**
* Adds a Parser to parse fields of a specific type.
* The field type is implied by the parameterized Parser instance.
* @param parser the parser to add
* @since 5.2
* @see #addFormatter(Formatter)
*/
void addParser(Parser<?> parser);
/**
* Adds a Formatter to format fields of a specific type.
* The field type is implied by the parameterized Formatter instance.

View File

@@ -37,6 +37,8 @@ import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
@@ -65,6 +67,18 @@ public class FormattingConversionService extends GenericConversionService
}
@Override
public void addPrinter(Printer<?> printer) {
Class<?> fieldType = getFieldType(printer, Printer.class);
addConverter(new PrinterConverter(fieldType, printer, this));
}
@Override
public void addParser(Parser<?> parser) {
Class<?> fieldType = getFieldType(parser, Parser.class);
addConverter(new ParserConverter(fieldType, parser, this));
}
@Override
public void addFormatter(Formatter<?> formatter) {
addFormatterForFieldType(getFieldType(formatter), formatter);
@@ -97,15 +111,18 @@ public class FormattingConversionService extends GenericConversionService
static Class<?> getFieldType(Formatter<?> formatter) {
Class<?> fieldType = GenericTypeResolver.resolveTypeArgument(formatter.getClass(), Formatter.class);
if (fieldType == null && formatter instanceof DecoratingProxy) {
return getFieldType(formatter, Formatter.class);
}
private static <T> Class<?> getFieldType(T instance, Class<T> genericInterface) {
Class<?> fieldType = GenericTypeResolver.resolveTypeArgument(instance.getClass(), genericInterface);
if (fieldType == null && instance instanceof DecoratingProxy) {
fieldType = GenericTypeResolver.resolveTypeArgument(
((DecoratingProxy) formatter).getDecoratedClass(), Formatter.class);
}
if (fieldType == null) {
throw new IllegalArgumentException("Unable to extract the parameterized field type from Formatter [" +
formatter.getClass().getName() + "]; does the class parameterize the <T> generic type?");
((DecoratingProxy) instance).getDecoratedClass(), genericInterface);
}
Assert.notNull(fieldType, () -> "Unable to extract the parameterized field type from " +
ClassUtils.getShortName(genericInterface) + " [" + instance.getClass().getName() +
"]; does the class parameterize the <T> generic type?");
return fieldType;
}