From 49e3f2b8c7070e32f87d09a973f038f26f11b1e9 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Thu, 17 Mar 2011 14:34:36 +0100 Subject: [PATCH] Improved handling of custom converters. On COnverter registration we now keep track of the types the converter can register and only apply custom conversion if we had discovered a custom converter initially. --- .../convert/MappingMongoConverter.java | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java index a189640a8..886fbdf5d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -42,6 +43,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.expression.BeanFactoryResolver; +import org.springframework.core.GenericTypeResolver; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.ConversionServiceFactory; @@ -72,7 +74,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext private static final List> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class); protected static final Log log = LogFactory.getLog(MappingMongoConverter.class); - protected GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService(); + protected final GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService(); + protected final Map, Class> customTypeMapping = new HashMap, Class>(); protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); protected MappingContext mappingContext; protected ApplicationContext applicationContext; @@ -94,12 +97,26 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext this.mappingContext = mappingContext; if (null != converters) { for (Converter c : converters) { + registerConverter(c); conversionService.addConverter(c); } } initializeConverters(); } + /** + * Inspects the given {@link Converter} for the types it can convert and registers the pair for custom type conversion + * in case the target type is a Mongo basic type. + * + * @param converter + */ + private void registerConverter(Converter converter) { + Class[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class); + if (MONGO_TYPES.contains(arguments[1])) { + customTypeMapping.put(arguments[0], arguments[1]); + } + } + public MappingContext getMappingContext() { return mappingContext; } @@ -444,7 +461,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext } } - Class basicTargetType = getCustomTargetType(obj); + // Lookup potential custom target type + Class basicTargetType = customTypeMapping.get(obj.getClass()); if (basicTargetType != null) { dbo.put(name, conversionService.convert(obj, basicTargetType)); @@ -457,23 +475,6 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext } - /** - * Returns whether the {@link ConversionService} has a custom {@link Converter} registered that can convert the given - * object into one of the types supported by MongoDB. - * - * @param obj - * @return - */ - private Class getCustomTargetType(Object obj) { - - for (Class mongoType : MONGO_TYPES) { - if (conversionService.canConvert(obj.getClass(), mongoType)) { - return mongoType; - } - } - return null; - } - protected void writeMapInternal(Map obj, DBObject dbo) { for (Map.Entry entry : obj.entrySet()) { Object key = entry.getKey();