This commit is contained in:
Keith Donald
2009-03-31 17:50:26 +00:00
parent 199c9bb9c5
commit ce8718ebf2
6 changed files with 183 additions and 54 deletions

View File

@@ -19,6 +19,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Map;
import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.core.MethodParameter;
@@ -135,6 +136,13 @@ public class TypeDescriptor {
return Collection.class.isAssignableFrom(getType());
}
/**
* Is this type a {@link Map} type?
*/
public boolean isMap() {
return Map.class.isAssignableFrom(getType());
}
/**
* If this type is an array type or {@link Collection} type, returns the underlying element type.
* Returns null if the type is neither an array or collection.

View File

@@ -16,7 +16,6 @@
package org.springframework.core.convert.service;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.Collection;
import org.springframework.core.convert.ConversionExecutor;
@@ -47,8 +46,7 @@ class ArrayToCollection extends AbstractCollectionConverter {
@SuppressWarnings("unchecked")
protected Object doExecute(Object sourceArray) throws Exception {
Class implClass = CollectionConversionUtils.getImpl(getTargetType().getType());
Constructor constructor = implClass.getConstructor((Class[]) null);
Collection collection = (Collection) constructor.newInstance((Object[]) null);
Collection collection = (Collection) implClass.newInstance();
int length = Array.getLength(sourceArray);
ConversionExecutor converter = getElementConverter();
for (int i = 0; i < length; i++) {

View File

@@ -40,8 +40,7 @@ class CollectionToCollection extends AbstractCollectionConverter {
Collection sourceCollection = (Collection) source;
Class targetCollectionType = getTargetType().getType();
Class implClass = CollectionConversionUtils.getImpl(targetCollectionType);
Collection targetCollection = (Collection) implClass.getConstructor((Class[]) null)
.newInstance((Object[]) null);
Collection targetCollection = (Collection) implClass.newInstance();
ConversionExecutor elementConverter = getElementConverter();
Class elementType;
if (elementConverter == null) {

View File

@@ -178,7 +178,6 @@ public class GenericConversionService implements ConversionService {
throws ConversionExecutorNotFoundException {
Assert.notNull(sourceClass, "The sourceType to convert from is required");
Assert.notNull(targetType, "The targetType to convert to is required");
// special handling for arrays since they are not indexable classes
TypeDescriptor sourceType = TypeDescriptor.valueOf(sourceClass);
if (sourceType.isArray()) {
if (targetType.isArray()) {
@@ -206,6 +205,13 @@ public class GenericConversionService implements ConversionService {
throw new UnsupportedOperationException("Object to Collection conversion not yet supported");
}
}
if (sourceType.isMap()) {
if (targetType.isMap()) {
return new MapToMap(sourceType, targetType, this);
} else {
throw new UnsupportedOperationException("Object to Map conversion not yet supported");
}
}
Converter converter = findRegisteredConverter(sourceType, targetType);
if (converter != null) {
return new StaticConversionExecutor(sourceType, targetType, converter);

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2004-2008 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 java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.springframework.core.convert.ConversionExecutionException;
import org.springframework.core.convert.ConversionExecutor;
import org.springframework.core.convert.TypeDescriptor;
class MapToMap implements ConversionExecutor {
private TypeDescriptor sourceType;
private TypeDescriptor targetType;
private GenericConversionService conversionService;
public MapToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
this.sourceType = sourceType;
this.targetType = targetType;
this.conversionService = conversionService;
}
@SuppressWarnings("unchecked")
public Object execute(Object source) throws ConversionExecutionException {
try {
Map map = (Map) source;
Map targetMap = (Map) getImpl(targetType.getType()).newInstance();
Iterator<Map.Entry<?, ?>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = it.next();
Object key = entry.getKey();
Object value = entry.getValue();
key = conversionService.executeConversion(key, TypeDescriptor.valueOf(targetType.getMapKeyType()));
value = conversionService.executeConversion(value, TypeDescriptor.valueOf(targetType.getMapValueType()));
targetMap.put(key, value);
}
return targetMap;
} catch (Exception e) {
throw new ConversionExecutionException(source, sourceType, targetType, e);
}
}
static Class<?> getImpl(Class<?> targetClass) {
if (targetClass.isInterface()) {
if (Map.class.equals(targetClass)) {
return HashMap.class;
} else if (SortedMap.class.equals(targetClass)) {
return TreeMap.class;
} else {
throw new IllegalArgumentException("Unsupported Map interface [" + targetClass.getName() + "]");
}
} else {
return targetClass;
}
}
}