|
|
|
@ -16,6 +16,8 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.core.convert.support; |
|
|
|
package org.springframework.core.convert.support; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter; |
|
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Array; |
|
|
|
import java.lang.reflect.Array; |
|
|
|
import java.lang.reflect.ParameterizedType; |
|
|
|
import java.lang.reflect.ParameterizedType; |
|
|
|
import java.lang.reflect.Type; |
|
|
|
import java.lang.reflect.Type; |
|
|
|
@ -30,7 +32,6 @@ import java.util.Map; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.GenericTypeResolver; |
|
|
|
import org.springframework.core.GenericTypeResolver; |
|
|
|
import org.springframework.core.convert.ConversionFailedException; |
|
|
|
|
|
|
|
import org.springframework.core.convert.ConversionService; |
|
|
|
import org.springframework.core.convert.ConversionService; |
|
|
|
import org.springframework.core.convert.ConverterNotFoundException; |
|
|
|
import org.springframework.core.convert.ConverterNotFoundException; |
|
|
|
import org.springframework.core.convert.TypeDescriptor; |
|
|
|
import org.springframework.core.convert.TypeDescriptor; |
|
|
|
@ -58,7 +59,6 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<Class, Map<Class, GenericConverter>> sourceTypeConverters = new HashMap<Class, Map<Class, GenericConverter>>(); |
|
|
|
private final Map<Class, Map<Class, GenericConverter>> sourceTypeConverters = new HashMap<Class, Map<Class, GenericConverter>>(); |
|
|
|
|
|
|
|
|
|
|
|
private ConversionService parent; |
|
|
|
private ConversionService parent; |
|
|
|
@ -69,12 +69,10 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public GenericConversionService() { |
|
|
|
public GenericConversionService() { |
|
|
|
initGenericConverters(); |
|
|
|
initGenericConverters(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Registers the converters in the set provided. |
|
|
|
* Registers the converters in the set provided. |
|
|
|
* JavaBean-friendly alternative to calling {@link #addConverter(Converter)}. |
|
|
|
* JavaBean-friendly alternative to calling {@link #addConverter(Converter)}. |
|
|
|
@ -111,7 +109,6 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
return this.parent; |
|
|
|
return this.parent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// implementing ConverterRegistry
|
|
|
|
// implementing ConverterRegistry
|
|
|
|
|
|
|
|
|
|
|
|
public void addConverter(Converter converter) { |
|
|
|
public void addConverter(Converter converter) { |
|
|
|
@ -140,7 +137,6 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
getSourceMap(sourceType).remove(targetType); |
|
|
|
getSourceMap(sourceType).remove(targetType); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// implementing ConversionService
|
|
|
|
// implementing ConversionService
|
|
|
|
|
|
|
|
|
|
|
|
public boolean canConvert(Class<?> sourceType, Class<?> targetType) { |
|
|
|
public boolean canConvert(Class<?> sourceType, Class<?> targetType) { |
|
|
|
@ -177,15 +173,7 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
if (converter == null) { |
|
|
|
if (converter == null) { |
|
|
|
throw new ConverterNotFoundException(sourceType, targetType); |
|
|
|
throw new ConverterNotFoundException(sourceType, targetType); |
|
|
|
} |
|
|
|
} |
|
|
|
try { |
|
|
|
return invokeConverter(converter, source, sourceType, targetType); |
|
|
|
return converter.convert(source, sourceType, targetType); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (ConversionFailedException ex) { |
|
|
|
|
|
|
|
throw ex; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
throw new ConversionFailedException(sourceType, targetType, source, ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// subclassing hooks
|
|
|
|
// subclassing hooks
|
|
|
|
@ -203,6 +191,7 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
addGenericConverter(Map.class, Map.class, new MapToMapGenericConverter(this)); |
|
|
|
addGenericConverter(Map.class, Map.class, new MapToMapGenericConverter(this)); |
|
|
|
addGenericConverter(Object.class, Object[].class, new ObjectToArrayGenericConverter(this)); |
|
|
|
addGenericConverter(Object.class, Object[].class, new ObjectToArrayGenericConverter(this)); |
|
|
|
addGenericConverter(Object.class, Collection.class, new ObjectToCollectionGenericConverter(this)); |
|
|
|
addGenericConverter(Object.class, Collection.class, new ObjectToCollectionGenericConverter(this)); |
|
|
|
|
|
|
|
addGenericConverter(String.class, Object[].class, new StringToArrayGenericConverter(this)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -242,21 +231,17 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
GenericConverter converter = findConverterByClassPair(sourceType.getObjectType(), targetType.getObjectType()); |
|
|
|
GenericConverter converter = findConverterByClassPair(sourceType.getObjectType(), targetType.getObjectType()); |
|
|
|
if (converter != null) { |
|
|
|
if (converter != null) { |
|
|
|
return converter; |
|
|
|
return converter; |
|
|
|
} |
|
|
|
} else if (this.parent != null && this.parent.canConvert(sourceType, targetType)) { |
|
|
|
else if (this.parent != null && this.parent.canConvert(sourceType, targetType)) { |
|
|
|
|
|
|
|
return this.parentConverterAdapter; |
|
|
|
return this.parentConverterAdapter; |
|
|
|
} |
|
|
|
} else { |
|
|
|
else { |
|
|
|
|
|
|
|
if (sourceType.isAssignableTo(targetType)) { |
|
|
|
if (sourceType.isAssignableTo(targetType)) { |
|
|
|
return NO_OP_CONVERTER; |
|
|
|
return NO_OP_CONVERTER; |
|
|
|
} |
|
|
|
} else { |
|
|
|
else { |
|
|
|
|
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// internal helpers
|
|
|
|
// internal helpers
|
|
|
|
|
|
|
|
|
|
|
|
private List<Class> getRequiredTypeInfo(Object converter) { |
|
|
|
private List<Class> getRequiredTypeInfo(Object converter) { |
|
|
|
@ -298,12 +283,10 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
if (typeInfo.size() == 2) { |
|
|
|
if (typeInfo.size() == 2) { |
|
|
|
return typeInfo; |
|
|
|
return typeInfo; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (Converter.class.isAssignableFrom((Class) rawType)) { |
|
|
|
else if (Converter.class.isAssignableFrom((Class) rawType)) { |
|
|
|
|
|
|
|
return getConverterTypeInfo((Class) rawType); |
|
|
|
return getConverterTypeInfo((Class) rawType); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (Converter.class.isAssignableFrom((Class) ifc)) { |
|
|
|
else if (Converter.class.isAssignableFrom((Class) ifc)) { |
|
|
|
|
|
|
|
return getConverterTypeInfo((Class) ifc); |
|
|
|
return getConverterTypeInfo((Class) ifc); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -330,8 +313,7 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
Map<Class, GenericConverter> objectConverters = getConvertersForSource(Object.class); |
|
|
|
Map<Class, GenericConverter> objectConverters = getConvertersForSource(Object.class); |
|
|
|
return getConverter(objectConverters, targetType); |
|
|
|
return getConverter(objectConverters, targetType); |
|
|
|
} |
|
|
|
} else { |
|
|
|
else { |
|
|
|
|
|
|
|
LinkedList<Class> classQueue = new LinkedList<Class>(); |
|
|
|
LinkedList<Class> classQueue = new LinkedList<Class>(); |
|
|
|
classQueue.addFirst(sourceType); |
|
|
|
classQueue.addFirst(sourceType); |
|
|
|
while (!classQueue.isEmpty()) { |
|
|
|
while (!classQueue.isEmpty()) { |
|
|
|
@ -393,8 +375,7 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return converters.get(Object.class); |
|
|
|
return converters.get(Object.class); |
|
|
|
} |
|
|
|
} else { |
|
|
|
else { |
|
|
|
|
|
|
|
LinkedList<Class> classQueue = new LinkedList<Class>(); |
|
|
|
LinkedList<Class> classQueue = new LinkedList<Class>(); |
|
|
|
classQueue.addFirst(targetType); |
|
|
|
classQueue.addFirst(targetType); |
|
|
|
while (!classQueue.isEmpty()) { |
|
|
|
while (!classQueue.isEmpty()) { |
|
|
|
@ -408,8 +389,7 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
if (componentType.getSuperclass() != null) { |
|
|
|
if (componentType.getSuperclass() != null) { |
|
|
|
classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass()); |
|
|
|
classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
else { |
|
|
|
|
|
|
|
if (currentClass.getSuperclass() != null) { |
|
|
|
if (currentClass.getSuperclass() != null) { |
|
|
|
classQueue.addFirst(currentClass.getSuperclass()); |
|
|
|
classQueue.addFirst(currentClass.getSuperclass()); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -423,7 +403,6 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ConverterAdapter implements GenericConverter { |
|
|
|
private static class ConverterAdapter implements GenericConverter { |
|
|
|
|
|
|
|
|
|
|
|
private Converter converter; |
|
|
|
private Converter converter; |
|
|
|
@ -438,7 +417,6 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ConverterFactoryAdapter implements GenericConverter { |
|
|
|
private static class ConverterFactoryAdapter implements GenericConverter { |
|
|
|
|
|
|
|
|
|
|
|
private ConverterFactory converterFactory; |
|
|
|
private ConverterFactory converterFactory; |
|
|
|
|