Merge pull request #607 from dharaburda/SPR-12050
* SPR-12050: Change GenericConversionService to better handle enum
This commit is contained in:
commit
c29937196f
|
@ -55,6 +55,7 @@ import org.springframework.util.StringUtils;
|
|||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
* @author David Haraburda
|
||||
* @since 3.0
|
||||
*/
|
||||
public class GenericConversionService implements ConfigurableConversionService {
|
||||
|
@ -567,19 +568,31 @@ public class GenericConversionService implements ConfigurableConversionService {
|
|||
Class<?> candidate = hierarchy.get(i);
|
||||
candidate = (array ? candidate.getComponentType() : ClassUtils.resolvePrimitiveIfNecessary(candidate));
|
||||
Class<?> superclass = candidate.getSuperclass();
|
||||
if (candidate.getSuperclass() != null && superclass != Object.class) {
|
||||
if (candidate.getSuperclass() != null && superclass != Object.class && superclass != Enum.class) {
|
||||
addToClassHierarchy(i + 1, candidate.getSuperclass(), array, hierarchy, visited);
|
||||
}
|
||||
for (Class<?> implementedInterface : candidate.getInterfaces()) {
|
||||
addToClassHierarchy(hierarchy.size(), implementedInterface, array, hierarchy, visited);
|
||||
}
|
||||
addInterfacesToClassHierarchy(candidate, array, hierarchy, visited);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (type.isEnum()) {
|
||||
addToClassHierarchy(hierarchy.size(), Enum.class, array, hierarchy, visited);
|
||||
addToClassHierarchy(hierarchy.size(), Enum.class, false, hierarchy, visited);
|
||||
addInterfacesToClassHierarchy(Enum.class, array, hierarchy, visited);
|
||||
}
|
||||
|
||||
addToClassHierarchy(hierarchy.size(), Object.class, array, hierarchy, visited);
|
||||
addToClassHierarchy(hierarchy.size(), Object.class, false, hierarchy, visited);
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
private void addInterfacesToClassHierarchy(Class<?> type, boolean asArray,
|
||||
List<Class<?>> hierarchy, Set<Class<?>> visited) {
|
||||
for (Class<?> implementedInterface : type.getInterfaces()) {
|
||||
addToClassHierarchy(hierarchy.size(), implementedInterface, asArray, hierarchy, visited);
|
||||
}
|
||||
}
|
||||
|
||||
private void addToClassHierarchy(int index, Class<?> type, boolean asArray,
|
||||
List<Class<?>> hierarchy, Set<Class<?>> visited) {
|
||||
if (asArray) {
|
||||
|
|
|
@ -57,6 +57,7 @@ import static org.junit.Assert.*;
|
|||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
* @author David Haraburda
|
||||
*/
|
||||
public class GenericConversionServiceTests {
|
||||
|
||||
|
@ -758,6 +759,20 @@ public class GenericConversionServiceTests {
|
|||
assertEquals("1", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToEnumWithInterfaceConversion() {
|
||||
conversionService.addConverterFactory(new StringToEnumConverterFactory());
|
||||
conversionService.addConverterFactory(new StringToMyEnumInterfaceConverterFactory());
|
||||
assertEquals(MyEnum.A, conversionService.convert("1", MyEnum.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToEnumWithBaseInterfaceConversion() {
|
||||
conversionService.addConverterFactory(new StringToEnumConverterFactory());
|
||||
conversionService.addConverterFactory(new StringToMyEnumBaseInterfaceConverterFactory());
|
||||
assertEquals(MyEnum.A, conversionService.convert("base1", MyEnum.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertNullAnnotatedStringToString() throws Exception {
|
||||
DefaultConversionService.addDefaultConverters(conversionService);
|
||||
|
@ -930,19 +945,34 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
}
|
||||
|
||||
interface MyEnumBaseInterface {
|
||||
String getBaseCode();
|
||||
}
|
||||
|
||||
interface MyEnumInterface {
|
||||
|
||||
interface MyEnumInterface extends MyEnumBaseInterface {
|
||||
String getCode();
|
||||
}
|
||||
|
||||
public static enum MyEnum implements MyEnumInterface {
|
||||
|
||||
A {
|
||||
@Override
|
||||
public String getCode() {
|
||||
return "1";
|
||||
}
|
||||
A("1"),
|
||||
B("2"),
|
||||
C("3");
|
||||
|
||||
private String code;
|
||||
|
||||
MyEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseCode() {
|
||||
return "base" + code;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,6 +1001,59 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
}
|
||||
|
||||
private static class StringToMyEnumInterfaceConverterFactory implements ConverterFactory<String, MyEnumInterface> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends MyEnumInterface> Converter<String, T> getConverter(Class<T> targetType) {
|
||||
return new StringToMyEnumInterfaceConverter(targetType);
|
||||
}
|
||||
|
||||
private static class StringToMyEnumInterfaceConverter<T extends Enum<?> & MyEnumInterface> implements Converter<String, T> {
|
||||
private final Class<T> enumType;
|
||||
|
||||
public StringToMyEnumInterfaceConverter(Class<T> enumType) {
|
||||
this.enumType = enumType;
|
||||
}
|
||||
|
||||
public T convert(String source) {
|
||||
for (T value : enumType.getEnumConstants()) {
|
||||
if (value.getCode().equals(source)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class StringToMyEnumBaseInterfaceConverterFactory implements ConverterFactory<String, MyEnumBaseInterface> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends MyEnumBaseInterface> Converter<String, T> getConverter(Class<T> targetType) {
|
||||
return new StringToMyEnumBaseInterfaceConverter(targetType);
|
||||
}
|
||||
|
||||
private static class StringToMyEnumBaseInterfaceConverter<T extends Enum<?> & MyEnumBaseInterface> implements Converter<String, T> {
|
||||
private final Class<T> enumType;
|
||||
|
||||
public StringToMyEnumBaseInterfaceConverter(Class<T> enumType) {
|
||||
this.enumType = enumType;
|
||||
}
|
||||
|
||||
public T convert(String source) {
|
||||
for (T value : enumType.getEnumConstants()) {
|
||||
if (value.getBaseCode().equals(source)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class MyStringToStringCollectionConverter implements Converter<String, Collection<String>> {
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue