ArrayToCollectionConverter.java 3.3 KB
Newer Older
K
Keith Donald 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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.
 */
16

K
Keith Donald 已提交
17 18
package org.springframework.core.convert.support;

19 20
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;

K
Keith Donald 已提交
21 22
import java.lang.reflect.Array;
import java.util.Collection;
23 24
import java.util.Collections;
import java.util.Set;
K
Keith Donald 已提交
25 26

import org.springframework.core.CollectionFactory;
K
Keith Donald 已提交
27
import org.springframework.core.convert.ConverterNotFoundException;
K
Keith Donald 已提交
28
import org.springframework.core.convert.TypeDescriptor;
29
import org.springframework.core.convert.converter.ConditionalGenericConverter;
30
import org.springframework.core.convert.converter.GenericConverter;
K
Keith Donald 已提交
31

32
/**
K
javadoc  
Keith Donald 已提交
33 34 35 36 37
 * Converts an Array to a Collection.
 * First, creates a new Collection of the requested targetType.
 * Then adds each array element to the target collection.
 * Will perform an element conversion from the source component type to the collection's parameterized type if necessary.
 * 
38 39 40
 * @author Keith Donald
 * @since 3.0
 */
41
final class ArrayToCollectionConverter implements ConditionalGenericConverter {
K
Keith Donald 已提交
42

K
Keith Donald 已提交
43
	private final GenericConversionService conversionService;
K
Keith Donald 已提交
44

45
	public ArrayToCollectionConverter(GenericConversionService conversionService) {
K
Keith Donald 已提交
46 47
		this.conversionService = conversionService;
	}
48

49 50
	public Set<ConvertiblePair> getConvertibleTypes() {
		return Collections.singleton(new ConvertiblePair(Object[].class, Collection.class));
51 52
	}

53 54 55 56
	public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
		return this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor());
	}

K
polish  
Keith Donald 已提交
57
	@SuppressWarnings("unchecked")
K
Keith Donald 已提交
58
	public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
59 60 61
		if (source == null) {
			return this.conversionService.convertNullSource(sourceType, targetType);
		}		
K
Keith Donald 已提交
62 63 64 65 66 67 68 69
		int length = Array.getLength(source);
		Collection collection = CollectionFactory.createCollection(targetType.getType(), length);
		TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
		TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
		if (targetElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) {
			for (int i = 0; i < length; i++) {
				collection.add(Array.get(source, i));
			}
70 71
		}
		else {
K
Keith Donald 已提交
72
			GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetElementType);
K
Keith Donald 已提交
73
			if (converter == null) {
K
Keith Donald 已提交
74
				throw new ConverterNotFoundException(sourceElementType, targetElementType);
75
			}
K
Keith Donald 已提交
76
			for (int i = 0; i < length; i++) {
77 78 79
				Object sourceElement = Array.get(source, i);
				Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetElementType);
				collection.add(targetElement);
K
Keith Donald 已提交
80 81 82 83 84 85
			}
		}
		return collection;
	}

}