Browse Source

Adapted introduction of BeanWrapper in Spring Data Commons.

Moved code dealing with the ConversionService into AbstractMongoConverter. Added getConversionService() to MongoConverter interface. Replaced usage of MappingBeanHelper with BeanWrapper usage.
pull/1/head
Oliver Gierke 15 years ago
parent
commit
8474a28538
  1. 9
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java
  2. 129
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/AbstractMongoConverter.java
  3. 165
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java
  4. 3
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MongoConverter.java
  5. 65
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/SimpleMongoConverter.java
  6. 4
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/repository/MappingMongoEntityInformation.java
  7. 2
      spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoOperationsUnitTests.java

9
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java

@ -47,6 +47,7 @@ import org.springframework.context.ApplicationEventPublisher; @@ -47,6 +47,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
@ -68,7 +69,7 @@ import org.springframework.data.document.mongodb.mapping.event.MongoMappingEvent @@ -68,7 +69,7 @@ import org.springframework.data.document.mongodb.mapping.event.MongoMappingEvent
import org.springframework.data.document.mongodb.query.Query;
import org.springframework.data.document.mongodb.query.QueryMapper;
import org.springframework.data.document.mongodb.query.Update;
import org.springframework.data.mapping.MappingBeanHelper;
import org.springframework.data.mapping.BeanWrapper;
import org.springframework.data.mapping.model.MappingContext;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.jca.cci.core.ConnectionCallback;
@ -1013,9 +1014,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { @@ -1013,9 +1014,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
if (idProp == null) {
throw new MappingException("No id property found for object of type " + entity.getType().getName());
}
ConversionService service = mongoConverter.getConversionService();
try {
return MappingBeanHelper.getProperty(object, idProp, Object.class, true);
return BeanWrapper.create(object, service).getProperty(idProp, Object.class, true);
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
@ -1048,7 +1051,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { @@ -1048,7 +1051,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
try {
MappingBeanHelper.setProperty(savedObject, idProp, id);
BeanWrapper.create(savedObject, mongoConverter.getConversionService()).setProperty(idProp, id);
return;
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);

129
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/AbstractMongoConverter.java

@ -18,13 +18,32 @@ package org.springframework.data.document.mongodb.convert; @@ -18,13 +18,32 @@ package org.springframework.data.document.mongodb.convert;
import static org.springframework.data.mapping.MappingBeanHelper.isSimpleType;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.document.mongodb.convert.ObjectIdConverters.BigIntegerToObjectIdConverter;
import org.springframework.data.document.mongodb.convert.ObjectIdConverters.ObjectIdToBigIntegerConverter;
import org.springframework.data.document.mongodb.convert.ObjectIdConverters.ObjectIdToStringConverter;
import org.springframework.data.document.mongodb.convert.ObjectIdConverters.StringToObjectIdConverter;
import org.springframework.data.mapping.MappingBeanHelper;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
@ -32,8 +51,111 @@ import com.mongodb.DBObject; @@ -32,8 +51,111 @@ import com.mongodb.DBObject;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public abstract class AbstractMongoConverter implements MongoConverter {
public abstract class AbstractMongoConverter implements MongoConverter, InitializingBean {
@SuppressWarnings({ "unchecked" })
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class,
DBObject.class);
protected final GenericConversionService conversionService;
private final Set<ConvertiblePair> customTypeMapping = new HashSet<ConvertiblePair>();
public AbstractMongoConverter(GenericConversionService conversionService) {
this.conversionService = conversionService == null ? ConversionServiceFactory.createDefaultConversionService()
: conversionService;
this.conversionService.removeConvertible(Object.class, String.class);
}
/**
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
* metadata driven conversion between of objects to/from DBObject
*
* @param converters
*/
public void setCustomConverters(Set<?> converters) {
if (null != converters) {
for (Object c : converters) {
registerConverter(c);
}
}
}
/**
* Registers converters for {@link ObjectId} handling, removes plain {@link #toString()} converter and promotes the
* configured {@link ConversionService} to {@link MappingBeanHelper}.
*/
private void initializeConverters() {
if (!conversionService.canConvert(ObjectId.class, String.class)) {
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
}
if (!conversionService.canConvert(String.class, ObjectId.class)) {
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
}
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
}
}
/**
* 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(Object converter) {
Class<?>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class);
if (MONGO_TYPES.contains(arguments[1]) || MONGO_TYPES.contains(arguments[0])) {
customTypeMapping.add(new ConvertiblePair(arguments[0], arguments[1]));
}
boolean added = false;
if (converter instanceof Converter) {
this.conversionService.addConverter((Converter<?, ?>) converter);
added = true;
}
if (converter instanceof ConverterFactory) {
this.conversionService.addConverterFactory((ConverterFactory<?, ?>) converter);
added = true;
}
if (!added) {
throw new IllegalArgumentException("Given set contains element that is neither Converter nor ConverterFactory!");
}
}
protected Class<?> getCustomTarget(Class<?> source, Class<?> expectedTargetType) {
for (ConvertiblePair typePair : customTypeMapping) {
if (typePair.getSourceType().isAssignableFrom(source)) {
Class<?> targetType = typePair.getTargetType();
if (targetType.equals(expectedTargetType) || expectedTargetType == null) {
return targetType;
}
}
}
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.document.mongodb.convert.MongoConverter#getConversionService()
*/
public ConversionService getConversionService() {
return conversionService;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() {
initializeConverters();
}
@SuppressWarnings("unchecked")
public Object maybeConvertObject(Object obj) {
if (obj instanceof Enum<?>) {
return ((Enum<?>) obj).name();
@ -93,14 +215,11 @@ public abstract class AbstractMongoConverter implements MongoConverter { @@ -93,14 +215,11 @@ public abstract class AbstractMongoConverter implements MongoConverter {
public BasicDBList maybeConvertList(BasicDBList dbl) {
BasicDBList newDbl = new BasicDBList();
Iterator iter = dbl.iterator();
Iterator<?> iter = dbl.iterator();
while (iter.hasNext()) {
Object o = iter.next();
newDbl.add(maybeConvertObject(o));
}
return newDbl;
}
public abstract void setCustomConverters(Set<?> converters);
}

165
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
package org.springframework.data.document.mongodb.convert;
import static org.springframework.data.document.mongodb.convert.ObjectIdConverters.*;
import static org.springframework.data.mapping.MappingBeanHelper.*;
import java.lang.reflect.Array;
@ -25,52 +24,46 @@ import java.math.BigInteger; @@ -25,52 +24,46 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.ObjectId;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
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.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.document.mongodb.MongoDbFactory;
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity;
import org.springframework.data.document.mongodb.mapping.MongoPersistentProperty;
import org.springframework.data.mapping.AssociationHandler;
import org.springframework.data.mapping.MappingBeanHelper;
import org.springframework.data.mapping.BeanWrapper;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.Association;
import org.springframework.data.mapping.model.MappingContext;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.ParameterValueProvider;
import org.springframework.data.mapping.model.PreferredConstructor;
import org.springframework.data.mapping.model.SpELAwareParameterValueProvider;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
* {@link MongoConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to
* {@link DBObject}.
@ -78,26 +71,29 @@ import org.springframework.util.StringUtils; @@ -78,26 +71,29 @@ import org.springframework.util.StringUtils;
* @author Jon Brisbin <jbrisbin@vmware.com>
* @author Oliver Gierke
*/
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware, InitializingBean {
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
public static final String CUSTOM_TYPE_KEY = "_class";
@SuppressWarnings({"unchecked"})
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class,
DBObject.class);
private static final List<Class<?>> VALID_ID_TYPES = Arrays.asList(new Class<?>[]{ObjectId.class, String.class,
BigInteger.class, byte[].class});
protected static final Log log = LogFactory.getLog(MappingMongoConverter.class);
protected final GenericConversionService conversionService = ConversionServiceFactory
.createDefaultConversionService();
protected final Set<ConvertiblePair> customTypeMapping = new HashSet<ConvertiblePair>();
protected final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
protected final SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
protected ApplicationContext applicationContext;
protected boolean useFieldAccessOnly = true;
protected MongoDbFactory mongoDbFactory;
/**
* Creates a new {@link MappingMongoConverter} given the new {@link MongoDbFactory} and {@link MappingContext}.
*
* @param mongoDbFactory
* @param mappingContext
*/
public MappingMongoConverter(MongoDbFactory mongoDbFactory, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
super(ConversionServiceFactory.createDefaultConversionService());
Assert.notNull(mappingContext);
this.mongoDbFactory = mongoDbFactory;
this.mappingContext = mappingContext;
}
@ -109,63 +105,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -109,63 +105,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
*/
public MappingMongoConverter(
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
this.mappingContext = mappingContext;
this.conversionService.removeConvertible(Object.class, String.class);
}
/**
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
* metadata driven conversion between of objects to/from DBObject
*
* @param converters
*/
@Override
public void setCustomConverters(Set<?> converters) {
if (null != converters) {
for (Object c : converters) {
registerConverter(c);
}
}
}
/**
* 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(Object converter) {
Class<?>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class);
if (MONGO_TYPES.contains(arguments[1]) || MONGO_TYPES.contains(arguments[0])) {
customTypeMapping.add(new ConvertiblePair(arguments[0], arguments[1]));
}
boolean added = false;
if (converter instanceof Converter) {
this.conversionService.addConverter((Converter<?, ?>) converter);
added = true;
}
if (converter instanceof ConverterFactory) {
this.conversionService.addConverterFactory((ConverterFactory<?, ?>) converter);
added = true;
}
if (!added) {
throw new IllegalArgumentException("Given set contains element that is neither Converter nor ConverterFactory!");
}
}
private Class<?> getCustomTarget(Class<?> source, Class<?> expectedTargetType) {
for (ConvertiblePair typePair : customTypeMapping) {
if (typePair.getSourceType().isAssignableFrom(source)) {
Class<?> targetType = typePair.getTargetType();
if (targetType.equals(expectedTargetType) || expectedTargetType == null) {
return targetType;
}
}
}
return null;
this(null, mappingContext);
}
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getMappingContext() {
@ -257,9 +197,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -257,9 +197,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
final List<String> ctorParamNames = new ArrayList<String>();
final MongoPersistentProperty idProperty = entity.getIdProperty();
final S instance = constructInstance(entity, new PreferredConstructor.ParameterValueProvider() {
ParameterValueProvider provider = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx) {
@Override
@SuppressWarnings("unchecked")
public <T> T getParameterValue(PreferredConstructor.Parameter<T> parameter) {
if (parameter.getKey() != null) {
return super.getParameterValue(parameter);
}
String name = parameter.getName();
TypeInformation<T> type = parameter.getType();
Class<T> rawType = parameter.getRawType();
@ -283,7 +230,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -283,7 +230,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return null;
}
}, spelCtx);
};
final BeanWrapper<MongoPersistentEntity<S>, S> wrapper = BeanWrapper.create(entity, provider, conversionService);
// Set properties not already set in the constructor
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
@ -298,7 +247,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -298,7 +247,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
Object obj = getValueInternal(prop, dbo, spelCtx, prop.getSpelExpression());
try {
setProperty(instance, prop, obj, useFieldAccessOnly);
wrapper.setProperty(prop, obj, useFieldAccessOnly);
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
@ -313,7 +262,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -313,7 +262,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
MongoPersistentProperty inverseProp = association.getInverse();
Object obj = getValueInternal(inverseProp, dbo, spelCtx, inverseProp.getSpelExpression());
try {
setProperty(instance, inverseProp, obj);
wrapper.setProperty(inverseProp, obj);
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
@ -322,7 +271,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -322,7 +271,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
});
return instance;
return wrapper.getBean();
}
/**
@ -376,7 +325,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -376,7 +325,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
writeInternal(obj, dbo, entity);
}
protected void writeInternal(final Object obj, final DBObject dbo, MongoPersistentEntity<?> entity) {
protected void writeInternal(Object obj, final DBObject dbo, MongoPersistentEntity<?> entity) {
if (obj == null) {
return;
@ -385,13 +334,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -385,13 +334,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (null == entity) {
throw new MappingException("No mapping metadata found for entity of type " + obj.getClass().getName());
}
final BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(obj, conversionService);
// Write the ID
final MongoPersistentProperty idProperty = entity.getIdProperty();
if (!dbo.containsField("_id") && null != idProperty) {
Object idObj;
try {
idObj = getProperty(obj, idProperty, Object.class, useFieldAccessOnly);
idObj = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
@ -413,7 +364,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -413,7 +364,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
public void doWithPersistentProperty(MongoPersistentProperty prop) {
Object propertyObj;
try {
propertyObj = getProperty(obj, prop, prop.getType(), useFieldAccessOnly);
propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
@ -435,7 +386,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -435,7 +386,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
Class<?> type = inverseProp.getType();
Object propertyObj;
try {
propertyObj = getProperty(obj, inverseProp, type, useFieldAccessOnly);
propertyObj = wrapper.getProperty(inverseProp, type, useFieldAccessOnly);
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
@ -452,28 +403,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -452,28 +403,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
this.applicationContext = applicationContext;
}
/**
* Registers converters for {@link ObjectId} handling, removes plain {@link #toString()} converter and promotes the
* configured {@link ConversionService} to {@link MappingBeanHelper}.
*/
private void initializeConverters() {
if (!conversionService.canConvert(ObjectId.class, String.class)) {
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
}
if (!conversionService.canConvert(String.class, ObjectId.class)) {
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
}
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
}
setConversionService(conversionService);
}
@SuppressWarnings({"unchecked"})
protected void writePropertyInternal(MongoPersistentProperty prop, Object obj, DBObject dbo) {
@ -651,8 +580,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -651,8 +580,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
MongoPersistentProperty idProperty = targetEntity.getIdProperty();
ObjectId id = null;
BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(target, conversionService);
try {
id = getProperty(target, idProperty, ObjectId.class, useFieldAccessOnly);
id = wrapper.getProperty(idProperty, ObjectId.class, useFieldAccessOnly);
if (null == id) {
throw new MappingException("Cannot create a reference to an object with a NULL id.");
}
@ -813,9 +743,4 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -813,9 +743,4 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
return rootList;
}
public void afterPropertiesSet() {
initializeConverters();
}
}

3
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MongoConverter.java

@ -17,6 +17,7 @@ package org.springframework.data.document.mongodb.convert; @@ -17,6 +17,7 @@ package org.springframework.data.document.mongodb.convert;
import com.mongodb.BasicDBList;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.document.mongodb.MongoReader;
import org.springframework.data.document.mongodb.MongoWriter;
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity;
@ -53,4 +54,6 @@ public interface MongoConverter extends MongoWriter<Object>, MongoReader<Object> @@ -53,4 +54,6 @@ public interface MongoConverter extends MongoWriter<Object>, MongoReader<Object>
Object[] maybeConvertArray(Object[] src);
BasicDBList maybeConvertList(BasicDBList dbl);
ConversionService getConversionService();
}

65
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/SimpleMongoConverter.java

@ -15,14 +15,11 @@ @@ -15,14 +15,11 @@
*/
package org.springframework.data.document.mongodb.convert;
import static org.springframework.data.document.mongodb.convert.ObjectIdConverters.*;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -51,9 +48,7 @@ import org.springframework.core.CollectionFactory; @@ -51,9 +48,7 @@ import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor;
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity;
import org.springframework.data.document.mongodb.mapping.MongoPersistentProperty;
@ -69,9 +64,9 @@ import org.springframework.util.comparator.CompoundComparator; @@ -69,9 +64,9 @@ import org.springframework.util.comparator.CompoundComparator;
* @author Thomas Risberg
* @author Oliver Gierke
*
* @deprecated since Spring 1.0 M3 in favor of {@link org.springframework.data.document.mongodb.convert.MappingMongoConverter}
* The MappingMongoConverter provides all the functionality of the SimpleMongoConverter and will replace it as the default
* converter used. The SimpleMongoCOnverter will be removed at some point before the GA release.
* @deprecated since Spring 1.0 M3 in favor of {@link org.springframework.data.document.mongodb.convert.MappingMongoConverter}
* The MappingMongoConverter provides all the functionality of the SimpleMongoConverter and will replace it as the default
* converter used. The SimpleMongoCOnverter will be removed at some point before the GA release.
*/
@Deprecated
public class SimpleMongoConverter extends AbstractMongoConverter implements InitializingBean {
@ -131,15 +126,13 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init @@ -131,15 +126,13 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
SIMPLE_TYPES = Collections.unmodifiableSet(basics);
}
private final GenericConversionService conversionService;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
/**
* Creates a {@link SimpleMongoConverter}.
*/
public SimpleMongoConverter() {
this.conversionService = ConversionServiceFactory.createDefaultConversionService();
this.conversionService.removeConvertible(Object.class, String.class);
super(ConversionServiceFactory.createDefaultConversionService());
this.mappingContext = new SimpleMongoMappingContext();
}
@ -150,49 +143,6 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init @@ -150,49 +143,6 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
return mappingContext;
}
/**
* Initializes additional converters that handle {@link ObjectId} conversion. Will register converters for supported
* id types if none are registered for those conversion already. {@link GenericConversionService} is configured.
*/
private void initializeConverters() {
if (!conversionService.canConvert(ObjectId.class, String.class)) {
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
}
if (!conversionService.canConvert(String.class, ObjectId.class)) {
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
}
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
}
}
/**
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over using
* object traversal to convert and object to/from DBObject
*
* @param converters
*/
public void setCustomConverters(Set<?> converters) {
for (Object converter : converters) {
boolean added = false;
if (converter instanceof Converter) {
this.conversionService.addConverter((Converter<?, ?>) converter);
added = true;
}
if (converter instanceof ConverterFactory) {
this.conversionService.addConverterFactory((ConverterFactory<?, ?>) converter);
added = true;
}
if (!added) {
throw new IllegalArgumentException("Given set contains element that is neither Converter nor ConverterFactory!");
}
}
}
/*
* (non-Javadoc)
*
@ -563,11 +513,4 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init @@ -563,11 +513,4 @@ public class SimpleMongoConverter extends AbstractMongoConverter implements Init
public ObjectId convertObjectId(Object id) {
return conversionService.convert(id, ObjectId.class);
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() {
initializeConverters();
}
}

4
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/repository/MappingMongoEntityInformation.java

@ -19,7 +19,7 @@ import java.io.Serializable; @@ -19,7 +19,7 @@ import java.io.Serializable;
import org.springframework.data.document.mongodb.mapping.BasicMongoPersistentEntity;
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity;
import org.springframework.data.document.mongodb.mapping.MongoPersistentProperty;
import org.springframework.data.mapping.MappingBeanHelper;
import org.springframework.data.mapping.BeanWrapper;
import org.springframework.data.repository.support.AbstractEntityInformation;
/**
@ -53,7 +53,7 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends A @@ -53,7 +53,7 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends A
MongoPersistentProperty idProperty = entityMetadata.getIdProperty();
try {
return (ID) MappingBeanHelper.getProperty(entity, idProperty, idProperty.getType(), false);
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
} catch (Exception e) {
throw new RuntimeException(e);
}

2
spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoOperationsUnitTests.java

@ -61,7 +61,7 @@ public abstract class MongoOperationsUnitTests { @@ -61,7 +61,7 @@ public abstract class MongoOperationsUnitTests {
person = new Person("Oliver");
persons = Arrays.asList(person);
converter = new AbstractMongoConverter() {
converter = new AbstractMongoConverter(null) {
public void write(Object t, DBObject dbo) {
dbo.put("firstName", person.getFirstName());

Loading…
Cancel
Save