Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2658 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
29 changed files with 208 additions and 776 deletions
@ -1,55 +0,0 @@
@@ -1,55 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* Converts an Array to a Map. |
||||
* First adapts the source Array to a List, then delegates to {@link CollectionToMapConverter} to perform the target Map conversion. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
final class ArrayToMapConverter implements ConditionalGenericConverter { |
||||
|
||||
private final CollectionToMapConverter helperConverter; |
||||
|
||||
public ArrayToMapConverter(GenericConversionService conversionService) { |
||||
this.helperConverter = new CollectionToMapConverter(conversionService); |
||||
} |
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return Collections.singleton(new ConvertiblePair(Object[].class, Map.class)); |
||||
} |
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.helperConverter.matches(sourceType, targetType); |
||||
} |
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.helperConverter.convert(Arrays.asList(ObjectUtils.toObjectArray(source)), sourceType, targetType); |
||||
} |
||||
|
||||
} |
||||
@ -1,125 +0,0 @@
@@ -1,125 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import static org.springframework.core.convert.support.ConversionUtils.getElementType; |
||||
|
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.CollectionFactory; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
|
||||
/** |
||||
* Converts a Collection to a Map. |
||||
* First, creates a new Map of the requested targetType with a size equal to the size of the source Collection. |
||||
* Then copies each element in the source collection to the target map. |
||||
* During the copy process, if an element is a String, that String is treated as a "key=value" pair, parsed, and a corresponding entry is created in the target map. |
||||
* If an element is another Object type, an entry is created in the targetMap with this Object as both the key and value. |
||||
* Will perform an element conversion from the source collection's parameterized type to the target map's parameterized K,V types if necessary. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
final class CollectionToMapConverter implements ConditionalGenericConverter { |
||||
|
||||
private final GenericConversionService conversionService; |
||||
|
||||
public CollectionToMapConverter(GenericConversionService conversionService) { |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return Collections.singleton(new ConvertiblePair(Collection.class, Map.class)); |
||||
} |
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getMapKeyTypeDescriptor()) && |
||||
this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getMapValueTypeDescriptor()); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (source == null) { |
||||
return this.conversionService.convertNullSource(sourceType, targetType); |
||||
} |
||||
Collection<?> sourceCollection = (Collection<?>) source; |
||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); |
||||
if (sourceElementType == TypeDescriptor.NULL) { |
||||
sourceElementType = getElementType(sourceCollection); |
||||
} |
||||
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor(); |
||||
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor(); |
||||
boolean keysCompatible = false; |
||||
if (sourceElementType != TypeDescriptor.NULL && sourceElementType.isAssignableTo(targetKeyType)) { |
||||
keysCompatible = true; |
||||
} |
||||
boolean valuesCompatible = false; |
||||
if (sourceElementType != TypeDescriptor.NULL && sourceElementType.isAssignableTo(targetValueType)) { |
||||
valuesCompatible = true; |
||||
} |
||||
if (keysCompatible && valuesCompatible) { |
||||
Map target = CollectionFactory.createMap(targetType.getType(), sourceCollection.size()); |
||||
if (String.class.equals(sourceElementType.getType())) { |
||||
for (Object element : sourceCollection) { |
||||
String[] property = parseProperty((String) element); |
||||
target.put(property[0], property[1]); |
||||
} |
||||
} |
||||
else { |
||||
for (Object element : sourceCollection) { |
||||
target.put(element, element); |
||||
} |
||||
} |
||||
return target; |
||||
} |
||||
else { |
||||
Map target = CollectionFactory.createMap(targetType.getType(), sourceCollection.size()); |
||||
MapEntryConverter converter = new MapEntryConverter(sourceElementType, sourceElementType, targetKeyType, |
||||
targetValueType, keysCompatible, valuesCompatible, this.conversionService); |
||||
if (String.class.equals(sourceElementType.getType())) { |
||||
for (Object element : sourceCollection) { |
||||
String[] property = parseProperty((String) element); |
||||
Object targetKey = converter.convertKey(property[0]); |
||||
Object targetValue = converter.convertValue(property[1]); |
||||
target.put(targetKey, targetValue); |
||||
} |
||||
} |
||||
else { |
||||
for (Object element : sourceCollection) { |
||||
Object targetKey = converter.convertKey(element); |
||||
Object targetValue = converter.convertValue(element); |
||||
target.put(targetKey, targetValue); |
||||
} |
||||
} |
||||
return target; |
||||
} |
||||
} |
||||
|
||||
private String[] parseProperty(String string) { |
||||
String[] property = string.split("="); |
||||
if (property.length < 2) { |
||||
throw new IllegalArgumentException("Invalid String property '" + string + |
||||
"'; properties should be in the format name=value"); |
||||
} |
||||
return property; |
||||
} |
||||
|
||||
} |
||||
@ -1,60 +0,0 @@
@@ -1,60 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
|
||||
/** |
||||
* Converts a Map to an Array. |
||||
* First converts the source Map to a Collection, then converts that Collection to an Array. |
||||
* Delegates to {@link MapToCollectionConverter} and {@link CollectionToArrayConverter} helpers to do this. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
final class MapToArrayConverter implements ConditionalGenericConverter { |
||||
|
||||
private final MapToCollectionConverter mapToCollectionHelperConverter; |
||||
|
||||
private final CollectionToArrayConverter collectionToArrayHelperConverter; |
||||
|
||||
public MapToArrayConverter(GenericConversionService conversionService) { |
||||
this.mapToCollectionHelperConverter = new MapToCollectionConverter(conversionService); |
||||
this.collectionToArrayHelperConverter = new CollectionToArrayConverter(conversionService); |
||||
} |
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return Collections.singleton(new ConvertiblePair(Map.class, Object[].class)); |
||||
} |
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.mapToCollectionHelperConverter.matches(sourceType, targetType); |
||||
} |
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
TypeDescriptor collectionType = TypeDescriptor.collection(List.class, targetType.getElementTypeDescriptor()); |
||||
Object collection = this.mapToCollectionHelperConverter.convert(source, sourceType, collectionType); |
||||
return this.collectionToArrayHelperConverter.convert(collection, collectionType, targetType); |
||||
} |
||||
|
||||
} |
||||
@ -1,102 +0,0 @@
@@ -1,102 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import static org.springframework.core.convert.support.ConversionUtils.getMapEntryTypes; |
||||
|
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.CollectionFactory; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
|
||||
/** |
||||
* Converts a Map to a Collection. |
||||
* First, creates a new Collection of the requested targetType with a size equal to the size of the source Map. |
||||
* Then copies each element in the source map to the target collection. |
||||
* During the copy process, if the target collection's parameterized type is a String, each Map entry is first encoded as a "key=value" property String, then added to the Collection. |
||||
* If the collection type is another Object type, the value of each Map entry is added to the Collection. |
||||
* Will perform a conversion from the source maps's parameterized K,V types to the target collection's parameterized type if necessary. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
final class MapToCollectionConverter implements ConditionalGenericConverter { |
||||
|
||||
private final GenericConversionService conversionService; |
||||
|
||||
public MapToCollectionConverter(GenericConversionService conversionService) { |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return Collections.singleton(new ConvertiblePair(Map.class, Collection.class)); |
||||
} |
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (String.class.equals(targetType.getType())) { |
||||
return this.conversionService.canConvert(sourceType.getMapKeyTypeDescriptor(), targetType.getElementTypeDescriptor()) && |
||||
this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType.getElementTypeDescriptor()); |
||||
} else { |
||||
return this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType.getElementTypeDescriptor()); |
||||
} |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (source == null) { |
||||
return this.conversionService.convertNullSource(sourceType, targetType); |
||||
} |
||||
Map<?, ?> sourceMap = (Map<?, ?>) source; |
||||
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor(); |
||||
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor(); |
||||
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) { |
||||
TypeDescriptor[] sourceEntryTypes = getMapEntryTypes(sourceMap); |
||||
sourceKeyType = sourceEntryTypes[0]; |
||||
sourceValueType = sourceEntryTypes[1]; |
||||
} |
||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); |
||||
boolean keysCompatible = false; |
||||
if (sourceKeyType != TypeDescriptor.NULL && sourceKeyType.isAssignableTo(targetElementType)) { |
||||
keysCompatible = true; |
||||
} |
||||
boolean valuesCompatible = false; |
||||
if (sourceValueType != TypeDescriptor.NULL || sourceValueType.isAssignableTo(targetElementType)) { |
||||
valuesCompatible = true; |
||||
} |
||||
Collection target = CollectionFactory.createCollection(targetType.getType(), sourceMap.size()); |
||||
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetElementType, |
||||
targetElementType, keysCompatible, valuesCompatible, this.conversionService); |
||||
if (String.class.equals(targetElementType.getType())) { |
||||
for (Object entry : sourceMap.entrySet()) { |
||||
Map.Entry<?, ?> mapEntry = (Map.Entry<?, ?>) entry; |
||||
String property = converter.convertKey(mapEntry.getKey()) + "=" |
||||
+ converter.convertValue(mapEntry.getValue()); |
||||
target.add(property); |
||||
} |
||||
} else { |
||||
for (Object value : sourceMap.values()) { |
||||
target.add(converter.convertValue(value)); |
||||
} |
||||
} |
||||
return target; |
||||
} |
||||
|
||||
} |
||||
@ -1,71 +0,0 @@
@@ -1,71 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
|
||||
/** |
||||
* Converts a Map to an Object by returning the first Map entry value after converting it to the desired targetType. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
final class MapToObjectConverter implements ConditionalGenericConverter { |
||||
|
||||
private final GenericConversionService conversionService; |
||||
|
||||
public MapToObjectConverter(GenericConversionService conversionService) { |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return Collections.singleton(new ConvertiblePair(Map.class, Object.class)); |
||||
} |
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType); |
||||
} |
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (source == null) { |
||||
return this.conversionService.convertNullSource(sourceType, targetType); |
||||
} |
||||
Map<?, ?> sourceMap = (Map<?, ?>) source; |
||||
if (sourceMap.size() == 0) { |
||||
return null; |
||||
} else { |
||||
Object firstValue = sourceMap.values().iterator().next(); |
||||
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor(); |
||||
if (sourceValueType == TypeDescriptor.NULL) { |
||||
sourceValueType = TypeDescriptor.forObject(firstValue); |
||||
} |
||||
boolean valuesCompatible = false; |
||||
if (sourceValueType != TypeDescriptor.NULL && sourceValueType.isAssignableTo(targetType)) { |
||||
valuesCompatible = true; |
||||
} |
||||
MapEntryConverter converter = new MapEntryConverter(sourceValueType, sourceValueType, targetType, |
||||
targetType, true, valuesCompatible, this.conversionService); |
||||
return converter.convertValue(firstValue); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,76 +0,0 @@
@@ -1,76 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-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.support; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.CollectionFactory; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
|
||||
/** |
||||
* Converts an Object to a single-entry Map containing the Object. |
||||
* The Object is put as both the entry key and value. |
||||
* Will convert the Object to the target Map's parameterized types K,V if necessary. |
||||
* |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
final class ObjectToMapConverter implements ConditionalGenericConverter { |
||||
|
||||
private final GenericConversionService conversionService; |
||||
|
||||
public ObjectToMapConverter(GenericConversionService conversionService) { |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return Collections.singleton(new ConvertiblePair(Object.class, Map.class)); |
||||
} |
||||
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
return this.conversionService.canConvert(sourceType, targetType.getMapKeyTypeDescriptor()) |
||||
&& this.conversionService.canConvert(sourceType, targetType.getMapValueTypeDescriptor()); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (source == null) { |
||||
return this.conversionService.convertNullSource(sourceType, targetType); |
||||
} |
||||
Map target = CollectionFactory.createMap(targetType.getType(), 1); |
||||
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor(); |
||||
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor(); |
||||
boolean keysCompatible = false; |
||||
if (sourceType != TypeDescriptor.NULL && sourceType.isAssignableTo(targetKeyType)) { |
||||
keysCompatible = true; |
||||
} |
||||
boolean valuesCompatible = false; |
||||
if (sourceType != TypeDescriptor.NULL && sourceType.isAssignableTo(targetValueType)) { |
||||
valuesCompatible = true; |
||||
} |
||||
MapEntryConverter converter = new MapEntryConverter(sourceType, sourceType, targetKeyType, targetValueType, |
||||
keysCompatible, valuesCompatible, this.conversionService); |
||||
Object key = converter.convertKey(source); |
||||
Object value = converter.convertValue(source); |
||||
target.put(key, value); |
||||
return target; |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue