提交 a1a7c320 编写于 作者: K Keith Donald

string to collection and array converters now are conditional and apply target element type match

上级 38041acc
......@@ -27,7 +27,12 @@ public interface ConversionService {
/**
* Returns true if objects of sourceType can be converted to targetType.
* @param sourceType the source type to convert from (required)
* If this method returns true, it means {@link #convert(Object, Class)} is capable of converting an instance of sourceType to targetType.
* Special note on collections, arrays, and maps types:
* For conversion between collection, array, and map types, this method will return 'true'
* even though a convert invocation may still generate a {@link ConversionException} if the underlying elements are not convertible.
* Callers are expected to handle this exceptional case when working with collections and maps.
* @param sourceType the source type to convert from (may be null if source is null)
* @param targetType the target type to convert to (required)
* @return true if a conversion can be performed, false if not
* @throws IllegalArgumentException if targetType is null
......@@ -36,12 +41,16 @@ public interface ConversionService {
/**
* Returns true if objects of sourceType can be converted to the targetType.
* The TypeDescriptors provide additional context about the source and target locations where conversion would occur, often object property locations.
* @param sourceType context about the source type to convert from (required)
* The TypeDescriptors provide additional context about the source and target locations where conversion would occur, often object fields or property locations.
* If this method returns true, it means {@link #convert(Object, TypeDescriptor, TypeDescriptor)} is capable of converting an instance of sourceType to targetType.
* Special note on collections, arrays, and maps types:
* For conversion between collection, array, and map types, this method will return 'true'
* even though a convert invocation may still generate a {@link ConversionException} if the underlying elements are not convertible.
* Callers are expected to handle this exceptional case when working with collections and maps.
* @param sourceType context about the source type to convert from (may be null if source is null)
* @param targetType context about the target type to convert to (required)
* @return true if a conversion can be performed between the source and target types, false if not
* @throws IllegalArgumentException if targetType is null
* @see TypeDescriptor#forObject(Object)
*/
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
......@@ -57,7 +66,7 @@ public interface ConversionService {
/**
* Convert the source to targetType.
* The TypeDescriptors provide additional context about the source and target locations where conversion will occur, often object property locations.
* The TypeDescriptors provide additional context about the source and target locations where conversion will occur, often object fields or property locations.
* @param source the source object to convert (may be null)
* @param sourceType context about the source type converting from (may be null if source is null)
* @param targetType context about the target type to convert to (required)
......@@ -65,7 +74,6 @@ public interface ConversionService {
* @throws ConversionException if a conversion exception occurred
* @throws IllegalArgumentException if targetType is null
* @throws IllegalArgumentException if sourceType is null but source is not null
* @see TypeDescriptor#forObject(Object)
*/
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
......
......@@ -22,16 +22,17 @@ import java.util.Set;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.util.StringUtils;
/**
* Converts a comma-delimited String to an Array.
*
* Only matches if String.class can be converted to the target array element type.
*
* @author Keith Donald
* @since 3.0
*/
final class StringToArrayConverter implements GenericConverter {
final class StringToArrayConverter implements ConditionalGenericConverter {
private final ConversionService conversionService;
......@@ -43,6 +44,10 @@ final class StringToArrayConverter implements GenericConverter {
return Collections.singleton(new ConvertiblePair(String.class, Object[].class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType, targetType.getElementType());
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return null;
......
......@@ -28,6 +28,7 @@ import org.springframework.util.StringUtils;
/**
* Converts a comma-delimited String to a Collection.
* If the target collection element type is declared, only matches if String.class can be converted to it.
*
* @author Keith Donald
* @since 3.0
......@@ -45,10 +46,11 @@ final class StringToCollectionConverter implements ConditionalGenericConverter {
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
if (targetType.getElementType() == null) {
if (targetType.getElementType() != null) {
return this.conversionService.canConvert(sourceType, targetType.getElementType());
} else {
return true;
}
return this.conversionService.canConvert(sourceType, targetType.getElementType());
}
@SuppressWarnings("unchecked")
......
......@@ -759,4 +759,5 @@ public class DefaultConversionTests {
return new TestEntity(id);
}
}
}
......@@ -16,16 +16,17 @@
package org.springframework.core.convert.support;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
......@@ -528,4 +529,25 @@ public class GenericConversionServiceTests {
public static Map<String, ?> wildcardMap;
@Test
public void stringToArrayCanConvert() {
conversionService.addConverter(new StringToArrayConverter(conversionService));
assertFalse(conversionService.canConvert(String.class, Integer[].class));
conversionService.addConverterFactory(new StringToNumberConverterFactory());
assertTrue(conversionService.canConvert(String.class, Integer[].class));
}
@Test
public void stringToCollectionCanConvert() throws Exception {
conversionService.addConverter(new StringToCollectionConverter(conversionService));
assertTrue(conversionService.canConvert(String.class, Collection.class));
TypeDescriptor targetType = new TypeDescriptor(getClass().getField("stringToCollection"));
assertFalse(conversionService.canConvert(TypeDescriptor.valueOf(String.class), targetType));
conversionService.addConverterFactory(new StringToNumberConverterFactory());
assertTrue(conversionService.canConvert(TypeDescriptor.valueOf(String.class), targetType));
}
public Collection<Integer> stringToCollection;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册