Browse Source

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.
pull/1/head
Oliver Gierke 15 years ago
parent
commit
49e3f2b8c7
  1. 39
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java

39
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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -42,6 +43,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.core.convert.support.ConversionServiceFactory;
@ -72,7 +74,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class); private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class);
protected static final Log log = LogFactory.getLog(MappingMongoConverter.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<?>, Class<?>> customTypeMapping = new HashMap<Class<?>, Class<?>>();
protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
protected MappingContext mappingContext; protected MappingContext mappingContext;
protected ApplicationContext applicationContext; protected ApplicationContext applicationContext;
@ -94,12 +97,26 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
this.mappingContext = mappingContext; this.mappingContext = mappingContext;
if (null != converters) { if (null != converters) {
for (Converter<?, ?> c : converters) { for (Converter<?, ?> c : converters) {
registerConverter(c);
conversionService.addConverter(c); conversionService.addConverter(c);
} }
} }
initializeConverters(); 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() { public MappingContext getMappingContext() {
return mappingContext; 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) { if (basicTargetType != null) {
dbo.put(name, conversionService.convert(obj, basicTargetType)); 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<Object, Object> obj, DBObject dbo) { protected void writeMapInternal(Map<Object, Object> obj, DBObject dbo) {
for (Map.Entry<Object, Object> entry : obj.entrySet()) { for (Map.Entry<Object, Object> entry : obj.entrySet()) {
Object key = entry.getKey(); Object key = entry.getKey();

Loading…
Cancel
Save