moved generic converter to spi; added entity converter; removed various service impls in favor of service factory

This commit is contained in:
Keith Donald
2009-11-19 09:10:51 +00:00
parent 211e36c249
commit d85dc01e28
37 changed files with 418 additions and 341 deletions

View File

@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
package org.springframework.core.convert.converter;
/**
* A generic converter that, as a ConverterMatcher, conditionally executes.

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
package org.springframework.core.convert.converter;
import org.springframework.core.convert.TypeDescriptor;
@@ -23,6 +23,7 @@ import org.springframework.core.convert.TypeDescriptor;
* For example, when converting from a String to a Date field, an implementation might return true only if the target Date field has also been annotated with <code>@DateTimeFormat</code>.
* @author Keith Donald
* @since 3.0
* TODO - consider collapsing into ConditionalGenericConverter
*/
public interface ConverterMatcher {

View File

@@ -34,7 +34,15 @@ public interface ConverterRegistry {
void addConverterFactory(ConverterFactory<?, ?> converterFactory);
/**
* Remove the conversion logic for the sourceType to the targetType.
* Add a generic converter to this registry.
* @param sourceType the source type to convert from
* @param targetType the target type to convert to
* @param converter the generic converter
*/
void addGenericConverter(GenericConverter converter);
/**
* Remove any converters from sourceType to targetType.
* @param sourceType the source type
* @param targetType the target type
*/

View File

@@ -14,11 +14,10 @@
* limitations under the License.
*/
package org.springframework.core.convert.support;
package org.springframework.core.convert.converter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.support.GenericConversionService;
/**
* Uniform converter interface as returned from {@link GenericConversionService#getConverter}.
@@ -35,6 +34,13 @@ import org.springframework.core.convert.converter.ConverterFactory;
*/
public interface GenericConverter {
/**
* The source and target types this converter can convert between.
* Each entry in the returned array is a two-element array where the first element is a sourceType that can be converted from,
* and the second element is a targetType that can be converted to.
*/
public Class<?>[][] getConvertibleTypes();
/**
* Convert the source to the targetType described by the TypeDescriptor.
* @param source the source object to convert (may be null)

View File

@@ -19,6 +19,7 @@ package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.asList;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a source array to a target array type.
@@ -33,6 +34,10 @@ final class ArrayToArrayConverter implements GenericConverter {
public ArrayToArrayConverter(GenericConversionService conversionService) {
this.helperConverter = new CollectionToArrayConverter(conversionService);
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object[].class, Object[].class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.convert(asList(source), sourceType, targetType);

View File

@@ -24,6 +24,7 @@ import java.util.Collection;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from an array to a collection.
@@ -39,6 +40,10 @@ final class ArrayToCollectionConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object[].class, Collection.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -18,7 +18,10 @@ package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.asList;
import java.util.Map;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from an array to a Map.
@@ -34,6 +37,10 @@ final class ArrayToMapConverter implements GenericConverter {
this.helperConverter = new CollectionToMapConverter(conversionService);
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object[].class, Map.class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.convert(asList(source), sourceType, targetType);
}

View File

@@ -19,6 +19,7 @@ package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.asList;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from an array to a single Object.
@@ -34,6 +35,10 @@ final class ArrayToObjectConverter implements GenericConverter {
this.helperConverter = new CollectionToObjectConverter(conversionService);
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object[].class, Object.class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.convert(asList(source), sourceType, targetType);
}

View File

@@ -25,6 +25,7 @@ import java.util.Iterator;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a Collection to an array.
@@ -40,6 +41,10 @@ final class CollectionToArrayConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Collection.class, Object[].class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);

View File

@@ -24,6 +24,7 @@ import java.util.Collection;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a source Collection to target Collection type.
@@ -39,6 +40,10 @@ final class CollectionToCollectionConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Collection.class, Collection.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -23,7 +23,7 @@ import java.util.Map;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.style.StylerUtils;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a Collection to a Map.
@@ -39,6 +39,10 @@ final class CollectionToMapConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Collection.class, Map.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -23,6 +23,7 @@ import java.util.Collection;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a Collection to a single Object.
@@ -40,6 +41,10 @@ final class CollectionToObjectConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Collection.class, Object.class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);

View File

@@ -0,0 +1,63 @@
/*
* 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 org.springframework.core.convert.ConversionService;
/**
* A factor for creating common ConversionService configurations.
* @author Keith Donald
* @since 3.0
*/
public final class ConversionServiceFactory {
private ConversionServiceFactory() {
}
/**
* Create a default ConversionService.
*/
public static ConversionService createDefault() {
GenericConversionService conversionService = new GenericConversionService();
conversionService.addGenericConverter(new ArrayToArrayConverter(conversionService));
conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService));
conversionService.addGenericConverter(new ArrayToMapConverter(conversionService));
conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService));
conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService));
conversionService.addGenericConverter(new CollectionToArrayConverter(conversionService));
conversionService.addGenericConverter(new CollectionToMapConverter(conversionService));
conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService));
conversionService.addGenericConverter(new MapToMapConverter(conversionService));
conversionService.addGenericConverter(new MapToArrayConverter(conversionService));
conversionService.addGenericConverter(new MapToCollectionConverter(conversionService));
conversionService.addGenericConverter(new MapToObjectConverter(conversionService));
conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService));
conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService));
conversionService.addGenericConverter(new ObjectToMapConverter(conversionService));
conversionService.addConverter(new StringToBooleanConverter());
conversionService.addConverter(new StringToCharacterConverter());
conversionService.addConverter(new StringToLocaleConverter());
conversionService.addConverter(new NumberToCharacterConverter());
conversionService.addConverterFactory(new StringToNumberConverterFactory());
conversionService.addConverterFactory(new StringToEnumConverterFactory());
conversionService.addConverterFactory(new NumberToNumberConverterFactory());
conversionService.addConverterFactory(new CharacterToNumberFactory());
conversionService.addConverter(new ObjectToStringConverter());
conversionService.addGenericConverter(new ObjectToObjectGenericConverter());
return conversionService;
}
}

View File

@@ -24,6 +24,7 @@ import java.util.RandomAccess;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
final class ConversionUtils {

View File

@@ -1,47 +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.Locale;
/**
* Default implementation of a conversion service. Will automatically register <i>from string</i>
* converters for a number of standard Java types like Class, Number, Boolean and so on.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
public class DefaultConversionService extends GenericConversionService {
/**
* Create a new default conversion service, installing the default converters.
*/
public DefaultConversionService() {
addConverter(String.class, Boolean.class, new StringToBooleanConverter());
addConverter(String.class, Character.class, new StringToCharacterConverter());
addConverter(String.class, Locale.class, new StringToLocaleConverter());
addConverter(Number.class, Character.class, new NumberToCharacterConverter());
addConverterFactory(String.class, Number.class, new StringToNumberConverterFactory());
addConverterFactory(String.class, Enum.class, new StringToEnumConverterFactory());
addConverterFactory(Number.class, Number.class, new NumberToNumberConverterFactory());
addConverterFactory(Character.class, Number.class, new CharacterToNumberFactory());
addConverter(Object.class, String.class, new ObjectToStringConverter());
addGenericConverter(Object.class, Object.class, new ObjectToObjectGenericConverter());
}
}

View File

@@ -0,0 +1,97 @@
/*
* 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.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* Converts an entity identifier to a entity reference by calling a static finder method on the target entity type.
* Also converts a entity reference to a String by printing its id property to String.
* For id-to-entity conversion to match, the finder method must be public, static, have the signature 'find[EntityName]([IdType])', and return an instance of the desired entity type.
* For entity-to-string conversion to match, a getter method for the 'id' property must be defined.
* @author Keith Donald
* @since 3.0
*/
final class EntityConverter implements ConditionalGenericConverter {
private ConversionService conversionService;
public EntityConverter(ConversionService conversionService) {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class[][] {
{ Object.class, Object.class },
{ Object.class, String.class }
};
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
if (String.class.equals(targetType.getType())) {
return getIdAccessor(sourceType.getType()) != null;
} else {
return getFinder(targetType.getType()) != null;
}
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (String.class.equals(targetType.getType())) {
Method idAccessor = getIdAccessor(sourceType.getType());
Object id = ReflectionUtils.invokeMethod(idAccessor, source);
return this.conversionService.convert(id, String.class);
} else {
Method finder = getFinder(targetType.getType());
Object id = conversionService.convert(source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
return ReflectionUtils.invokeMethod(finder, source, id);
}
}
private Method getIdAccessor(Class<?> entityClass) {
return ClassUtils.getMethodIfAvailable(entityClass, "getId");
}
private Method getFinder(Class<?> entityClass) {
String finderMethod = "find" + getEntityName(entityClass);
Method[] methods = entityClass.getDeclaredMethods();
for (Method method : methods) {
if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1) {
if (method.getName().equals(finderMethod)) {
return method;
}
}
}
return null;
}
private String getEntityName(Class<?> entityClass) {
String shortName = ClassUtils.getShortName(entityClass);
int lastDot = shortName.lastIndexOf('.');
if (lastDot != -1) {
return shortName.substring(lastDot + 1);
} else {
return shortName;
}
}
}

View File

@@ -19,12 +19,10 @@ package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -35,7 +33,9 @@ import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.ConverterMatcher;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -50,6 +50,10 @@ public class GenericConversionService implements ConversionService, ConverterReg
private static final Log logger = LogFactory.getLog(GenericConversionService.class);
private static final GenericConverter NO_OP_CONVERTER = new GenericConverter() {
public Class<?>[][] getConvertibleTypes() {
return null;
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return source;
}
@@ -57,68 +61,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
private final Map<Class<?>, Map<Class<?>, MatchableConverters>> converters = new HashMap<Class<?>, Map<Class<?>, MatchableConverters>>(36);
private ConversionService parent;
private GenericConverter parentConverterAdapter = new GenericConverter() {
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return parent.convert(source, sourceType, targetType);
}
};
public GenericConversionService() {
addGenericConverter(Object[].class, Object[].class, new ArrayToArrayConverter(this));
addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionConverter(this));
addGenericConverter(Object[].class, Map.class, new ArrayToMapConverter(this));
addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter(this));
addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionConverter(this));
addGenericConverter(Collection.class, Object[].class, new CollectionToArrayConverter(this));
addGenericConverter(Collection.class, Map.class, new CollectionToMapConverter(this));
addGenericConverter(Collection.class, Object.class, new CollectionToObjectConverter(this));
addGenericConverter(Map.class, Map.class, new MapToMapConverter(this));
addGenericConverter(Map.class, Object[].class, new MapToArrayConverter(this));
addGenericConverter(Map.class, Collection.class, new MapToCollectionConverter(this));
addGenericConverter(Map.class, Object.class, new MapToObjectConverter(this));
addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter(this));
addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter(this));
addGenericConverter(Object.class, Map.class, new ObjectToMapConverter(this));
}
/**
* Registers the converters in the set provided.
* JavaBean-friendly alternative to calling {@link #addConverter(Converter)}.
* @see #addConverter(Converter)
*/
public void setConverters(Set<Converter<?, ?>> converters) {
for (Converter<?, ?> converter : converters) {
addConverter(converter);
}
}
/**
* Registers the converter factories in the set provided.
* JavaBean-friendly alternative to calling {@link #addConverterFactory(ConverterFactory)}.
* @see #addConverterFactory(ConverterFactory)
*/
public void setConverterFactories(Set<ConverterFactory<?, ?>> converters) {
for (ConverterFactory<?, ?> converterFactory : converters) {
addConverterFactory(converterFactory);
}
}
/**
* Set the parent of this conversion service. This is optional.
*/
public void setParent(ConversionService parent) {
this.parent = parent;
}
/**
* Returns the parent of this conversion service. May be null.
*/
public ConversionService getParent() {
return this.parent;
}
// implementing ConverterRegistry
public void addConverter(Converter<?, ?> converter) {
@@ -127,9 +69,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
throw new IllegalArgumentException(
"Unable to the determine sourceType <S> and targetType <T> your Converter<S, T> converts between; declare these types or implement ConverterInfo");
}
Class<?> sourceType = typeInfo[0];
Class<?> targetType = typeInfo[1];
addConverter(sourceType, targetType, converter);
addGenericConverter(new ConverterAdapter(typeInfo, converter));
}
public void addConverterFactory(ConverterFactory<?, ?> converterFactory) {
@@ -138,11 +78,16 @@ public class GenericConversionService implements ConversionService, ConverterReg
throw new IllegalArgumentException(
"Unable to the determine sourceType <S> and targetRangeType R your ConverterFactory<S, R> converts between; declare these types or implement ConverterInfo");
}
Class<?> sourceType = typeInfo[0];
Class<?> targetType = typeInfo[1];
addConverterFactory(sourceType, targetType, converterFactory);
addGenericConverter(new ConverterFactoryAdapter(typeInfo, converterFactory));
}
public void addGenericConverter(GenericConverter converter) {
Class<?>[][] convertibleTypes = converter.getConvertibleTypes();
for (Class<?>[] convertibleType : convertibleTypes) {
getMatchableConvertersList(convertibleType[0], convertibleType[1]).add(converter);
}
}
public void removeConvertible(Class<?> sourceType, Class<?> targetType) {
getSourceConverterMap(sourceType).remove(targetType);
}
@@ -182,50 +127,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
return invokeConverter(converter, source, sourceType, targetType);
}
/**
* Registers a GenericConverter for the source/target type pair.
* @param sourceType the source type to convert from
* @param targetType the target type to convert to
* @param converter the generic converter.
*/
public void addGenericConverter(Class<?> sourceType, Class<?> targetType, GenericConverter converter) {
getMatchableConvertersList(sourceType, targetType).add(converter);
}
/**
* Registers a GenericConverter for the source/target type pair that will only be matched if the provided matcher returns true.
* @param sourceType the source type to convert from
* @param targetType the target type to convert to
* @param matcher a matcher can restrict a match of the converter based on source and target runtime field types
* @param converter the generic converter.
*/
public void addGenericConverter(Class<?> sourceType, Class<?> targetType, GenericConverter converter,
ConverterMatcher matcher) {
getMatchableConvertersList(sourceType, targetType).add(matcher, converter);
}
/**
* Registers a Converter with the sourceType and targetType to index on specified explicitly.
* This method performs better than {@link #addConverter(Converter)} because there parameterized types S and T don't have to be discovered.
* @param sourceType the source type to convert from
* @param targetType the target type to convert to
* @param converter the converter.
*/
public void addConverter(Class<?> sourceType, Class<?> targetType, Converter<?, ?> converter) {
addGenericConverter(sourceType, targetType, new ConverterAdapter(converter));
}
/**
* Registers a ConverterFactory with the sourceType and targetType to index on specified explicitly.
* This method performs better than {@link #addConverter(ConverterFactory)} because there parameterized types S and T don't have to be discovered.
* @param sourceType the source type to convert from
* @param targetType the target type to convert to
* @param converter the converter.factory
*/
public void addConverterFactory(Class<?> sourceType, Class<?> targetType, ConverterFactory<?, ?> converterFactory) {
addGenericConverter(sourceType, targetType, new ConverterFactoryAdapter(converterFactory));
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ConversionService converters = ").append("\n");
@@ -236,9 +137,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
builder.append("\n");
}
}
if (this.parent != null) {
builder.append("parent = ").append(this.parent);
}
return builder.toString();
}
@@ -275,8 +173,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
GenericConverter converter = findConverterForClassPair(sourceType, targetType);
if (converter != null) {
return converter;
} else if (this.parent != null && this.parent.canConvert(sourceType, targetType)) {
return this.parentConverterAdapter;
} else {
return getDefaultConverter(sourceType, targetType);
}
@@ -443,10 +339,17 @@ public class GenericConversionService implements ConversionService, ConverterReg
@SuppressWarnings("unchecked")
private final class ConverterAdapter implements GenericConverter {
private final Class<?>[] typeInfo;
private final Converter converter;
public ConverterAdapter(Converter<?, ?> converter) {
public ConverterAdapter(Class<?>[] typeInfo, Converter<?, ?> converter) {
this.converter = converter;
this.typeInfo = typeInfo;
}
public Class<?>[][] getConvertibleTypes() {
return new Class[][] { this.typeInfo };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
@@ -464,12 +367,19 @@ public class GenericConversionService implements ConversionService, ConverterReg
@SuppressWarnings("unchecked")
private final class ConverterFactoryAdapter implements GenericConverter {
private final Class<?>[] typeInfo;
private final ConverterFactory converterFactory;
public ConverterFactoryAdapter(ConverterFactory<?, ?> converterFactory) {
public ConverterFactoryAdapter(Class<?>[] typeInfo, ConverterFactory<?, ?> converterFactory) {
this.converterFactory = converterFactory;
this.typeInfo = typeInfo;
}
public Class<?>[][] getConvertibleTypes() {
return new Class[][] { this.typeInfo };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return convertNullSource(sourceType, targetType);

View File

@@ -20,6 +20,7 @@ import static org.springframework.core.convert.support.ConversionUtils.invokeCon
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Helper for converting map entries.

View File

@@ -17,8 +17,10 @@
package org.springframework.core.convert.support;
import java.util.List;
import java.util.Map;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a Map to an array.
@@ -37,6 +39,10 @@ final class MapToArrayConverter implements GenericConverter {
this.collectionToArrayHelperConverter = new CollectionToArrayConverter(conversionService);
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Map.class, Object[].class } };
}
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);

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a Map to a Collection.
@@ -38,6 +39,10 @@ final class MapToCollectionConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Map.class, Collection.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -22,6 +22,7 @@ import java.util.Map;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a source Map to a target Map type.
@@ -37,6 +38,10 @@ final class MapToMapConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Map.class, Map.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Properties;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a Map to a single Object.
@@ -39,6 +40,10 @@ final class MapToObjectConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Map.class, Object.class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);

View File

@@ -22,6 +22,7 @@ import java.lang.reflect.Array;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.util.StringUtils;
/**
@@ -38,6 +39,10 @@ final class ObjectToArrayConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object.class, Object[].class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);

View File

@@ -23,6 +23,7 @@ import java.util.Collection;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.util.StringUtils;
/**
@@ -39,6 +40,10 @@ final class ObjectToCollectionConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object.class, Collection.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -22,6 +22,7 @@ import java.util.Properties;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts from a single Object to a Map.
@@ -37,6 +38,10 @@ final class ObjectToMapConverter implements GenericConverter {
this.conversionService = conversionService;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object.class, Map.class } };
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {

View File

@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -42,6 +43,10 @@ final class ObjectToObjectGenericConverter implements ConditionalGenericConverte
return getValueOfMethodOn(targetClass, sourceClass) != null || getConstructor(targetClass, sourceClass) != null;
}
public Class<?>[][] getConvertibleTypes() {
return new Class<?>[][] { { Object.class, Object.class } };
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (sourceType.isAssignableTo(targetType)) {
return source;