Ensure ConversionService.canConvert(Enum) no longer throws an exception
This commit is contained in:
parent
702c63a7e8
commit
9034e73bd2
|
@ -21,8 +21,9 @@ import org.jspecify.annotations.Nullable;
|
|||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalConverter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
|
@ -71,13 +72,30 @@ abstract class ConversionUtils {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static Class<?> getEnumType(Class<?> targetType) {
|
||||
public static @Nullable Class<?> getEnumType(Class<?> targetType) {
|
||||
Class<?> enumType = targetType;
|
||||
while (enumType != null && !enumType.isEnum()) {
|
||||
enumType = enumType.getSuperclass();
|
||||
}
|
||||
Assert.notNull(enumType, () -> "The target type " + targetType.getName() + " does not refer to an enum");
|
||||
return enumType;
|
||||
}
|
||||
|
||||
static class NonConvertableToEnum<T> implements Converter<String, T>, ConditionalConverter {
|
||||
|
||||
private final Class<T> targetType;
|
||||
|
||||
public NonConvertableToEnum(Class<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable T convert(String source) {
|
||||
throw new IllegalArgumentException("The target type " + targetType.getName() + " does not refer to an enum");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,11 @@ final class IntegerToEnumConverterFactory implements ConverterFactory<Integer, E
|
|||
|
||||
@Override
|
||||
public <T extends Enum> Converter<Integer, T> getConverter(Class<T> targetType) {
|
||||
return new IntegerToEnum(ConversionUtils.getEnumType(targetType));
|
||||
Class<?> enumType = ConversionUtils.getEnumType(targetType);
|
||||
if (enumType == null) {
|
||||
return new ConversionUtils.NonConvertableToEnum(targetType);
|
||||
}
|
||||
return new IntegerToEnum(enumType);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,10 +33,13 @@ final class StringToEnumConverterFactory implements ConverterFactory<String, Enu
|
|||
|
||||
@Override
|
||||
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
|
||||
return new StringToEnum(ConversionUtils.getEnumType(targetType));
|
||||
Class<?> enumType = ConversionUtils.getEnumType(targetType);
|
||||
if (enumType == null) {
|
||||
return new ConversionUtils.NonConvertableToEnum(targetType);
|
||||
}
|
||||
return new StringToEnum(enumType);
|
||||
}
|
||||
|
||||
|
||||
private static class StringToEnum<T extends Enum> implements Converter<String, T> {
|
||||
|
||||
private final Class<T> enumType;
|
||||
|
|
|
@ -503,6 +503,16 @@ class GenericConversionServiceTests {
|
|||
assertThat(conversionService.convert("base1", MyEnum.class)).isEqualTo(MyEnum.A);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toEnumCanConvertShouldNotThrowException() {
|
||||
conversionService.addConverterFactory(new IntegerToEnumConverterFactory());
|
||||
conversionService.addConverterFactory(new StringToEnumConverterFactory());
|
||||
assertThat(conversionService.canConvert(Integer.class, Enum.class)).isFalse();
|
||||
assertThat(conversionService.canConvert(Integer.class, MyEnum.class)).isTrue();
|
||||
assertThat(conversionService.canConvert(String.class, Enum.class)).isFalse();
|
||||
assertThat(conversionService.canConvert(String.class, MyEnum.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertNullAnnotatedStringToString() throws Exception {
|
||||
String source = null;
|
||||
|
|
Loading…
Reference in New Issue