|
|
|
@ -58,14 +58,23 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
private GenericConversionService parent; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 GenericConverter parentConverterAdapter = new GenericConverter() { |
|
|
|
|
|
|
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
|
|
|
|
|
|
|
return parent.convert(source, sourceType, targetType); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)}. |
|
|
|
@ -91,17 +100,18 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set the parent of this conversion service. This is optional. |
|
|
|
* Set the parent of this conversion service. This is optional. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setParent(GenericConversionService parent) { |
|
|
|
public void setParent(ConversionService parent) { |
|
|
|
this.parent = parent; |
|
|
|
this.parent = parent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns the parent of this conversion service. Could be null. |
|
|
|
* Returns the parent of this conversion service. Could be null. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public GenericConversionService getParent() { |
|
|
|
public ConversionService getParent() { |
|
|
|
return this.parent; |
|
|
|
return this.parent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// implementing ConverterRegistry
|
|
|
|
// implementing ConverterRegistry
|
|
|
|
|
|
|
|
|
|
|
|
public void addConverter(Converter converter) { |
|
|
|
public void addConverter(Converter converter) { |
|
|
|
@ -130,12 +140,14 @@ 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) { |
|
|
|
return canConvert(TypeDescriptor.valueOf(sourceType), TypeDescriptor.valueOf(targetType)); |
|
|
|
return canConvert(TypeDescriptor.valueOf(sourceType), TypeDescriptor.valueOf(targetType)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public <T> T convert(Object source, Class<T> targetType) { |
|
|
|
public <T> T convert(Object source, Class<T> targetType) { |
|
|
|
Assert.notNull(targetType, "The targetType to convert to is required"); |
|
|
|
Assert.notNull(targetType, "The targetType to convert to is required"); |
|
|
|
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType)); |
|
|
|
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType)); |
|
|
|
@ -167,10 +179,12 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
try { |
|
|
|
try { |
|
|
|
return converter.convert(source, sourceType, targetType); |
|
|
|
return converter.convert(source, sourceType, targetType); |
|
|
|
} catch (ConversionFailedException e) { |
|
|
|
} |
|
|
|
throw e; |
|
|
|
catch (ConversionFailedException ex) { |
|
|
|
} catch (Exception e) { |
|
|
|
throw ex; |
|
|
|
throw new ConversionFailedException(sourceType, targetType, source, e); |
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
throw new ConversionFailedException(sourceType, targetType, source, ex); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -229,17 +243,20 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
if (converter != null) { |
|
|
|
if (converter != null) { |
|
|
|
return converter; |
|
|
|
return converter; |
|
|
|
} |
|
|
|
} |
|
|
|
if (this.parent != null) { |
|
|
|
else if (this.parent != null && this.parent.canConvert(sourceType, targetType)) { |
|
|
|
return this.parent.getConverter(sourceType, targetType); |
|
|
|
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) { |
|
|
|
@ -281,10 +298,12 @@ 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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -311,7 +330,8 @@ 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()) { |
|
|
|
@ -373,7 +393,8 @@ 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()) { |
|
|
|
@ -387,7 +408,8 @@ 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()); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -401,6 +423,7 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ConverterAdapter implements GenericConverter { |
|
|
|
private static class ConverterAdapter implements GenericConverter { |
|
|
|
|
|
|
|
|
|
|
|
private Converter converter; |
|
|
|
private Converter converter; |
|
|
|
@ -409,12 +432,13 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
this.converter = converter; |
|
|
|
this.converter = converter; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
|
|
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
|
|
|
return this.converter.convert(source); |
|
|
|
return this.converter.convert(source); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ConverterFactoryAdapter implements GenericConverter { |
|
|
|
private static class ConverterFactoryAdapter implements GenericConverter { |
|
|
|
|
|
|
|
|
|
|
|
private ConverterFactory converterFactory; |
|
|
|
private ConverterFactory converterFactory; |
|
|
|
@ -423,10 +447,10 @@ public class GenericConversionService implements ConversionService, ConverterReg |
|
|
|
this.converterFactory = converterFactory; |
|
|
|
this.converterFactory = converterFactory; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
|
|
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
|
|
|
return this.converterFactory.getConverter(targetType.getObjectType()).convert(source); |
|
|
|
return this.converterFactory.getConverter(targetType.getObjectType()).convert(source); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|