Browse Source

conversion service helper tests - part 1

pull/23217/head
Keith Donald 17 years ago
parent
commit
9ce71f67ff
  1. 10
      org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java
  2. 8
      org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java
  3. 41
      org.springframework.core/src/main/java/org/springframework/core/convert/service/AbstractCollectionConverter.java
  4. 3
      org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToArray.java
  5. 10
      org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToCollection.java
  6. 5
      org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionConversionUtils.java
  7. 25
      org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToArray.java
  8. 6
      org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToCollection.java
  9. 4
      org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java
  10. 2
      org.springframework.core/src/main/java/org/springframework/core/convert/service/MapToMap.java
  11. 33
      org.springframework.core/src/main/java/org/springframework/core/convert/service/NoOpConversionExecutor.java
  12. 10
      org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java
  13. 4
      org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java
  14. 19
      org.springframework.core/src/test/java/org/springframework/core/convert/service/ArrayToArrayTests.java
  15. 65
      org.springframework.core/src/test/java/org/springframework/core/convert/service/ArrayToCollectionTests.java
  16. 60
      org.springframework.core/src/test/java/org/springframework/core/convert/service/CollectionToArrayTests.java

10
org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java

@ -32,7 +32,7 @@ public class ConversionExecutionException extends ConversionException { @@ -32,7 +32,7 @@ public class ConversionExecutionException extends ConversionException {
/**
* The source type we tried to convert the value from.
*/
private TypeDescriptor sourceType;
private Class<?> sourceType;
/**
* The target type we tried to convert the value to.
@ -46,7 +46,7 @@ public class ConversionExecutionException extends ConversionException { @@ -46,7 +46,7 @@ public class ConversionExecutionException extends ConversionException {
* @param targetType the value's target type
* @param cause the cause of the conversion failure
*/
public ConversionExecutionException(Object value, TypeDescriptor sourceType, TypeDescriptor targetType, Throwable cause) {
public ConversionExecutionException(Object value, Class<?> sourceType, TypeDescriptor targetType, Throwable cause) {
super(defaultMessage(value, sourceType, targetType, cause), cause);
this.value = value;
this.sourceType = sourceType;
@ -60,7 +60,7 @@ public class ConversionExecutionException extends ConversionException { @@ -60,7 +60,7 @@ public class ConversionExecutionException extends ConversionException {
* @param targetType the value's target type
* @param message a descriptive message of what went wrong.
*/
public ConversionExecutionException(Object value, TypeDescriptor sourceType, TypeDescriptor targetType, String message) {
public ConversionExecutionException(Object value, Class<?> sourceType, TypeDescriptor targetType, String message) {
super(message);
this.value = value;
this.sourceType = sourceType;
@ -77,7 +77,7 @@ public class ConversionExecutionException extends ConversionException { @@ -77,7 +77,7 @@ public class ConversionExecutionException extends ConversionException {
/**
* Returns the source type we tried to convert the value from.
*/
public TypeDescriptor getSourceType() {
public Class<?> getSourceType() {
return sourceType;
}
@ -88,7 +88,7 @@ public class ConversionExecutionException extends ConversionException { @@ -88,7 +88,7 @@ public class ConversionExecutionException extends ConversionException {
return targetType;
}
private static String defaultMessage(Object value, TypeDescriptor sourceType, TypeDescriptor targetType, Throwable cause) {
private static String defaultMessage(Object value, Class<?> sourceType, TypeDescriptor targetType, Throwable cause) {
return "Unable to convert value " + StylerUtils.style(value) + " from type [" + sourceType.getName()
+ "] to type [" + targetType.getName() + "]; reason = '" + cause.getMessage() + "'";
}

8
org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java

@ -25,6 +25,14 @@ package org.springframework.core.convert; @@ -25,6 +25,14 @@ package org.springframework.core.convert;
*/
public interface ConversionService {
/**
* Returns true if objects of sourceType can be converted to targetType.
* @param source the source to convert from (may be null)
* @param targetType the target type to convert to
* @return true if a conversion can be performed, false if not
*/
public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType);
/**
* Returns true if the source can be converted to targetType.
* @param source the source to convert from (may be null)

41
org.springframework.core/src/main/java/org/springframework/core/convert/service/AbstractCollectionConverter.java

@ -17,40 +17,41 @@ package org.springframework.core.convert.service; @@ -17,40 +17,41 @@ package org.springframework.core.convert.service;
import org.springframework.core.convert.ConversionExecutionException;
import org.springframework.core.convert.ConversionExecutor;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
abstract class AbstractCollectionConverter implements ConversionExecutor {
private ConversionService conversionService;
private ConversionExecutor elementConverter;
private TypeDescriptor sourceCollectionType;
private TypeDescriptor targetCollectionType;
private GenericConversionService conversionService;
private ConversionExecutor elementConverter;
public AbstractCollectionConverter(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType, GenericConversionService conversionService) {
public AbstractCollectionConverter(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType, ConversionService conversionService) {
this.conversionService = conversionService;
this.sourceCollectionType = sourceCollectionType;
this.targetCollectionType = targetCollectionType;
this.conversionService = conversionService;
this.elementConverter = createElementConverter();
Class<?> sourceElementType = sourceCollectionType.getElementType();
Class<?> targetElementType = targetCollectionType.getElementType();
if (sourceElementType != null && targetElementType != null) {
elementConverter = conversionService.getConversionExecutor(sourceElementType, TypeDescriptor.valueOf(targetElementType));
} else {
elementConverter = NoOpConversionExecutor.INSTANCE;
}
}
private ConversionExecutor createElementConverter() {
Class<?> sourceElementType = getSourceType().getElementType();
Class<?> targetElementType = getTargetType().getElementType();
return (sourceElementType != null && targetElementType != null) ? conversionService.getElementConverter(sourceElementType, targetElementType) : null;
protected Class<?> getTargetCollectionType() {
return targetCollectionType.getType();
}
protected TypeDescriptor getSourceType() {
return sourceCollectionType;
}
protected TypeDescriptor getTargetType() {
return targetCollectionType;
protected Class<?> getTargetElementType() {
return targetCollectionType.getElementType();
}
protected GenericConversionService getConversionService() {
protected ConversionService getConversionService() {
return conversionService;
}
@ -62,7 +63,7 @@ abstract class AbstractCollectionConverter implements ConversionExecutor { @@ -62,7 +63,7 @@ abstract class AbstractCollectionConverter implements ConversionExecutor {
try {
return doExecute(source);
} catch (Exception e) {
throw new ConversionExecutionException(source, sourceCollectionType, targetCollectionType, e);
throw new ConversionExecutionException(source, sourceCollectionType.getType(), targetCollectionType, e);
}
}

3
org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToArray.java

@ -33,9 +33,10 @@ class ArrayToArray extends AbstractCollectionConverter { @@ -33,9 +33,10 @@ class ArrayToArray extends AbstractCollectionConverter {
super(sourceArrayType, targetArrayType, conversionService);
}
@Override
public Object doExecute(Object sourceArray) throws Exception {
int length = Array.getLength(sourceArray);
Object targetArray = Array.newInstance(getTargetType().getElementType(), length);
Object targetArray = Array.newInstance(getTargetElementType(), length);
for (int i = 0; i < length; i++) {
Object value = Array.get(sourceArray, i);
Array.set(targetArray, i, getElementConverter().execute(value));

10
org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToCollection.java

@ -45,16 +45,12 @@ class ArrayToCollection extends AbstractCollectionConverter { @@ -45,16 +45,12 @@ class ArrayToCollection extends AbstractCollectionConverter {
@Override
@SuppressWarnings("unchecked")
protected Object doExecute(Object sourceArray) throws Exception {
Class implClass = CollectionConversionUtils.getImpl(getTargetType().getType());
Class implClass = CollectionConversionUtils.getImpl(getTargetCollectionType());
Collection collection = (Collection) implClass.newInstance();
int length = Array.getLength(sourceArray);
ConversionExecutor converter = getElementConverter();
ConversionExecutor elementConverter = getElementConverter();
for (int i = 0; i < length; i++) {
Object value = Array.get(sourceArray, i);
if (converter != null) {
value = converter.execute(value);
}
collection.add(value);
collection.add(elementConverter.execute(Array.get(sourceArray, i)));
}
return collection;
}

5
org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionConversionUtils.java

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.core.convert.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@ -24,7 +25,7 @@ import java.util.TreeSet; @@ -24,7 +25,7 @@ import java.util.TreeSet;
class CollectionConversionUtils {
static Class<?> getImpl(Class<?> targetClass) {
public static Class<?> getImpl(Class<?> targetClass) {
if (targetClass.isInterface()) {
if (List.class.equals(targetClass)) {
return ArrayList.class;
@ -32,6 +33,8 @@ class CollectionConversionUtils { @@ -32,6 +33,8 @@ class CollectionConversionUtils {
return LinkedHashSet.class;
} else if (SortedSet.class.equals(targetClass)) {
return TreeSet.class;
} else if (Collection.class.equals(targetClass)) {
return ArrayList.class;
} else {
throw new IllegalArgumentException("Unsupported collection interface [" + targetClass.getName() + "]");
}

25
org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToArray.java

@ -46,19 +46,30 @@ class CollectionToArray extends AbstractCollectionConverter { @@ -46,19 +46,30 @@ class CollectionToArray extends AbstractCollectionConverter {
@Override
protected Object doExecute(Object source) throws Exception {
Collection<?> collection = (Collection<?>) source;
Class<?> targetComponentType = getTargetType().getElementType();
Object array = Array.newInstance(targetComponentType, collection.size());
Object array = Array.newInstance(getTargetElementType(), collection.size());
int i = 0;
ConversionExecutor converter = getElementConverter();
ConversionExecutor elementConverter = getElementConverter(collection);
for (Iterator<?> it = collection.iterator(); it.hasNext(); i++) {
Object value = it.next();
if (converter == null) {
converter = getConversionService().getElementConverter(value.getClass(), targetComponentType);
}
value = converter.execute(value);
value = elementConverter.execute(value);
Array.set(array, i, value);
}
return array;
}
private ConversionExecutor getElementConverter(Collection<?> target) {
ConversionExecutor elementConverter = getElementConverter();
if (elementConverter == NoOpConversionExecutor.INSTANCE && !target.isEmpty()) {
Iterator<?> it = target.iterator();
while (it.hasNext()) {
Object value = it.next();
if (value != null) {
elementConverter = getConversionService().getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
break;
}
}
}
return elementConverter;
}
}

6
org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToCollection.java

@ -37,13 +37,13 @@ class CollectionToCollection extends AbstractCollectionConverter { @@ -37,13 +37,13 @@ class CollectionToCollection extends AbstractCollectionConverter {
@SuppressWarnings("unchecked")
protected Object doExecute(Object source) throws Exception {
Collection sourceCollection = (Collection) source;
Class targetCollectionType = getTargetType().getType();
Class targetCollectionType = getTargetCollectionType();
Class implClass = CollectionConversionUtils.getImpl(targetCollectionType);
Collection targetCollection = (Collection) implClass.newInstance();
ConversionExecutor elementConverter = getElementConverter();
Class elementType;
if (elementConverter == null) {
elementType = getTargetType().getElementType();
elementType = getTargetElementType();
} else {
elementType = null;
}
@ -51,7 +51,7 @@ class CollectionToCollection extends AbstractCollectionConverter { @@ -51,7 +51,7 @@ class CollectionToCollection extends AbstractCollectionConverter {
while (it.hasNext()) {
Object value = it.next();
if (elementConverter == null && elementType != null) {
elementConverter = getConversionService().getElementConverter(value.getClass(), elementType);
elementConverter = getConversionService().getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(elementType));
}
value = elementConverter.execute(value);
targetCollection.add(value);

4
org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java

@ -158,6 +158,10 @@ public class GenericConversionService implements ConversionService { @@ -158,6 +158,10 @@ public class GenericConversionService implements ConversionService {
// implementing ConversionService
public boolean canConvert(Class<?> source, TypeDescriptor targetType) {
return false;
}
public boolean canConvert(Object source, TypeDescriptor targetType) {
return false;
}

2
org.springframework.core/src/main/java/org/springframework/core/convert/service/MapToMap.java

@ -56,7 +56,7 @@ class MapToMap implements ConversionExecutor { @@ -56,7 +56,7 @@ class MapToMap implements ConversionExecutor {
}
return targetMap;
} catch (Exception e) {
throw new ConversionExecutionException(source, sourceType, targetType, e);
throw new ConversionExecutionException(source, sourceType.getType(), targetType, e);
}
}

33
org.springframework.core/src/main/java/org/springframework/core/convert/service/NoOpConversionExecutor.java

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
/*
* Copyright 2004-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.service;
import org.springframework.core.convert.ConversionExecutionException;
import org.springframework.core.convert.ConversionExecutor;
class NoOpConversionExecutor implements ConversionExecutor {
public static final ConversionExecutor INSTANCE = new NoOpConversionExecutor();
private NoOpConversionExecutor() {
}
public Object execute(Object source) throws ConversionExecutionException {
return source;
}
}

10
org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java

@ -30,9 +30,9 @@ class StaticConversionExecutor implements ConversionExecutor { @@ -30,9 +30,9 @@ class StaticConversionExecutor implements ConversionExecutor {
private final Converter converter;
public StaticConversionExecutor(TypeDescriptor sourceClass, TypeDescriptor targetClass, Converter converter) {
this.sourceType = sourceClass;
this.targetType = targetClass;
public StaticConversionExecutor(TypeDescriptor sourceType, TypeDescriptor targetType, Converter converter) {
this.sourceType = sourceType;
this.targetType = targetType;
this.converter = converter;
}
@ -41,13 +41,13 @@ class StaticConversionExecutor implements ConversionExecutor { @@ -41,13 +41,13 @@ class StaticConversionExecutor implements ConversionExecutor {
return null;
}
if (sourceType != null && !sourceType.isInstance(source)) {
throw new ConversionExecutionException(source, sourceType, targetType, "Source object "
throw new ConversionExecutionException(source, sourceType.getType(), targetType, "Source object "
+ source + " to convert is expected to be an instance of [" + sourceType.getName() + "]");
}
try {
return converter.convert(source);
} catch (Exception e) {
throw new ConversionExecutionException(source, sourceType, targetType, e);
throw new ConversionExecutionException(source, sourceType.getType(), targetType, e);
}
}

4
org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java

@ -41,13 +41,13 @@ class StaticSuperConversionExecutor implements ConversionExecutor { @@ -41,13 +41,13 @@ class StaticSuperConversionExecutor implements ConversionExecutor {
return null;
}
if (!sourceType.isInstance(source)) {
throw new ConversionExecutionException(source, sourceType, targetType, "Source object "
throw new ConversionExecutionException(source, sourceType.getType(), targetType, "Source object "
+ source + " to convert is expected to be an instance of [" + sourceType.getName() + "]");
}
try {
return converter.convert(source, targetType.getType());
} catch (Exception e) {
throw new ConversionExecutionException(source, sourceType, targetType, e);
throw new ConversionExecutionException(source, sourceType.getType(), targetType, e);
}
}

19
org.springframework.core/src/test/java/org/springframework/core/convert/service/ArrayToArrayTests.java

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
package org.springframework.core.convert.service;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
public class ArrayToArrayTests {
@Test
public void testArrayToArrayConversion() {
DefaultConversionService service = new DefaultConversionService();
ArrayToArray c = new ArrayToArray(TypeDescriptor.valueOf(String[].class), TypeDescriptor.valueOf(Integer[].class), service);
Integer[] result = (Integer[]) c.execute(new String[] { "1", "2", "3" });
assertEquals(new Integer(1), result[0]);
assertEquals(new Integer(2), result[1]);
assertEquals(new Integer(3), result[2]);
}
}

65
org.springframework.core/src/test/java/org/springframework/core/convert/service/ArrayToCollectionTests.java

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
package org.springframework.core.convert.service;
import static org.junit.Assert.assertEquals;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
public class ArrayToCollectionTests {
@Test
public void testArrayToCollectionConversion() throws Exception {
DefaultConversionService service = new DefaultConversionService();
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("bindTarget")), service);
List result = (List) c.execute(new String[] { "1", "2", "3" });
assertEquals(new Integer(1), result.get(0));
assertEquals(new Integer(2), result.get(1));
assertEquals(new Integer(3), result.get(2));
}
@Test
public void testArrayToSetConversion() throws Exception {
DefaultConversionService service = new DefaultConversionService();
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("setTarget")), service);
Set result = (Set) c.execute(new String[] { "1" });
assertEquals("1", result.iterator().next());
}
@Test
public void testArrayToSortedSetConversion() throws Exception {
DefaultConversionService service = new DefaultConversionService();
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("sortedSetTarget")), service);
SortedSet result = (SortedSet) c.execute(new String[] { "1" });
assertEquals(new Integer(1), result.iterator().next());
}
@Test
public void testArrayToCollectionImplConversion() throws Exception {
DefaultConversionService service = new DefaultConversionService();
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("implTarget")), service);
LinkedList result = (LinkedList) c.execute(new String[] { "1" });
assertEquals("1", result.iterator().next());
}
@Test
public void testArrayToNonGenericCollectionConversionNullElement() throws Exception {
DefaultConversionService service = new DefaultConversionService();
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("listTarget")), service);
List result = (List) c.execute(new Integer[] { null, new Integer(1) });
assertEquals(null, result.get(0));
assertEquals(new Integer(1), result.get(1));
}
public Collection<Integer> bindTarget;
public List listTarget;
public Set setTarget;
public SortedSet<Integer> sortedSetTarget;
public LinkedList<String> implTarget;
}

60
org.springframework.core/src/test/java/org/springframework/core/convert/service/CollectionToArrayTests.java

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
package org.springframework.core.convert.service;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
public class CollectionToArrayTests {
@Test
public void testCollectionToArrayConversion() throws Exception {
DefaultConversionService service = new DefaultConversionService();
CollectionToArray c = new CollectionToArray(new TypeDescriptor(getClass().getField("bindTarget")),
TypeDescriptor.valueOf(Integer[].class), service);
bindTarget.add("1");
bindTarget.add("2");
bindTarget.add("3");
Integer[] result = (Integer[]) c.execute(bindTarget);
assertEquals(new Integer(1), result[0]);
assertEquals(new Integer(2), result[1]);
assertEquals(new Integer(3), result[2]);
}
@Test
public void testCollectionToArrayConversionNoGenericInfo() throws Exception {
DefaultConversionService service = new DefaultConversionService();
CollectionToArray c = new CollectionToArray(TypeDescriptor.valueOf(Collection.class), TypeDescriptor
.valueOf(Integer[].class), service);
bindTarget.add("1");
bindTarget.add("2");
bindTarget.add("3");
Integer[] result = (Integer[]) c.execute(bindTarget);
assertEquals(new Integer(1), result[0]);
assertEquals(new Integer(2), result[1]);
assertEquals(new Integer(3), result[2]);
}
@Test
public void testCollectionToArrayConversionNoGenericInfoNullElement() throws Exception {
DefaultConversionService service = new DefaultConversionService();
CollectionToArray c = new CollectionToArray(TypeDescriptor.valueOf(Collection.class), TypeDescriptor
.valueOf(Integer[].class), service);
bindTarget.add(null);
bindTarget.add("1");
bindTarget.add("2");
bindTarget.add("3");
Integer[] result = (Integer[]) c.execute(bindTarget);
assertEquals(null, result[0]);
assertEquals(new Integer(1), result[1]);
assertEquals(new Integer(2), result[2]);
assertEquals(new Integer(3), result[3]);
}
public Collection<String> bindTarget = new ArrayList<String>();
}
Loading…
Cancel
Save