From f82c6ed7cc8639991bac0afde787ea00ad4331ae Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sat, 27 Oct 2012 09:06:25 -0700 Subject: [PATCH] Support conversion from Enum Interface EnumToStringConverter in now conditional and only matches Enums that do not implement interfaces that can be converted. Issue: SPR-9692 --- .../support/DefaultConversionService.java | 3 +- .../support/EnumToStringConverter.java | 27 +++++++++++++-- .../GenericConversionServiceTests.java | 34 +++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java index fe510e9a53..86e580983b 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java @@ -59,6 +59,7 @@ public class DefaultConversionService extends GenericConversionService { // internal helpers private static void addScalarConverters(ConverterRegistry converterRegistry) { + ConversionService conversionService = (ConversionService) converterRegistry; converterRegistry.addConverter(new StringToBooleanConverter()); converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter()); @@ -74,7 +75,7 @@ public class DefaultConversionService extends GenericConversionService { converterRegistry.addConverterFactory(new CharacterToNumberFactory()); converterRegistry.addConverterFactory(new StringToEnumConverterFactory()); - converterRegistry.addConverter(Enum.class, String.class, new EnumToStringConverter()); + converterRegistry.addConverter(Enum.class, String.class, new EnumToStringConverter(conversionService)); converterRegistry.addConverter(new StringToLocaleConverter()); converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter()); diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/EnumToStringConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/EnumToStringConverter.java index bb06f1773a..b9eede1abd 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/EnumToStringConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/EnumToStringConverter.java @@ -16,14 +16,37 @@ package org.springframework.core.convert.support; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.ConditionalConversion; import org.springframework.core.convert.converter.Converter; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; /** - * Simply calls {@link Enum#name()} to convert a source Enum to a String. + * Calls {@link Enum#name()} to convert a source Enum to a String. This converter will + * not match enums with interfaces that can be converterd. * @author Keith Donald + * @author Phillip Webb * @since 3.0 */ -final class EnumToStringConverter implements Converter, String> { +final class EnumToStringConverter implements Converter, String>, ConditionalConversion { + + private final ConversionService conversionService; + + public EnumToStringConverter(ConversionService conversionService) { + this.conversionService = conversionService; + } + + public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { + for (Class interfaceType : ClassUtils.getAllInterfacesForClass(sourceType.getType())) { + if (conversionService.canConvert(TypeDescriptor.valueOf(interfaceType), + targetType)) { + return false; + } + } + return true; + } public String convert(Enum source) { return source.name(); diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java index b99c76af1d..bba7379395 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java @@ -734,6 +734,22 @@ public class GenericConversionServiceTests { assertTrue(Arrays.equals(new byte[] { 2, 3, 4 }, converted)); } + @Test + public void testEnumToStringConversion() { + conversionService.addConverter(new EnumToStringConverter(conversionService)); + String result = conversionService.convert(MyEnum.A, String.class); + assertEquals("A", result); + } + + @Test + public void testEnumWithInterfaceToStringConversion() { + // SPR-9692 + conversionService.addConverter(new EnumToStringConverter(conversionService)); + conversionService.addConverter(new MyEnumInterfaceToStringConverter()); + String result = conversionService.convert(MyEnum.A, String.class); + assertEquals("1", result); + } + private static class MyConditionalConverter implements Converter, ConditionalConversion { @@ -803,4 +819,22 @@ public class GenericConversionServiceTests { } } + interface MyEnumInterface { + String getCode(); + } + + public static enum MyEnum implements MyEnumInterface { + A { + public String getCode() { + return "1"; + } + }; + } + + private static class MyEnumInterfaceToStringConverter + implements Converter { + public String convert(T source) { + return source.getCode(); + } + } }