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:
parent
a89bfffd8c
commit
5e505ce3a9
|
@ -29,6 +29,24 @@ import org.springframework.core.convert.converter.ConverterRegistry;
|
||||||
*/
|
*/
|
||||||
public interface FormatterRegistry extends 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.
|
* Adds a Formatter to format fields of a specific type.
|
||||||
* The field type is implied by the parameterized Formatter instance.
|
* The field type is implied by the parameterized Formatter instance.
|
||||||
|
|
|
@ -37,6 +37,8 @@ import org.springframework.format.FormatterRegistry;
|
||||||
import org.springframework.format.Parser;
|
import org.springframework.format.Parser;
|
||||||
import org.springframework.format.Printer;
|
import org.springframework.format.Printer;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.util.StringValueResolver;
|
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
|
@Override
|
||||||
public void addFormatter(Formatter<?> formatter) {
|
public void addFormatter(Formatter<?> formatter) {
|
||||||
addFormatterForFieldType(getFieldType(formatter), formatter);
|
addFormatterForFieldType(getFieldType(formatter), formatter);
|
||||||
|
@ -97,15 +111,18 @@ public class FormattingConversionService extends GenericConversionService
|
||||||
|
|
||||||
|
|
||||||
static Class<?> getFieldType(Formatter<?> formatter) {
|
static Class<?> getFieldType(Formatter<?> formatter) {
|
||||||
Class<?> fieldType = GenericTypeResolver.resolveTypeArgument(formatter.getClass(), Formatter.class);
|
return getFieldType(formatter, Formatter.class);
|
||||||
if (fieldType == null && formatter instanceof DecoratingProxy) {
|
}
|
||||||
|
|
||||||
|
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(
|
fieldType = GenericTypeResolver.resolveTypeArgument(
|
||||||
((DecoratingProxy) formatter).getDecoratedClass(), Formatter.class);
|
((DecoratingProxy) instance).getDecoratedClass(), genericInterface);
|
||||||
}
|
|
||||||
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?");
|
|
||||||
}
|
}
|
||||||
|
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;
|
return fieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -346,8 +346,25 @@ public class FormattingConversionServiceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void introspectedFormatter() throws ParseException {
|
public void introspectedFormatter() throws ParseException {
|
||||||
formattingService.addFormatter(new NumberStyleFormatter());
|
formattingService.addFormatter(new NumberStyleFormatter("#,#00.0#"));
|
||||||
assertThat(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class))).isNull();
|
assertThat(formattingService.convert(123, String.class)).isEqualTo("123.0");
|
||||||
|
assertThat(formattingService.convert("123.0", Integer.class)).isEqualTo(123);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void introspectedPrinter() throws ParseException {
|
||||||
|
formattingService.addPrinter(new NumberStyleFormatter("#,#00.0#"));
|
||||||
|
assertThat(formattingService.convert(123, String.class)).isEqualTo("123.0");
|
||||||
|
assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() ->
|
||||||
|
assertThat(formattingService.convert("123.0", Integer.class)).isNull())
|
||||||
|
.withCauseInstanceOf(NumberFormatException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void introspectedParser() throws ParseException {
|
||||||
|
formattingService.addParser(new NumberStyleFormatter("#,#00.0#"));
|
||||||
|
assertThat(formattingService.convert("123.0", Integer.class)).isEqualTo(123);
|
||||||
|
assertThat(formattingService.convert(123, String.class)).isEqualTo("123");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue