@@ -85,7 +85,7 @@ public TypeConverterDelegate(PropertyEditorRegistrySupport propertyEditorRegistr
85
85
* @throws IllegalArgumentException if type conversion failed
86
86
*/
87
87
public <T > T convertIfNecessary (Object newValue , Class <T > requiredType ) throws IllegalArgumentException {
88
- return convertIfNecessary (null , null , newValue , requiredType , null , null );
88
+ return convertIfNecessary (null , null , newValue , requiredType , TypeDescriptor . valueOf ( requiredType ) );
89
89
}
90
90
91
91
/**
@@ -101,7 +101,8 @@ public <T> T convertIfNecessary(Object newValue, Class<T> requiredType) throws I
101
101
public <T > T convertIfNecessary (Object newValue , Class <T > requiredType , MethodParameter methodParam )
102
102
throws IllegalArgumentException {
103
103
104
- return convertIfNecessary (null , null , newValue , requiredType , null , methodParam );
104
+ return convertIfNecessary (null , null , newValue , requiredType ,
105
+ (methodParam != null ? new TypeDescriptor (methodParam ) : TypeDescriptor .valueOf (requiredType )));
105
106
}
106
107
107
108
/**
@@ -118,7 +119,25 @@ public <T> T convertIfNecessary(
118
119
String propertyName , Object oldValue , Object newValue , Class <T > requiredType )
119
120
throws IllegalArgumentException {
120
121
121
- return convertIfNecessary (propertyName , oldValue , newValue , requiredType , null , null );
122
+ return convertIfNecessary (propertyName , oldValue , newValue , requiredType , TypeDescriptor .valueOf (requiredType ));
123
+ }
124
+
125
+ /**
126
+ * Convert the value to the required type (if necessary from a String),
127
+ * for the specified property.
128
+ * @param propertyName name of the property
129
+ * @param oldValue the previous value, if available (may be <code>null</code>)
130
+ * @param newValue the proposed new value
131
+ * @param requiredType the type we must convert to
132
+ * (or <code>null</code> if not known, for example in case of a collection element)
133
+ * @param methodParam the method parameter that is the target of the conversion
134
+ * @return the new value, possibly the result of type conversion
135
+ * @throws IllegalArgumentException if type conversion failed
136
+ */
137
+ public <T > T convertIfNecessary (String propertyName , Object oldValue , Object newValue ,
138
+ Class <T > requiredType , MethodParameter methodParam ) throws IllegalArgumentException {
139
+
140
+ return convertIfNecessary (propertyName , oldValue , newValue , requiredType , new TypeDescriptor (methodParam ));
122
141
}
123
142
124
143
/**
@@ -132,9 +151,22 @@ public <T> T convertIfNecessary(
132
151
public Object convertIfNecessary (Object oldValue , Object newValue , PropertyDescriptor descriptor )
133
152
throws IllegalArgumentException {
134
153
135
- return convertIfNecessary (
136
- descriptor .getName (), oldValue , newValue , descriptor .getPropertyType (), descriptor ,
137
- BeanUtils .getWriteMethodParameter (descriptor ));
154
+ return convertIfNecessary (descriptor .getName (), oldValue , newValue , descriptor .getPropertyType (),
155
+ new BeanTypeDescriptor (descriptor ));
156
+ }
157
+
158
+ /**
159
+ * Convert the value to the required type for the specified property.
160
+ * @param oldValue the previous value, if available (may be <code>null</code>)
161
+ * @param newValue the proposed new value
162
+ * @param field the field that is the target of the conversion
163
+ * @return the new value, possibly the result of type conversion
164
+ * @throws IllegalArgumentException if type conversion failed
165
+ */
166
+ public Object convertIfNecessary (Object oldValue , Object newValue , Field field )
167
+ throws IllegalArgumentException {
168
+
169
+ return convertIfNecessary (field .getName (), oldValue , newValue , field .getType (), new TypeDescriptor (field ));
138
170
}
139
171
140
172
@@ -146,17 +178,13 @@ public Object convertIfNecessary(Object oldValue, Object newValue, PropertyDescr
146
178
* @param newValue the proposed new value
147
179
* @param requiredType the type we must convert to
148
180
* (or <code>null</code> if not known, for example in case of a collection element)
149
- * @param descriptor the JavaBeans descriptor for the property
150
- * @param methodParam the method parameter that is the target of the conversion
151
- * (may be <code>null</code>)
181
+ * @param typeDescriptor the descriptor for the target property or field
152
182
* @return the new value, possibly the result of type conversion
153
183
* @throws IllegalArgumentException if type conversion failed
154
184
*/
155
185
@ SuppressWarnings ("unchecked" )
156
- protected <T > T convertIfNecessary (
157
- String propertyName , Object oldValue , Object newValue , Class <T > requiredType ,
158
- PropertyDescriptor descriptor , MethodParameter methodParam )
159
- throws IllegalArgumentException {
186
+ private <T > T convertIfNecessary (String propertyName , Object oldValue , Object newValue ,
187
+ Class <T > requiredType , TypeDescriptor typeDescriptor ) throws IllegalArgumentException {
160
188
161
189
Object convertedValue = newValue ;
162
190
@@ -167,23 +195,15 @@ protected <T> T convertIfNecessary(
167
195
ConversionService conversionService = this .propertyEditorRegistry .getConversionService ();
168
196
if (editor == null && conversionService != null && convertedValue != null ) {
169
197
TypeDescriptor sourceTypeDesc = TypeDescriptor .valueOf (convertedValue .getClass ());
170
- TypeDescriptor targetTypeDesc ;
171
- if (methodParam != null ) {
172
- targetTypeDesc = (descriptor != null ?
173
- new BeanTypeDescriptor (methodParam , descriptor ) : new TypeDescriptor (methodParam ));
174
- }
175
- else {
176
- targetTypeDesc = TypeDescriptor .valueOf (requiredType );
177
- }
178
- if (conversionService .canConvert (sourceTypeDesc , targetTypeDesc )) {
179
- return (T ) conversionService .convert (convertedValue , sourceTypeDesc , targetTypeDesc );
198
+ if (conversionService .canConvert (sourceTypeDesc , typeDescriptor )) {
199
+ return (T ) conversionService .convert (convertedValue , sourceTypeDesc , typeDescriptor );
180
200
}
181
201
}
182
202
183
203
// Value not of required type?
184
204
if (editor != null || (requiredType != null && !ClassUtils .isAssignableValue (requiredType , convertedValue ))) {
185
205
if (editor == null ) {
186
- editor = findDefaultEditor (requiredType , descriptor );
206
+ editor = findDefaultEditor (requiredType , typeDescriptor );
187
207
}
188
208
convertedValue = doConvertValue (oldValue , convertedValue , requiredType , editor );
189
209
}
@@ -199,12 +219,12 @@ protected <T> T convertIfNecessary(
199
219
else if (convertedValue instanceof Collection ) {
200
220
// Convert elements to target type, if determined.
201
221
convertedValue = convertToTypedCollection (
202
- (Collection ) convertedValue , propertyName , requiredType , methodParam );
222
+ (Collection ) convertedValue , propertyName , requiredType , typeDescriptor );
203
223
}
204
224
else if (convertedValue instanceof Map ) {
205
225
// Convert keys and values to respective target type, if determined.
206
226
convertedValue = convertToTypedMap (
207
- (Map ) convertedValue , propertyName , requiredType , methodParam );
227
+ (Map ) convertedValue , propertyName , requiredType , typeDescriptor );
208
228
}
209
229
if (convertedValue .getClass ().isArray () && Array .getLength (convertedValue ) == 1 ) {
210
230
convertedValue = Array .get (convertedValue , 0 );
@@ -316,10 +336,11 @@ private Object attemptToConvertStringToEnum(Class<?> requiredType, String trimme
316
336
* @param descriptor the JavaBeans descriptor for the property
317
337
* @return the corresponding editor, or <code>null</code> if none
318
338
*/
319
- protected PropertyEditor findDefaultEditor (Class requiredType , PropertyDescriptor descriptor ) {
339
+ protected PropertyEditor findDefaultEditor (Class requiredType , TypeDescriptor typeDescriptor ) {
320
340
PropertyEditor editor = null ;
321
- if (descriptor != null ) {
322
- editor = descriptor .createPropertyEditor (this .targetObject );
341
+ if (typeDescriptor instanceof BeanTypeDescriptor ) {
342
+ PropertyDescriptor pd = ((BeanTypeDescriptor ) typeDescriptor ).getPropertyDescriptor ();
343
+ editor = pd .createPropertyEditor (this .targetObject );
323
344
}
324
345
if (editor == null && requiredType != null ) {
325
346
// No custom editor -> check BeanWrapperImpl's default editors.
@@ -484,9 +505,10 @@ else if (input.getClass().isArray()) {
484
505
485
506
@ SuppressWarnings ("unchecked" )
486
507
protected Collection convertToTypedCollection (
487
- Collection original , String propertyName , Class requiredType , MethodParameter methodParam ) {
508
+ Collection original , String propertyName , Class requiredType , TypeDescriptor typeDescriptor ) {
488
509
489
510
boolean originalAllowed = requiredType .isInstance (original );
511
+ MethodParameter methodParam = typeDescriptor .getMethodParameter ();
490
512
Class elementType = null ;
491
513
if (methodParam != null ) {
492
514
elementType = GenericCollectionTypeResolver .getCollectionParameterType (methodParam );
@@ -540,7 +562,7 @@ protected Collection convertToTypedCollection(
540
562
methodParam .increaseNestingLevel ();
541
563
}
542
564
Object convertedElement =
543
- convertIfNecessary (indexedPropertyName , null , element , elementType , null , methodParam );
565
+ convertIfNecessary (indexedPropertyName , null , element , elementType , typeDescriptor );
544
566
if (methodParam != null ) {
545
567
methodParam .decreaseNestingLevel ();
546
568
}
@@ -551,10 +573,11 @@ protected Collection convertToTypedCollection(
551
573
}
552
574
553
575
@ SuppressWarnings ("unchecked" )
554
- protected Map convertToTypedMap (Map original , String propertyName , Class requiredType , MethodParameter methodParam ) {
576
+ protected Map convertToTypedMap (Map original , String propertyName , Class requiredType , TypeDescriptor typeDescriptor ) {
555
577
boolean originalAllowed = requiredType .isInstance (original );
556
578
Class keyType = null ;
557
579
Class valueType = null ;
580
+ MethodParameter methodParam = typeDescriptor .getMethodParameter ();
558
581
if (methodParam != null ) {
559
582
keyType = GenericCollectionTypeResolver .getMapKeyParameterType (methodParam );
560
583
valueType = GenericCollectionTypeResolver .getMapValueParameterType (methodParam );
@@ -609,11 +632,11 @@ protected Map convertToTypedMap(Map original, String propertyName, Class require
609
632
methodParam .increaseNestingLevel ();
610
633
methodParam .setTypeIndexForCurrentLevel (0 );
611
634
}
612
- Object convertedKey = convertIfNecessary (keyedPropertyName , null , key , keyType , null , methodParam );
635
+ Object convertedKey = convertIfNecessary (keyedPropertyName , null , key , keyType , typeDescriptor );
613
636
if (methodParam != null ) {
614
637
methodParam .setTypeIndexForCurrentLevel (1 );
615
638
}
616
- Object convertedValue = convertIfNecessary (keyedPropertyName , null , value , valueType , null , methodParam );
639
+ Object convertedValue = convertIfNecessary (keyedPropertyName , null , value , valueType , typeDescriptor );
617
640
if (methodParam != null ) {
618
641
methodParam .decreaseNestingLevel ();
619
642
}
0 commit comments