custom conversion list binding support

This commit is contained in:
Keith Donald
2009-02-13 15:49:17 +00:00
parent b3ff31a04a
commit 16ab312c45
4 changed files with 164 additions and 22 deletions

View File

@@ -95,8 +95,13 @@ public class ArrayToCollection implements TwoWayConverter {
for (Iterator it = collection.iterator(); it.hasNext(); i++) {
Object value = it.next();
if (value != null) {
ConversionExecutor converter = conversionService.getConversionExecutor(value.getClass(), sourceClass
.getComponentType());
ConversionExecutor converter;
if (elementConverter != null) {
converter = elementConverter;
} else {
converter = conversionService.getConversionExecutor(value.getClass(), sourceClass
.getComponentType());
}
value = converter.execute(value);
}
Array.set(array, i, value);

View File

@@ -30,10 +30,16 @@ public class ObjectToArray implements Converter {
private ConversionService conversionService;
private ConversionExecutor elementConverter;
public ObjectToArray(ConversionService conversionService) {
this.conversionService = conversionService;
}
public ObjectToArray(ConversionExecutor elementConverter) {
this.elementConverter = elementConverter;
}
public Class getSourceClass() {
return Object.class;
}
@@ -48,7 +54,12 @@ public class ObjectToArray implements Converter {
}
Class componentType = targetClass.getComponentType();
Object array = Array.newInstance(componentType, 1);
ConversionExecutor converter = conversionService.getConversionExecutor(source.getClass(), componentType);
ConversionExecutor converter;
if (elementConverter != null) {
converter = elementConverter;
} else {
converter = conversionService.getConversionExecutor(source.getClass(), componentType);
}
Array.set(array, 0, converter.execute(source));
return array;
}

View File

@@ -191,8 +191,11 @@ public class GenericConversionService implements ConversionService {
if (converter.getSourceClass().isAssignableFrom(sourceComponentType)) {
if (!converter.getTargetClass().isAssignableFrom(targetComponentType)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to an array of type [" + targetComponentType + "]");
"Custom ConversionExecutor with id '" + id
+ "' cannot convert from array storing elements of type ["
+ sourceComponentType.getName()
+ "]; to an array of storing elements of type ["
+ targetComponentType.getName() + "]");
}
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, converter);
@@ -206,42 +209,82 @@ public class GenericConversionService implements ConversionService {
} else {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to an array of type [" + targetComponentType + "]");
+ sourceComponentType.getName() + "]; to an array of type ["
+ targetComponentType.getName() + "]");
}
} else if (Collection.class.isAssignableFrom(targetClass)) {
// type erasure has prevented us from getting the concrete type, this is best we can do for now
Class targetComponentType = converter.getTargetClass();
if (!targetClass.isInterface() && Modifier.isAbstract(targetClass.getModifiers())) {
throw new IllegalArgumentException("Conversion target class [" + targetClass.getName()
+ "] is invalid; cannot convert to abstract collection types--"
+ "request an interface or concrete implementation instead");
}
if (converter.getSourceClass().isAssignableFrom(sourceComponentType)) {
if (!converter.getTargetClass().isAssignableFrom(targetComponentType)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to collection of type [" + targetComponentType
+ "]");
}
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, converter);
// type erasure has prevented us from getting the concrete type, this is best we can do for now
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType, converter
.getTargetClass(), converter);
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToCollection(
elementConverter));
} else if (converter.getTargetClass().isAssignableFrom(sourceComponentType)
&& converter instanceof TwoWayConverter) {
TwoWayConverter twoWay = (TwoWayConverter) converter;
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, new ReverseConverter(twoWay));
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType, converter
.getSourceClass(), new ReverseConverter(twoWay));
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToCollection(
elementConverter));
} else {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to collection of type [" + targetComponentType + "]");
"Custom ConversionExecutor with id '" + id
+ "' cannot convert from array storing elements type ["
+ sourceComponentType.getName() + "]; to collection");
}
}
}
if (targetClass.isArray()) {
Class targetComponentType = targetClass.getComponentType();
if (Collection.class.isAssignableFrom(sourceClass)) {
// type erasure limits us here as well
throw new UnsupportedOperationException("Not yet implemented");
if (converter.getTargetClass().isAssignableFrom(targetComponentType)) {
ConversionExecutor elementConverter = new StaticConversionExecutor(converter.getSourceClass(),
targetComponentType, converter);
Converter collectionToArray = new ReverseConverter(new ArrayToCollection(elementConverter));
return new StaticConversionExecutor(sourceClass, targetClass, collectionToArray);
} else if (converter.getSourceClass().isAssignableFrom(targetComponentType)
&& converter instanceof TwoWayConverter) {
TwoWayConverter twoWay = (TwoWayConverter) converter;
ConversionExecutor elementConverter = new StaticConversionExecutor(converter.getTargetClass(),
targetComponentType, new ReverseConverter(twoWay));
Converter collectionToArray = new ReverseConverter(new ArrayToCollection(elementConverter));
return new StaticConversionExecutor(sourceClass, targetClass, collectionToArray);
} else {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id
+ "' cannot convert from collection to to an array holding elements of type ["
+ targetComponentType.getName() + "]");
}
} else {
throw new UnsupportedOperationException("Not yet implemented");
if (converter.getSourceClass().isAssignableFrom(sourceClass)) {
if (!converter.getTargetClass().isAssignableFrom(targetComponentType)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from sourceClass ["
+ sourceClass.getName() + "] to array holding elements of type ["
+ targetComponentType.getName() + "]");
}
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceClass,
targetComponentType, converter);
return new StaticConversionExecutor(sourceClass, targetClass, new ObjectToArray(elementConverter));
} else if (converter.getTargetClass().isAssignableFrom(sourceClass)
&& converter instanceof TwoWayConverter) {
if (!converter.getSourceClass().isAssignableFrom(targetComponentType)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from sourceClass ["
+ sourceClass.getName() + "] to array holding elements of type ["
+ targetComponentType.getName() + "]");
}
TwoWayConverter twoWay = (TwoWayConverter) converter;
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceClass,
targetComponentType, new ReverseConverter(twoWay));
return new StaticConversionExecutor(sourceClass, targetClass, new ObjectToArray(elementConverter));
}
}
}
if (converter.getSourceClass().isAssignableFrom(sourceClass)) {

View File

@@ -197,6 +197,89 @@ public class DefaultConversionServiceTests extends TestCase {
assertEquals("princy2", p[1]);
}
public void testRegisterCustomConverterArrayToList() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter("princy", new CustomTwoWayConverter());
ConversionExecutor executor = service.getConversionExecutor("princy", String[].class, List.class);
List list = (List) executor.execute(new String[] { "princy1", "princy2" });
assertEquals("princy1", ((Principal) list.get(0)).getName());
assertEquals("princy2", ((Principal) list.get(1)).getName());
}
public void testRegisterCustomConverterArrayToListReverse() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter("princy", new CustomTwoWayConverter());
ConversionExecutor executor = service.getConversionExecutor("princy", Principal[].class, List.class);
final Principal princy1 = new Principal() {
public String getName() {
return "princy1";
}
};
final Principal princy2 = new Principal() {
public String getName() {
return "princy2";
}
};
List p = (List) executor.execute(new Principal[] { princy1, princy2 });
assertEquals("princy1", p.get(0));
assertEquals("princy2", p.get(1));
}
public void testRegisterCustomConverterListToArray() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter("princy", new CustomTwoWayConverter());
ConversionExecutor executor = service.getConversionExecutor("princy", List.class, Principal[].class);
List princyList = new ArrayList();
princyList.add("princy1");
princyList.add("princy2");
Principal[] p = (Principal[]) executor.execute(princyList);
assertEquals("princy1", p[0].getName());
assertEquals("princy2", p[1].getName());
}
public void testRegisterCustomConverterListToArrayReverse() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter("princy", new CustomTwoWayConverter());
ConversionExecutor executor = service.getConversionExecutor("princy", List.class, String[].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);
String[] p = (String[]) executor.execute(princyList);
assertEquals("princy1", p[0]);
assertEquals("princy2", p[1]);
}
public void testRegisterCustomConverterObjectToArray() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter("princy", new CustomTwoWayConverter());
ConversionExecutor executor = service.getConversionExecutor("princy", String.class, Principal[].class);
Principal[] p = (Principal[]) executor.execute("princy1");
assertEquals("princy1", p[0].getName());
}
public void testRegisterCustomConverterObjectToArrayReverse() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter("princy", new CustomTwoWayConverter());
ConversionExecutor executor = service.getConversionExecutor("princy", Principal.class, String[].class);
final Principal princy1 = new Principal() {
public String getName() {
return "princy1";
}
};
String[] p = (String[]) executor.execute(princy1);
assertEquals("princy1", p[0]);
}
public void testConversionPrimitive() {
DefaultConversionService service = new DefaultConversionService();
ConversionExecutor executor = service.getConversionExecutor(String.class, int.class);