Skip to content

Commit f82c6ed

Browse files
philwebbcbeams
authored andcommitted
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
1 parent 138957b commit f82c6ed

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public static void addDefaultConverters(ConverterRegistry converterRegistry) {
5959
// internal helpers
6060

6161
private static void addScalarConverters(ConverterRegistry converterRegistry) {
62+
ConversionService conversionService = (ConversionService) converterRegistry;
6263
converterRegistry.addConverter(new StringToBooleanConverter());
6364
converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());
6465

@@ -74,7 +75,7 @@ private static void addScalarConverters(ConverterRegistry converterRegistry) {
7475
converterRegistry.addConverterFactory(new CharacterToNumberFactory());
7576

7677
converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
77-
converterRegistry.addConverter(Enum.class, String.class, new EnumToStringConverter());
78+
converterRegistry.addConverter(Enum.class, String.class, new EnumToStringConverter(conversionService));
7879

7980
converterRegistry.addConverter(new StringToLocaleConverter());
8081
converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());

spring-core/src/main/java/org/springframework/core/convert/support/EnumToStringConverter.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,37 @@
1616

1717
package org.springframework.core.convert.support;
1818

19+
import org.springframework.core.convert.ConversionService;
20+
import org.springframework.core.convert.TypeDescriptor;
21+
import org.springframework.core.convert.converter.ConditionalConversion;
1922
import org.springframework.core.convert.converter.Converter;
23+
import org.springframework.util.ClassUtils;
24+
import org.springframework.util.ReflectionUtils;
2025

2126
/**
22-
* Simply calls {@link Enum#name()} to convert a source Enum to a String.
27+
* Calls {@link Enum#name()} to convert a source Enum to a String. This converter will
28+
* not match enums with interfaces that can be converterd.
2329
* @author Keith Donald
30+
* @author Phillip Webb
2431
* @since 3.0
2532
*/
26-
final class EnumToStringConverter implements Converter<Enum<?>, String> {
33+
final class EnumToStringConverter implements Converter<Enum<?>, String>, ConditionalConversion {
34+
35+
private final ConversionService conversionService;
36+
37+
public EnumToStringConverter(ConversionService conversionService) {
38+
this.conversionService = conversionService;
39+
}
40+
41+
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
42+
for (Class<?> interfaceType : ClassUtils.getAllInterfacesForClass(sourceType.getType())) {
43+
if (conversionService.canConvert(TypeDescriptor.valueOf(interfaceType),
44+
targetType)) {
45+
return false;
46+
}
47+
}
48+
return true;
49+
}
2750

2851
public String convert(Enum<?> source) {
2952
return source.name();

spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,22 @@ public Byte convert(Byte source) {
734734
assertTrue(Arrays.equals(new byte[] { 2, 3, 4 }, converted));
735735
}
736736

737+
@Test
738+
public void testEnumToStringConversion() {
739+
conversionService.addConverter(new EnumToStringConverter(conversionService));
740+
String result = conversionService.convert(MyEnum.A, String.class);
741+
assertEquals("A", result);
742+
}
743+
744+
@Test
745+
public void testEnumWithInterfaceToStringConversion() {
746+
// SPR-9692
747+
conversionService.addConverter(new EnumToStringConverter(conversionService));
748+
conversionService.addConverter(new MyEnumInterfaceToStringConverter<MyEnum>());
749+
String result = conversionService.convert(MyEnum.A, String.class);
750+
assertEquals("1", result);
751+
}
752+
737753
private static class MyConditionalConverter implements Converter<String, Color>,
738754
ConditionalConversion {
739755

@@ -803,4 +819,22 @@ public int getNestedMatchAttempts() {
803819
}
804820
}
805821

822+
interface MyEnumInterface {
823+
String getCode();
824+
}
825+
826+
public static enum MyEnum implements MyEnumInterface {
827+
A {
828+
public String getCode() {
829+
return "1";
830+
}
831+
};
832+
}
833+
834+
private static class MyEnumInterfaceToStringConverter<T extends MyEnumInterface>
835+
implements Converter<T, String> {
836+
public String convert(T source) {
837+
return source.getCode();
838+
}
839+
}
806840
}

0 commit comments

Comments
 (0)