custom conversion list, array binding
This commit is contained in:
@@ -18,10 +18,16 @@ public class CollectionToCollection implements Converter {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
private ConversionExecutor elementConverter;
|
||||
|
||||
public CollectionToCollection(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public CollectionToCollection(ConversionExecutor elementConverter) {
|
||||
this.elementConverter = elementConverter;
|
||||
}
|
||||
|
||||
public Class getSourceClass() {
|
||||
return Collection.class;
|
||||
}
|
||||
@@ -66,14 +72,18 @@ public class CollectionToCollection implements Converter {
|
||||
}
|
||||
|
||||
private ConversionExecutor getElementConverter(Object source, Class targetClass) {
|
||||
if (JdkVersion.isAtLeastJava15()) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass);
|
||||
if (elementType != null) {
|
||||
Class componentType = source.getClass().getComponentType();
|
||||
return conversionService.getConversionExecutor(componentType, elementType);
|
||||
if (elementConverter != null) {
|
||||
return elementConverter;
|
||||
} else {
|
||||
if (JdkVersion.isAtLeastJava15()) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass);
|
||||
if (elementType != null) {
|
||||
Class componentType = source.getClass().getComponentType();
|
||||
return conversionService.getConversionExecutor(componentType, elementType);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,11 +26,13 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.binding.convert.ConversionException;
|
||||
import org.springframework.binding.convert.ConversionExecutionException;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionExecutorNotFoundException;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.converters.ArrayToArray;
|
||||
import org.springframework.binding.convert.converters.ArrayToCollection;
|
||||
import org.springframework.binding.convert.converters.CollectionToCollection;
|
||||
import org.springframework.binding.convert.converters.Converter;
|
||||
import org.springframework.binding.convert.converters.ObjectToArray;
|
||||
import org.springframework.binding.convert.converters.ReverseConverter;
|
||||
@@ -287,6 +289,18 @@ public class GenericConversionService implements ConversionService {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Collection.class.isAssignableFrom(sourceClass) && Collection.class.isAssignableFrom(targetClass)) {
|
||||
ConversionExecutor elementConverter;
|
||||
// type erasure forces us to do runtime checks of list elements
|
||||
if (converter instanceof TwoWayConverter) {
|
||||
elementConverter = new TwoWayCapableConversionExecutor(converter.getSourceClass(), converter
|
||||
.getTargetClass(), (TwoWayConverter) converter);
|
||||
} else {
|
||||
elementConverter = new StaticConversionExecutor(converter.getSourceClass(), converter.getTargetClass(),
|
||||
converter);
|
||||
}
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, new CollectionToCollection(elementConverter));
|
||||
}
|
||||
if (converter.getSourceClass().isAssignableFrom(sourceClass)) {
|
||||
if (!converter.getTargetClass().isAssignableFrom(targetClass)) {
|
||||
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
|
||||
@@ -488,4 +502,46 @@ public class GenericConversionService implements ConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
private static class TwoWayCapableConversionExecutor implements ConversionExecutor {
|
||||
|
||||
private Class sourceClass;
|
||||
|
||||
private Class targetClass;
|
||||
|
||||
private TwoWayConverter converter;
|
||||
|
||||
public TwoWayCapableConversionExecutor(Class sourceClass, Class targetClass, TwoWayConverter converter) {
|
||||
this.sourceClass = sourceClass;
|
||||
this.targetClass = targetClass;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
public Class getSourceClass() {
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
return targetClass;
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionExecutionException {
|
||||
if (source == null || getSourceClass().isInstance(source)) {
|
||||
try {
|
||||
return converter.convertSourceToTargetClass(source, targetClass);
|
||||
} catch (Exception e) {
|
||||
throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), e);
|
||||
}
|
||||
} else if (getTargetClass().isInstance(source)) {
|
||||
try {
|
||||
return converter.convertTargetToSourceClass(source, sourceClass);
|
||||
} catch (Exception e) {
|
||||
throw new ConversionExecutionException(source, getTargetClass(), getSourceClass(), e);
|
||||
}
|
||||
} else {
|
||||
throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), "Source object "
|
||||
+ source + " to convert is expected to be an instance of [" + getSourceClass().getName()
|
||||
+ "] or [" + getTargetClass().getName() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class StaticConversionExecutor implements ConversionExecutor {
|
||||
public Object execute(Object source) throws ConversionExecutionException {
|
||||
if (source != null && !sourceClass.isInstance(source)) {
|
||||
throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), "Source object "
|
||||
+ source + " to convert is expected to be an instance of " + getSourceClass());
|
||||
+ source + " to convert is expected to be an instance of [" + getSourceClass().getName() + "]");
|
||||
}
|
||||
try {
|
||||
return converter.convertSourceToTargetClass(source, targetClass);
|
||||
|
||||
@@ -280,6 +280,40 @@ public class DefaultConversionServiceTests extends TestCase {
|
||||
assertEquals("princy1", p[0]);
|
||||
}
|
||||
|
||||
public void testRegisterCustomConverterListToList() {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
service.addConverter("princy", new CustomTwoWayConverter());
|
||||
ConversionExecutor executor = service.getConversionExecutor("princy", List.class, List.class);
|
||||
List princyList = new ArrayList();
|
||||
princyList.add("princy1");
|
||||
princyList.add("princy2");
|
||||
List list = (List) executor.execute(princyList);
|
||||
assertEquals("princy1", ((Principal) list.get(0)).getName());
|
||||
assertEquals("princy2", ((Principal) list.get(1)).getName());
|
||||
}
|
||||
|
||||
public void testRegisterCustomConverterListToListReverse() {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
service.addConverter("princy", new CustomTwoWayConverter());
|
||||
ConversionExecutor executor = service.getConversionExecutor("princy", List.class, List.class);
|
||||
final Principal princy1 = new Principal() {
|
||||
public String getName() {
|
||||
return "princy1";
|
||||
}
|
||||
};
|
||||
final Principal princy2 = new Principal() {
|
||||
public String getName() {
|
||||
return "princy2";
|
||||
}
|
||||
};
|
||||
List princyList = new ArrayList();
|
||||
princyList.add(princy1);
|
||||
princyList.add(princy2);
|
||||
List list = (List) executor.execute(princyList);
|
||||
assertEquals("princy1", list.get(0));
|
||||
assertEquals("princy2", list.get(1));
|
||||
}
|
||||
|
||||
public void testConversionPrimitive() {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ConversionExecutor executor = service.getConversionExecutor(String.class, int.class);
|
||||
|
||||
Reference in New Issue
Block a user