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
master
Phillip Webb 12 years ago committed by Chris Beams
parent 138957b148
commit f82c6ed7cc
  1. 3
      spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java
  2. 27
      spring-core/src/main/java/org/springframework/core/convert/support/EnumToStringConverter.java
  3. 34
      spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.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());

@ -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<Enum<?>, String> {
final class EnumToStringConverter implements Converter<Enum<?>, 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();

@ -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<MyEnum>());
String result = conversionService.convert(MyEnum.A, String.class);
assertEquals("1", result);
}
private static class MyConditionalConverter implements Converter<String, Color>,
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<T extends MyEnumInterface>
implements Converter<T, String> {
public String convert(T source) {
return source.getCode();
}
}
}

Loading…
Cancel
Save