@ -185,18 +185,10 @@ final class BindConverter {
private static class TypeConverterConversionService extends GenericConversionService {
TypeConverterConversionService ( Consumer < PropertyEditorRegistry > initializer ) {
addConverter ( new TypeConverterConverter ( createTypeConverter( initializer) ) ) ;
addConverter ( new TypeConverterConverter ( initializer) ) ;
ApplicationConversionService . addDelimitedStringConverters ( this ) ;
}
private SimpleTypeConverter createTypeConverter ( Consumer < PropertyEditorRegistry > initializer ) {
SimpleTypeConverter typeConverter = new SimpleTypeConverter ( ) ;
if ( initializer ! = null ) {
initializer . accept ( typeConverter ) ;
}
return typeConverter ;
}
@Override
public boolean canConvert ( TypeDescriptor sourceType , TypeDescriptor targetType ) {
// Prefer conversion service to handle things like String to char[].
@ -213,10 +205,15 @@ final class BindConverter {
* /
private static class TypeConverterConverter implements ConditionalGenericConverter {
private final SimpleTypeConverter typeConverter ;
private final Consumer < PropertyEditorRegistry > initializer ;
// SimpleTypeConverter is not thread-safe to use for conversion but we can use it
// in a thread-safe way to check if conversion is possible.
private final SimpleTypeConverter matchesOnlyTypeConverter ;
TypeConverterConverter ( SimpleTypeConverter typeConverter ) {
this . typeConverter = typeConverter ;
TypeConverterConverter ( Consumer < PropertyEditorRegistry > initializer ) {
this . initializer = initializer ;
this . matchesOnlyTypeConverter = createTypeConverter ( ) ;
}
@Override
@ -226,32 +223,32 @@ final class BindConverter {
@Override
public boolean matches ( TypeDescriptor sourceType , TypeDescriptor targetType ) {
return getPropertyEditor ( targetType . getType ( ) ) ! = null ;
}
@Override
public Object convert ( Object source , TypeDescriptor sourceType , TypeDescriptor targetType ) {
SimpleTypeConverter typeConverter = this . typeConverter ;
return typeConverter . convertIfNecessary ( source , targetType . getType ( ) ) ;
}
private PropertyEditor getPropertyEditor ( Class < ? > type ) {
Class < ? > type = targetType . getType ( ) ;
if ( type = = null | | type = = Object . class | | Collection . class . isAssignableFrom ( type )
| | Map . class . isAssignableFrom ( type ) ) {
return null ;
return false ;
}
SimpleTypeConverter typeConverter = this . typeConverter ;
PropertyEditor editor = typeConverter . getDefaultEditor ( type ) ;
PropertyEditor editor = this . matchesOnlyTypeConverter . getDefaultEditor ( type ) ;
if ( editor = = null ) {
editor = t ypeConverter. findCustomEditor ( type , null ) ;
editor = this . matchesOnlyTypeConverter . findCustomEditor ( type , null ) ;
}
if ( editor = = null & & String . class ! = type ) {
editor = BeanUtils . findEditorByConvention ( type ) ;
}
if ( editor = = null | | EXCLUDED_EDITORS . contains ( editor . getClass ( ) ) ) {
return null ;
return ( editor ! = null & & ! EXCLUDED_EDITORS . contains ( editor . getClass ( ) ) ) ;
}
return editor ;
@Override
public Object convert ( Object source , TypeDescriptor sourceType , TypeDescriptor targetType ) {
return createTypeConverter ( ) . convertIfNecessary ( source , targetType . getType ( ) ) ;
}
private SimpleTypeConverter createTypeConverter ( ) {
SimpleTypeConverter typeConverter = new SimpleTypeConverter ( ) ;
if ( this . initializer ! = null ) {
this . initializer . accept ( typeConverter ) ;
}
return typeConverter ;
}
}