From 9a6c6b9ee63caa30b9e37960348f8f1a1259e123 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 25 Feb 2013 13:17:40 -0800 Subject: [PATCH] StringToEnumConverterFactory class from enum value Update StringToEnumConverterFactory to search superclasses until Class.isEnum() returns true. This allows conversion when the enum class is obtained from the enum value: public static enum SubFoo { BAR { String s() { return "x"; } }; abstract String s(); } conversionService.convert("BAR", SubFoo.BAR.getClass()) This fix is particularly important when converting collections of enums. Issue: SPR-10329 --- .../support/StringToEnumConverterFactory.java | 11 +++++++-- .../support/DefaultConversionTests.java | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java b/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java index 62cf4748ea..7326b3f045 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.core.convert.support; 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 java.lang.Enum by calling {@link Enum#valueOf(Class, String)}. @@ -29,7 +30,13 @@ import org.springframework.core.convert.converter.ConverterFactory; final class StringToEnumConverterFactory implements ConverterFactory { public Converter getConverter(Class targetType) { - return new StringToEnum(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 new StringToEnum(enumType); } private class StringToEnum implements Converter { diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/DefaultConversionTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/DefaultConversionTests.java index 7b2ff0490a..ba42cddf9d 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/DefaultConversionTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/DefaultConversionTests.java @@ -17,6 +17,7 @@ package org.springframework.core.convert.support; import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.*; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -212,6 +213,11 @@ public class DefaultConversionTests { assertEquals(Foo.BAR, conversionService.convert("BAR", Foo.class)); } + @Test + public void testStringToEnumWithSubclss() throws Exception { + assertEquals(SubFoo.BAZ, conversionService.convert("BAZ", SubFoo.BAR.getClass())); + } + @Test public void testStringToEnumEmptyString() { assertEquals(null, conversionService.convert("", Foo.class)); @@ -226,6 +232,24 @@ public class DefaultConversionTests { BAR, BAZ; } + public static enum SubFoo { + + BAR { + @Override + String s() { + return "x"; + } + }, + BAZ { + @Override + String s() { + return "y"; + } + }; + + abstract String s(); + } + @Test public void testStringToLocale() { assertEquals(Locale.ENGLISH, conversionService.convert("en", Locale.class));