documented hooks
This commit is contained in:
parent
a6e28f4eb5
commit
01e900c33a
|
|
@ -17,6 +17,7 @@ package org.springframework.core.convert.support;
|
|||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class ArrayToArrayGenericConverter implements GenericConverter {
|
||||
|
|
@ -35,6 +36,9 @@ class ArrayToArrayGenericConverter implements GenericConverter {
|
|||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
||||
Object target = Array.newInstance(targetElementType.getType(), Array.getLength(source));
|
||||
GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
for (int i = 0; i < Array.getLength(target); i++) {
|
||||
Array.set(target, i, converter.convert(Array.get(source, i), sourceElementType, targetElementType));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import java.lang.reflect.Array;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class ArrayToCollectionGenericConverter implements GenericConverter {
|
||||
|
|
@ -40,6 +41,9 @@ class ArrayToCollectionGenericConverter implements GenericConverter {
|
|||
}
|
||||
} else {
|
||||
GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
collection.add(converter.convert(Array.get(source, i), sourceElementType, targetElementType));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package org.springframework.core.convert.support;
|
|||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class ArrayToObjectGenericConverter implements GenericConverter {
|
||||
|
|
@ -37,6 +38,9 @@ class ArrayToObjectGenericConverter implements GenericConverter {
|
|||
return Array.get(source, 0);
|
||||
} else {
|
||||
GenericConverter converter = conversionService.getConverter(sourceElementType, targetType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
return converter.convert(Array.get(source, 0), sourceElementType, targetType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import java.lang.reflect.Array;
|
|||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class CollectionToArrayGenericConverter implements GenericConverter {
|
||||
|
|
@ -44,6 +45,9 @@ class CollectionToArrayGenericConverter implements GenericConverter {
|
|||
}
|
||||
} else {
|
||||
GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
for (Iterator it = sourceCollection.iterator(); it.hasNext(); i++) {
|
||||
Array.set(array, i, converter.convert(it.next(), sourceElementType, targetElementType));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.core.convert.support;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class CollectionToCollectionGenericConverter implements GenericConverter {
|
||||
|
|
@ -46,6 +47,9 @@ class CollectionToCollectionGenericConverter implements GenericConverter {
|
|||
}
|
||||
Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
|
||||
GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
for (Object element : sourceCollection) {
|
||||
targetCollection.add(converter.convert(element, sourceElementType, targetElementType));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package org.springframework.core.convert.support;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class CollectionToObjectGenericConverter implements GenericConverter {
|
||||
|
|
@ -37,6 +38,9 @@ class CollectionToObjectGenericConverter implements GenericConverter {
|
|||
return sourceCollection.iterator().next();
|
||||
} else {
|
||||
GenericConverter converter = conversionService.getConverter(sourceElementType, targetType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
return converter.convert(sourceCollection.iterator().next(), sourceElementType, targetType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,9 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
return null;
|
||||
}
|
||||
GenericConverter converter = getConverter(sourceType, targetType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
try {
|
||||
return converter.convert(source, sourceType, targetType);
|
||||
} catch (ConversionFailedException e) {
|
||||
|
|
@ -173,6 +176,9 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
|
||||
// subclassing hooks
|
||||
|
||||
/**
|
||||
* Hook to initialize the "generic" converters that require the full TypeDescriptor context to perform their conversion operations.
|
||||
*/
|
||||
protected void initGenericConverters() {
|
||||
addGenericConverter(Object[].class, Object[].class, new ArrayToArrayGenericConverter(this));
|
||||
addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionGenericConverter(this));
|
||||
|
|
@ -185,14 +191,39 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
addGenericConverter(Object.class, Collection.class, new ObjectToCollectionGenericConverter(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a GenericConverter.
|
||||
* @param sourceType the source type to convert from
|
||||
* @param targetType the target type to convert to
|
||||
* @param converter the generic converter.
|
||||
*/
|
||||
protected void addGenericConverter(Class<?> sourceType, Class<?> targetType, GenericConverter converter) {
|
||||
getSourceMap(sourceType).put(targetType, converter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook method to convert a null value.
|
||||
* Default implementation simply returns <code>null</code>.
|
||||
* Subclasses may override to return a custom null objects for specific target types.
|
||||
* @param sourceType the sourceType
|
||||
* @param targetType the tagetType
|
||||
* @return the null object
|
||||
*/
|
||||
protected Object convertNull(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook method to lookup the converter for a given sourceType/targetType pair.
|
||||
* First queries this ConversionService's converter map.
|
||||
* If no suitable Converter is found, and a {@link #setParent(GenericConversionService) parent} is set, then queries the parent.
|
||||
* If still no suitable Converter is found, returns a NO_OP Converter if the sourceType and targetType are assignable.
|
||||
* Returns <code>null</code> if this ConversionService simply cannot convert between sourceType and targetType.
|
||||
* Subclasses may override.
|
||||
* @param sourceType the source type to convert from
|
||||
* @param targetType the target type to convert to
|
||||
* @return the generic converter that will perform the conversion, or <code>null</code> if no suitable converter was found
|
||||
*/
|
||||
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
GenericConverter converter = findConverterByClassPair(sourceType.getObjectType(), targetType.getObjectType());
|
||||
if (converter != null) {
|
||||
|
|
@ -204,7 +235,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
if (sourceType.isAssignableTo(targetType)) {
|
||||
return NO_OP_CONVERTER;
|
||||
} else {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.springframework.core.convert.support;
|
|||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class MapToMapGenericConverter implements GenericConverter {
|
||||
|
|
@ -95,11 +96,17 @@ class MapToMapGenericConverter implements GenericConverter {
|
|||
GenericConversionService conversionService) {
|
||||
if (sourceKeyType != TypeDescriptor.NULL && targetKeyType != TypeDescriptor.NULL && !keysCompatible) {
|
||||
this.keyConverter = conversionService.getConverter(sourceKeyType, targetKeyType);
|
||||
if (this.keyConverter == null) {
|
||||
throw new ConverterNotFoundException(sourceKeyType, targetKeyType);
|
||||
}
|
||||
this.sourceKeyType = sourceKeyType;
|
||||
this.targetKeyType = targetKeyType;
|
||||
}
|
||||
if (sourceValueType != TypeDescriptor.NULL && targetValueType != TypeDescriptor.NULL && !valuesCompatible) {
|
||||
this.valueConverter = conversionService.getConverter(sourceValueType, targetValueType);
|
||||
if (this.valueConverter == null) {
|
||||
throw new ConverterNotFoundException(sourceValueType, targetValueType);
|
||||
}
|
||||
this.targetKeyType = targetKeyType;
|
||||
this.targetValueType = targetValueType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package org.springframework.core.convert.support;
|
|||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class ObjectToArrayGenericConverter implements GenericConverter {
|
||||
|
|
@ -34,6 +35,9 @@ class ObjectToArrayGenericConverter implements GenericConverter {
|
|||
Array.set(target, 0, source);
|
||||
} else {
|
||||
GenericConverter converter = conversionService.getConverter(sourceType, targetElementType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
Array.set(target, 0, converter.convert(source, sourceType, targetElementType));
|
||||
}
|
||||
return target;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.core.convert.support;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
class ObjectToCollectionGenericConverter implements GenericConverter {
|
||||
|
|
@ -35,6 +36,9 @@ class ObjectToCollectionGenericConverter implements GenericConverter {
|
|||
target.add(source);
|
||||
} else {
|
||||
GenericConverter converter = conversionService.getConverter(sourceType, targetElementType);
|
||||
if (converter == null) {
|
||||
throw new ConverterNotFoundException(sourceType, targetType);
|
||||
}
|
||||
target.add(converter.convert(source, sourceType, targetElementType));
|
||||
}
|
||||
return target;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.springframework.core.convert.support;
|
|||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -265,6 +267,27 @@ public class GenericConversionServiceTests {
|
|||
assertEquals(new Integer(3), result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericConverterDelegatingBackToConversionServiceConverterNotFound() {
|
||||
try {
|
||||
converter.convert("1", Integer[].class);
|
||||
} catch (ConversionFailedException e) {
|
||||
assertTrue(e.getCause() instanceof ConverterNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parent() {
|
||||
GenericConversionService parent = new GenericConversionService();
|
||||
converter.setParent(parent);
|
||||
assertFalse(converter.canConvert(String.class, Integer.class));
|
||||
try {
|
||||
converter.convert("3", Integer.class);
|
||||
} catch (ConverterNotFoundException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static enum FooEnum {
|
||||
BAR, BAZ
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue