Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
Expand Down Expand Up @@ -71,12 +70,17 @@ public static boolean canConvertElements(@Nullable TypeDescriptor sourceElementT
return false;
}

public static Class<?> getEnumType(Class<?> targetType) {
/**
* Resolve the enum type for the supplied target type.
* @param targetType the target type for which to resolve the enum type
* @return the resolved enum type, or {@code null} if the supplied target type
* does not refer to an enum
*/
public static @Nullable Class<?> resolveEnumType(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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

import org.jspecify.annotations.Nullable;

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.ConverterFactory;
import org.springframework.util.Assert;

/**
* Converts from an Integer to a {@link java.lang.Enum} by calling {@link Class#getEnumConstants()}.
Expand All @@ -29,11 +32,18 @@
* @since 4.3
*/
@SuppressWarnings({"rawtypes", "unchecked"})
final class IntegerToEnumConverterFactory implements ConverterFactory<Integer, Enum> {
final class IntegerToEnumConverterFactory implements ConverterFactory<Integer, Enum>, ConditionalConverter {

@Override
public <T extends Enum> Converter<Integer, @Nullable T> getConverter(Class<T> targetType) {
return new IntegerToEnum(ConversionUtils.getEnumType(targetType));
Class<?> enumType = ConversionUtils.resolveEnumType(targetType);
Assert.notNull(enumType, () -> "The target type " + targetType.getName() + " does not refer to an enum");
return new IntegerToEnum(enumType);
}

@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return (ConversionUtils.resolveEnumType(targetType.getType()) != null);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

import org.jspecify.annotations.Nullable;

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.ConverterFactory;
import org.springframework.util.Assert;

/**
* Converts from a String to a {@link java.lang.Enum} by calling {@link Enum#valueOf(Class, String)}.
Expand All @@ -29,11 +32,18 @@
* @since 3.0
*/
@SuppressWarnings({"rawtypes", "unchecked"})
final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
final class StringToEnumConverterFactory implements ConverterFactory<String, Enum>, ConditionalConverter {

@Override
public <T extends Enum> Converter<String, @Nullable T> getConverter(Class<T> targetType) {
return new StringToEnum(ConversionUtils.getEnumType(targetType));
Class<?> enumType = ConversionUtils.resolveEnumType(targetType);
Assert.notNull(enumType, () -> "The target type " + targetType.getName() + " does not refer to an enum");
return new StringToEnum(enumType);
}

@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return (ConversionUtils.resolveEnumType(targetType.getType()) != null);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,20 @@ void stringToEnumWithBaseInterfaceConversion() {
assertThat(conversionService.convert("base1", MyEnum.class)).isEqualTo(MyEnum.A);
}

@Test // gh-34532
void canConvertToEnumDoesNotThrowForNonEnumTargetType() {
conversionService.addConverterFactory(new StringToEnumConverterFactory());
conversionService.addConverterFactory(new IntegerToEnumConverterFactory());

assertThat(conversionService.canConvert(String.class, Enum.class)).isFalse();
assertThat(conversionService.canConvert(Integer.class, Enum.class)).isFalse();

assertThat(conversionService.canConvert(String.class, MyEnum.class)).isTrue();
assertThat(conversionService.canConvert(Integer.class, MyEnum.class)).isTrue();
assertThat(conversionService.convert("A", MyEnum.class)).isEqualTo(MyEnum.A);
assertThat(conversionService.convert(0, MyEnum.class)).isEqualTo(MyEnum.A);
}

@Test
void convertNullAnnotatedStringToString() throws Exception {
String source = null;
Expand Down