refined TypeConverterDelegate's ConversionService exception handling

Issue: SPR-9498
This commit is contained in:
Juergen Hoeller 2012-09-05 00:59:46 +02:00
parent 15e384dfd3
commit 6bce098310
2 changed files with 62 additions and 61 deletions

View File

@ -176,11 +176,13 @@ class TypeConverterDelegate {
}
}
if (editor == null) {
editor = findDefaultEditor(requiredType, typeDescriptor);
editor = findDefaultEditor(requiredType);
}
convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
}
boolean standardConversion = false;
if (requiredType != null) {
// Try to apply some standard type conversion rules if appropriate.
@ -196,14 +198,17 @@ class TypeConverterDelegate {
// Convert elements to target type, if determined.
convertedValue = convertToTypedCollection(
(Collection) convertedValue, propertyName, requiredType, typeDescriptor);
standardConversion = true;
}
else if (convertedValue instanceof Map) {
// Convert keys and values to respective target type, if determined.
convertedValue = convertToTypedMap(
(Map) convertedValue, propertyName, requiredType, typeDescriptor);
standardConversion = true;
}
if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) {
convertedValue = Array.get(convertedValue, 0);
standardConversion = true;
}
if (String.class.equals(requiredType) && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) {
// We can stringify any primitive value...
@ -234,6 +239,7 @@ class TypeConverterDelegate {
}
convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue);
standardConversion = true;
}
}
@ -262,8 +268,7 @@ class TypeConverterDelegate {
}
if (firstAttemptEx != null) {
if (editor == null && convertedValue == newValue && requiredType != null &&
!ClassUtils.isAssignableValue(requiredType, convertedValue)) {
if (editor == null && !standardConversion && requiredType != null && !Object.class.equals(requiredType)) {
throw firstAttemptEx;
}
logger.debug("Original ConversionService attempt failed - ignored since " +
@ -322,16 +327,11 @@ class TypeConverterDelegate {
/**
* Find a default editor for the given type.
* @param requiredType the type to find an editor for
* @param descriptor the JavaBeans descriptor for the property
* @return the corresponding editor, or <code>null</code> if none
*/
protected PropertyEditor findDefaultEditor(Class requiredType, TypeDescriptor typeDescriptor) {
private PropertyEditor findDefaultEditor(Class requiredType) {
PropertyEditor editor = null;
//if (typeDescriptor instanceof PropertyTypeDescriptor) {
//PropertyDescriptor pd = ((PropertyTypeDescriptor) typeDescriptor).getPropertyDescriptor();
//editor = pd.createPropertyEditor(this.targetObject);
//}
if (editor == null && requiredType != null) {
if (requiredType != null) {
// No custom editor -> check BeanWrapperImpl's default editors.
editor = this.propertyEditorRegistry.getDefaultEditor(requiredType);
if (editor == null && !String.class.equals(requiredType)) {
@ -353,7 +353,7 @@ class TypeConverterDelegate {
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
protected Object doConvertValue(Object oldValue, Object newValue, Class<?> requiredType, PropertyEditor editor) {
private Object doConvertValue(Object oldValue, Object newValue, Class<?> requiredType, PropertyEditor editor) {
Object convertedValue = newValue;
boolean sharedEditor = false;
@ -440,7 +440,7 @@ class TypeConverterDelegate {
* @param editor the PropertyEditor to use
* @return the converted value
*/
protected Object doConvertTextValue(Object oldValue, String newTextValue, PropertyEditor editor) {
private Object doConvertTextValue(Object oldValue, String newTextValue, PropertyEditor editor) {
try {
editor.setValue(oldValue);
}
@ -454,7 +454,7 @@ class TypeConverterDelegate {
return editor.getValue();
}
protected Object convertToTypedArray(Object input, String propertyName, Class<?> componentType) {
private Object convertToTypedArray(Object input, String propertyName, Class<?> componentType) {
if (input instanceof Collection) {
// Convert Collection elements to array elements.
Collection coll = (Collection) input;
@ -493,7 +493,7 @@ class TypeConverterDelegate {
}
@SuppressWarnings("unchecked")
protected Collection convertToTypedCollection(
private Collection convertToTypedCollection(
Collection original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
if (!Collection.class.isAssignableFrom(requiredType)) {
@ -575,7 +575,7 @@ class TypeConverterDelegate {
}
@SuppressWarnings("unchecked")
protected Map convertToTypedMap(
private Map convertToTypedMap(
Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
if (!Map.class.isAssignableFrom(requiredType)) {

View File

@ -72,6 +72,28 @@ import test.beans.TestBean;
*/
public final class BeanWrapperTests {
@Test
public void testNullNestedTypeDescriptor() {
Foo foo = new Foo();
BeanWrapperImpl wrapper = new BeanWrapperImpl(foo);
wrapper.setConversionService(new DefaultConversionService());
wrapper.setAutoGrowNestedPaths(true);
wrapper.setPropertyValue("listOfMaps[0]['luckyNumber']", "9");
assertEquals("9", foo.listOfMaps.get(0).get("luckyNumber"));
}
@Test
public void testNullNestedTypeDescriptor2() {
Foo foo = new Foo();
BeanWrapperImpl wrapper = new BeanWrapperImpl(foo);
wrapper.setConversionService(new DefaultConversionService());
wrapper.setAutoGrowNestedPaths(true);
Map<String, String> map = new HashMap<String, String>();
map.put("favoriteNumber", "9");
wrapper.setPropertyValue("list[0]", map);
assertEquals(map, foo.list.get(0));
}
@Test
public void testNullNestedTypeDescriptorWithNoConversionService() {
Foo foo = new Foo();
@ -96,52 +118,6 @@ public final class BeanWrapperTests {
assertEquals("9", foo.listOfMaps.get(0).get("luckyNumber"));
}
@Test
public void testNullNestedTypeDescriptor() {
Foo foo = new Foo();
BeanWrapperImpl wrapper = new BeanWrapperImpl(foo);
wrapper.setConversionService(new DefaultConversionService());
wrapper.setAutoGrowNestedPaths(true);
wrapper.setPropertyValue("listOfMaps[0]['luckyNumber']", "9");
assertEquals("9", foo.listOfMaps.get(0).get("luckyNumber"));
}
@Test
public void testNullNestedTypeDescriptor2() {
Foo foo = new Foo();
BeanWrapperImpl wrapper = new BeanWrapperImpl(foo);
wrapper.setConversionService(new DefaultConversionService());
wrapper.setAutoGrowNestedPaths(true);
Map<String, String> map = new HashMap<String, String>();
map.put("favoriteNumber", "9");
wrapper.setPropertyValue("list[0]", map);
assertEquals(map, foo.list.get(0));
}
static class Foo {
private List list;
private List<Map> listOfMaps;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public List<Map> getListOfMaps() {
return listOfMaps;
}
public void setListOfMaps(List<Map> listOfMaps) {
this.listOfMaps = listOfMaps;
}
}
@Test
public void testIsReadablePropertyNotReadable() {
NoRead nr = new NoRead();
@ -1565,6 +1541,31 @@ public final class BeanWrapperTests {
assertEquals(TestEnum.TEST_VALUE, consumer.getEnumValue());
}
private static class Foo {
private List list;
private List<Map> listOfMaps;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public List<Map> getListOfMaps() {
return listOfMaps;
}
public void setListOfMaps(List<Map> listOfMaps) {
this.listOfMaps = listOfMaps;
}
}
private static class DifferentTestBean extends TestBean {
// class to test naming of beans in a BeanWrapper error message
}