@ -85,7 +85,7 @@ class TypeConverterDelegate {
@@ -85,7 +85,7 @@ class TypeConverterDelegate {
* @throws IllegalArgumentException if type conversion failed
* /
public < T > T convertIfNecessary ( Object newValue , Class < T > requiredType ) throws IllegalArgumentException {
return convertIfNecessary ( null , null , newValue , requiredType , null , null ) ;
return convertIfNecessary ( null , null , newValue , requiredType , TypeDescriptor . valueOf ( requiredType ) ) ;
}
/ * *
@ -101,7 +101,8 @@ class TypeConverterDelegate {
@@ -101,7 +101,8 @@ class TypeConverterDelegate {
public < T > T convertIfNecessary ( Object newValue , Class < T > requiredType , MethodParameter methodParam )
throws IllegalArgumentException {
return convertIfNecessary ( null , null , newValue , requiredType , null , methodParam ) ;
return convertIfNecessary ( null , null , newValue , requiredType ,
( methodParam ! = null ? new TypeDescriptor ( methodParam ) : TypeDescriptor . valueOf ( requiredType ) ) ) ;
}
/ * *
@ -118,7 +119,25 @@ class TypeConverterDelegate {
@@ -118,7 +119,25 @@ class TypeConverterDelegate {
String propertyName , Object oldValue , Object newValue , Class < T > requiredType )
throws IllegalArgumentException {
return convertIfNecessary ( propertyName , oldValue , newValue , requiredType , null , null ) ;
return convertIfNecessary ( propertyName , oldValue , newValue , requiredType , TypeDescriptor . valueOf ( requiredType ) ) ;
}
/ * *
* Convert the value to the required type ( if necessary from a String ) ,
* for the specified property .
* @param propertyName name of the property
* @param oldValue the previous value , if available ( may be < code > null < / code > )
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* ( or < code > null < / code > if not known , for example in case of a collection element )
* @param methodParam the method parameter that is the target of the conversion
* @return the new value , possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
* /
public < T > T convertIfNecessary ( String propertyName , Object oldValue , Object newValue ,
Class < T > requiredType , MethodParameter methodParam ) throws IllegalArgumentException {
return convertIfNecessary ( propertyName , oldValue , newValue , requiredType , new TypeDescriptor ( methodParam ) ) ;
}
/ * *
@ -132,9 +151,22 @@ class TypeConverterDelegate {
@@ -132,9 +151,22 @@ class TypeConverterDelegate {
public Object convertIfNecessary ( Object oldValue , Object newValue , PropertyDescriptor descriptor )
throws IllegalArgumentException {
return convertIfNecessary (
descriptor . getName ( ) , oldValue , newValue , descriptor . getPropertyType ( ) , descriptor ,
BeanUtils . getWriteMethodParameter ( descriptor ) ) ;
return convertIfNecessary ( descriptor . getName ( ) , oldValue , newValue , descriptor . getPropertyType ( ) ,
new BeanTypeDescriptor ( descriptor ) ) ;
}
/ * *
* Convert the value to the required type for the specified property .
* @param oldValue the previous value , if available ( may be < code > null < / code > )
* @param newValue the proposed new value
* @param field the field that is the target of the conversion
* @return the new value , possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
* /
public Object convertIfNecessary ( Object oldValue , Object newValue , Field field )
throws IllegalArgumentException {
return convertIfNecessary ( field . getName ( ) , oldValue , newValue , field . getType ( ) , new TypeDescriptor ( field ) ) ;
}
@ -146,17 +178,13 @@ class TypeConverterDelegate {
@@ -146,17 +178,13 @@ class TypeConverterDelegate {
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* ( or < code > null < / code > if not known , for example in case of a collection element )
* @param descriptor the JavaBeans descriptor for the property
* @param methodParam the method parameter that is the target of the conversion
* ( may be < code > null < / code > )
* @param typeDescriptor the descriptor for the target property or field
* @return the new value , possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
* /
@SuppressWarnings ( "unchecked" )
protected < T > T convertIfNecessary (
String propertyName , Object oldValue , Object newValue , Class < T > requiredType ,
PropertyDescriptor descriptor , MethodParameter methodParam )
throws IllegalArgumentException {
private < T > T convertIfNecessary ( String propertyName , Object oldValue , Object newValue ,
Class < T > requiredType , TypeDescriptor typeDescriptor ) throws IllegalArgumentException {
Object convertedValue = newValue ;
@ -167,23 +195,15 @@ class TypeConverterDelegate {
@@ -167,23 +195,15 @@ class TypeConverterDelegate {
ConversionService conversionService = this . propertyEditorRegistry . getConversionService ( ) ;
if ( editor = = null & & conversionService ! = null & & convertedValue ! = null ) {
TypeDescriptor sourceTypeDesc = TypeDescriptor . valueOf ( convertedValue . getClass ( ) ) ;
TypeDescriptor targetTypeDesc ;
if ( methodParam ! = null ) {
targetTypeDesc = ( descriptor ! = null ?
new BeanTypeDescriptor ( methodParam , descriptor ) : new TypeDescriptor ( methodParam ) ) ;
}
else {
targetTypeDesc = TypeDescriptor . valueOf ( requiredType ) ;
}
if ( conversionService . canConvert ( sourceTypeDesc , targetTypeDesc ) ) {
return ( T ) conversionService . convert ( convertedValue , sourceTypeDesc , targetTypeDesc ) ;
if ( conversionService . canConvert ( sourceTypeDesc , typeDescriptor ) ) {
return ( T ) conversionService . convert ( convertedValue , sourceTypeDesc , typeDescriptor ) ;
}
}
// Value not of required type?
if ( editor ! = null | | ( requiredType ! = null & & ! ClassUtils . isAssignableValue ( requiredType , convertedValue ) ) ) {
if ( editor = = null ) {
editor = findDefaultEditor ( requiredType , d escriptor) ;
editor = findDefaultEditor ( requiredType , typeDescriptor ) ;
}
convertedValue = doConvertValue ( oldValue , convertedValue , requiredType , editor ) ;
}
@ -199,12 +219,12 @@ class TypeConverterDelegate {
@@ -199,12 +219,12 @@ class TypeConverterDelegate {
else if ( convertedValue instanceof Collection ) {
// Convert elements to target type, if determined.
convertedValue = convertToTypedCollection (
( Collection ) convertedValue , propertyName , requiredType , methodParam ) ;
( Collection ) convertedValue , propertyName , requiredType , typeDescriptor ) ;
}
else if ( convertedValue instanceof Map ) {
// Convert keys and values to respective target type, if determined.
convertedValue = convertToTypedMap (
( Map ) convertedValue , propertyName , requiredType , methodParam ) ;
( Map ) convertedValue , propertyName , requiredType , typeDescriptor ) ;
}
if ( convertedValue . getClass ( ) . isArray ( ) & & Array . getLength ( convertedValue ) = = 1 ) {
convertedValue = Array . get ( convertedValue , 0 ) ;
@ -316,10 +336,11 @@ class TypeConverterDelegate {
@@ -316,10 +336,11 @@ class TypeConverterDelegate {
* @param descriptor the JavaBeans descriptor for the property
* @return the corresponding editor , or < code > null < / code > if none
* /
protected PropertyEditor findDefaultEditor ( Class requiredType , PropertyDescriptor d escriptor) {
protected PropertyEditor findDefaultEditor ( Class requiredType , TypeDescriptor typeD escriptor) {
PropertyEditor editor = null ;
if ( descriptor ! = null ) {
editor = descriptor . createPropertyEditor ( this . targetObject ) ;
if ( typeDescriptor instanceof BeanTypeDescriptor ) {
PropertyDescriptor pd = ( ( BeanTypeDescriptor ) typeDescriptor ) . getPropertyDescriptor ( ) ;
editor = pd . createPropertyEditor ( this . targetObject ) ;
}
if ( editor = = null & & requiredType ! = null ) {
// No custom editor -> check BeanWrapperImpl's default editors.
@ -484,9 +505,10 @@ class TypeConverterDelegate {
@@ -484,9 +505,10 @@ class TypeConverterDelegate {
@SuppressWarnings ( "unchecked" )
protected Collection convertToTypedCollection (
Collection original , String propertyName , Class requiredType , MethodParameter methodParam ) {
Collection original , String propertyName , Class requiredType , TypeDescriptor typeDescriptor ) {
boolean originalAllowed = requiredType . isInstance ( original ) ;
MethodParameter methodParam = typeDescriptor . getMethodParameter ( ) ;
Class elementType = null ;
if ( methodParam ! = null ) {
elementType = GenericCollectionTypeResolver . getCollectionParameterType ( methodParam ) ;
@ -540,7 +562,7 @@ class TypeConverterDelegate {
@@ -540,7 +562,7 @@ class TypeConverterDelegate {
methodParam . increaseNestingLevel ( ) ;
}
Object convertedElement =
convertIfNecessary ( indexedPropertyName , null , element , elementType , null , methodParam ) ;
convertIfNecessary ( indexedPropertyName , null , element , elementType , typeDescriptor ) ;
if ( methodParam ! = null ) {
methodParam . decreaseNestingLevel ( ) ;
}
@ -551,10 +573,11 @@ class TypeConverterDelegate {
@@ -551,10 +573,11 @@ class TypeConverterDelegate {
}
@SuppressWarnings ( "unchecked" )
protected Map convertToTypedMap ( Map original , String propertyName , Class requiredType , MethodParameter methodParam ) {
protected Map convertToTypedMap ( Map original , String propertyName , Class requiredType , TypeDescriptor typeDescriptor ) {
boolean originalAllowed = requiredType . isInstance ( original ) ;
Class keyType = null ;
Class valueType = null ;
MethodParameter methodParam = typeDescriptor . getMethodParameter ( ) ;
if ( methodParam ! = null ) {
keyType = GenericCollectionTypeResolver . getMapKeyParameterType ( methodParam ) ;
valueType = GenericCollectionTypeResolver . getMapValueParameterType ( methodParam ) ;
@ -609,11 +632,11 @@ class TypeConverterDelegate {
@@ -609,11 +632,11 @@ class TypeConverterDelegate {
methodParam . increaseNestingLevel ( ) ;
methodParam . setTypeIndexForCurrentLevel ( 0 ) ;
}
Object convertedKey = convertIfNecessary ( keyedPropertyName , null , key , keyType , null , methodParam ) ;
Object convertedKey = convertIfNecessary ( keyedPropertyName , null , key , keyType , typeDescriptor ) ;
if ( methodParam ! = null ) {
methodParam . setTypeIndexForCurrentLevel ( 1 ) ;
}
Object convertedValue = convertIfNecessary ( keyedPropertyName , null , value , valueType , null , methodParam ) ;
Object convertedValue = convertIfNecessary ( keyedPropertyName , null , value , valueType , typeDescriptor ) ;
if ( methodParam ! = null ) {
methodParam . decreaseNestingLevel ( ) ;
}