diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 06a373655..c3e99515b 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -1,170 +1,191 @@
- 4.0.0
-
- org.springframework.data
- spring-data-document-parent
- 1.0.0.BUILD-SNAPSHOT
- ../spring-data-document-parent/pom.xml
-
- spring-data-mongodb
- jar
- Spring Data MongoDB Support
-
-
- 2.4
-
-
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ 4.0.0
+
+ org.springframework.data
+ spring-data-document-parent
+ 1.0.0.BUILD-SNAPSHOT
+ ../spring-data-document-parent/pom.xml
+
+ spring-data-mongodb
+ jar
+ Spring Data MongoDB Support
-
-
- org.springframework
- spring-beans
-
-
- org.springframework
- spring-tx
-
-
- org.springframework
- spring-expression
-
-
- org.springframework
- spring-test
- test
-
+
+ 2.4
+
-
-
- org.springframework.data
- spring-data-document-core
- ${project.version}
-
-
- org.springframework.data
- spring-data-commons-core
- ${data.commons.version}
-
-
-
-
- org.mongodb
- mongo-java-driver
- ${mongo.version}
-
-
- javax.persistence
- persistence-api
-
-
-
+
-
- com.mysema.querydsl
- querydsl-mongodb
- 2.1.1
- true
-
-
- com.google.code.morphia
- morphia
-
-
-
-
-
- com.mysema.querydsl
- querydsl-apt
- 2.1.1
- provided
-
-
-
- javax.annotation
- jsr250-api
- true
-
+
+
+ org.springframework
+ spring-beans
+
+
+ org.springframework
+ spring-tx
+
+
+ org.springframework
+ spring-expression
+
+
+ org.springframework
+ spring-test
+ test
+
-
- javax.annotation
- jsr250-api
- true
-
+
+
+ org.springframework.data
+ spring-data-document-core
+ ${project.version}
+
+
+ org.springframework.data
+ spring-data-commons-core
+ ${data.commons.version}
+
-
-
-
-
- org.mockito
- mockito-all
- test
-
+
+
+ org.mongodb
+ mongo-java-driver
+ ${mongo.version}
+
+
+ javax.persistence
+ persistence-api
+
+
+
-
- org.hamcrest
- hamcrest-all
- 1.1
- test
-
-
-
- junit
- junit
- test
-
-
-
- joda-time
- joda-time
- 1.6
- test
-
+
+ com.mysema.querydsl
+ querydsl-mongodb
+ 2.1.1
+ true
+
+
+ com.google.code.morphia
+ morphia
+
+
+
-
-
-
-
- com.springsource.bundlor
- com.springsource.bundlor.maven
-
-
-
- com.mysema.maven
- maven-apt-plugin
- 1.0
-
-
- generate-test-sources
-
- test-process
-
-
- target/generated-sources/test-annotations
- org.springframework.data.document.mongodb.repository.MongoAnnotationProcessor
-
-
-
-
-
-
-
-
-
- querydsl
- Mysema QueryDsl
- http://source.mysema.com/maven2/releases
-
- false
-
-
-
+
+ com.mysema.querydsl
+ querydsl-apt
+ 2.1.1
+ provided
+
+
+
+ javax.annotation
+ jsr250-api
+ true
+
+
+
+ javax.annotation
+ jsr250-api
+ true
+
+
+
+
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ 1.1
+ test
+
+
+
+ junit
+ junit
+ test
+
+
+
+ joda-time
+ joda-time
+ 1.6
+ test
+
+
+
+ org.slf4j
+ slf4j-api
+ test
+
+
+ org.slf4j
+ jcl-over-slf4j
+ test
+
+
+ org.slf4j
+ slf4j-log4j12
+ test
+
+
+ log4j
+ log4j
+ test
+
+
+
+
+
+
+ com.springsource.bundlor
+ com.springsource.bundlor.maven
+
+
+
+ com.mysema.maven
+ maven-apt-plugin
+ 1.0
+
+
+ generate-test-sources
+
+ test-process
+
+
+ target/generated-sources/test-annotations
+ org.springframework.data.document.mongodb.repository.MongoAnnotationProcessor
+
+
+
+
+
+
+
+
+
+ querydsl
+ Mysema QueryDsl
+ http://source.mysema.com/maven2/releases
+
+ false
+
+
+
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java
index fedaee693..7c5159054 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java
@@ -57,7 +57,6 @@ import org.springframework.data.document.mongodb.convert.MappingMongoConverter;
import org.springframework.data.document.mongodb.convert.MongoConverter;
import org.springframework.data.document.mongodb.convert.SimpleMongoConverter;
import org.springframework.data.document.mongodb.index.IndexDefinition;
-import org.springframework.data.document.mongodb.mapping.Document;
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity;
import org.springframework.data.document.mongodb.mapping.event.AfterConvertEvent;
import org.springframework.data.document.mongodb.mapping.event.AfterLoadEvent;
@@ -67,7 +66,9 @@ import org.springframework.data.document.mongodb.mapping.event.BeforeSaveEvent;
import org.springframework.data.document.mongodb.mapping.event.MongoMappingEvent;
import org.springframework.data.document.mongodb.query.Query;
import org.springframework.data.document.mongodb.query.Update;
+import org.springframework.data.mapping.context.MappingContextAware;
import org.springframework.data.mapping.model.MappingContext;
+import org.springframework.data.mapping.model.PersistentEntity;
import org.springframework.jca.cci.core.ConnectionCallback;
import org.springframework.util.Assert;
@@ -79,7 +80,7 @@ import org.springframework.util.Assert;
* @author Mark Pollack
* @author Oliver Gierke
*/
-public class MongoTemplate implements InitializingBean, MongoOperations, ApplicationContextAware, ApplicationEventPublisherAware {
+public class MongoTemplate implements InitializingBean, MongoOperations, ApplicationContextAware, ApplicationEventPublisherAware, MappingContextAware {
private static final Log LOGGER = LogFactory.getLog(MongoTemplate.class);
@@ -98,6 +99,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
private WriteResultChecking writeResultChecking = WriteResultChecking.NONE;
private MongoConverter mongoConverter;
+ private MappingContext mappingContext;
private final Mongo mongo;
private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
@@ -202,6 +204,10 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
this.eventPublisher = applicationEventPublisher;
}
+ public void setMappingContext(MappingContext mappingContext) {
+ this.mappingContext = mappingContext;
+ }
+
/**
* Sets the username to use to connect to the Mongo database
*
@@ -508,19 +514,11 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
// Find methods that take a Query to express the query and that return a List of objects.
public List find(Query query, Class targetClass) {
- String collName = getEntityCollection(targetClass);
- if (null == collName) {
- collName = getRequiredDefaultCollectionName();
- }
- return find(collName, query, targetClass);
+ return find(getEntityCollection(targetClass), query, targetClass);
}
public List find(Query query, Class targetClass, MongoReader reader) {
- String collName = getEntityCollection(targetClass);
- if (null == collName) {
- collName = getRequiredDefaultCollectionName();
- }
- return find(collName, query, targetClass, reader);
+ return find(getEntityCollection(targetClass), query, targetClass, reader);
}
public List find(String collectionName, final Query query, Class targetClass) {
@@ -585,11 +583,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
* @see org.springframework.data.document.mongodb.MongoOperations#insert(java.lang.Object)
*/
public void insert(Object objectToSave) {
- String collName = getEntityCollection(objectToSave);
- if (null == collName) {
- collName = getRequiredDefaultCollectionName();
- }
- insert(collName, objectToSave);
+ insert(getEntityCollection(objectToSave), objectToSave);
}
/* (non-Javadoc)
@@ -603,11 +597,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
* @see org.springframework.data.document.mongodb.MongoOperations#insert(T, org.springframework.data.document.mongodb.MongoWriter)
*/
public void insert(T objectToSave, MongoWriter writer) {
- String collName = getEntityCollection(objectToSave);
- if (null == collName) {
- collName = getDefaultCollectionName();
- }
- insert(collName, objectToSave, writer);
+ insert(getEntityCollection(objectToSave), objectToSave, writer);
}
/* (non-Javadoc)
@@ -1103,7 +1093,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
return name;
}
- private String getEntityCollection(Object obj) {
+ private String getEntityCollection(T obj) {
if (null != obj) {
return getEntityCollection(obj.getClass());
}
@@ -1111,26 +1101,15 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
return null;
}
- private String getEntityCollection(Class> clazz) {
- if (mongoConverter instanceof MappingMongoConverter) {
- MappingContext ctx = ((MappingMongoConverter) mongoConverter).getMappingContext();
- MongoPersistentEntity entity = (MongoPersistentEntity) ctx.getPersistentEntity(clazz);
- if (null != entity) {
- return entity.getCollection();
+ private String getEntityCollection(Class clazz) {
+ if (null != mappingContext) {
+ PersistentEntity entity = mappingContext.getPersistentEntity(clazz);
+ if (null != entity && entity instanceof MongoPersistentEntity) {
+ return ((MongoPersistentEntity) entity).getCollection();
}
}
- // Entity hasn't yet been added, try and figure it out anyway
- if (clazz.isAnnotationPresent(Document.class)) {
- Document doc = clazz.getAnnotation(Document.class);
- if (!"".equals(doc.collection())) {
- return doc.collection();
- }
-
- // Default to simple name
- return clazz.getSimpleName().toLowerCase();
- }
-
- return null;
+ // Otherwise, return the default for this template.
+ return getRequiredDefaultCollectionName();
}
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoMappingConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoMappingConverterParser.java
index 5dcc67b56..4d44f1181 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoMappingConverterParser.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoMappingConverterParser.java
@@ -33,8 +33,9 @@ import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.document.mongodb.convert.MappingMongoConverter;
import org.springframework.data.document.mongodb.mapping.Document;
-import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator;
import org.springframework.data.document.mongodb.mapping.MongoMappingContext;
+import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator;
+import org.springframework.data.mapping.context.MappingContextAwareBeanPostProcessor;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -44,77 +45,83 @@ import org.w3c.dom.Element;
*/
public class MongoMappingConverterParser extends AbstractBeanDefinitionParser {
- static final String MAPPING_CONTEXT = "mappingContext";
- private static final String INDEX_HELPER = "indexCreationHelper";
- private static final String TEMPLATE = "mongoTemplate";
- private static final String BASE_PACKAGE = "base-package";
+ static final String MAPPING_CONTEXT = "mappingContext";
- @Override
- protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
- String id = super.resolveId(element, definition, parserContext);
- return StringUtils.hasText(id) ? id : "mappingConverter";
- }
+ private static final String INDEX_HELPER = "indexCreationHelper";
+ private static final String TEMPLATE = "mongoTemplate";
+ private static final String POST_PROCESSOR = "mappingContextAwareBeanPostProcessor";
- @Override
- protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
- BeanDefinitionRegistry registry = parserContext.getRegistry();
+ private static final String BASE_PACKAGE = "base-package";
- String ctxRef = element.getAttribute("mapping-context-ref");
- if (!StringUtils.hasText(ctxRef)) {
- BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class);
-
- Set classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
- if (classesToAdd != null) {
- mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
- }
-
- registry.registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
- ctxRef = MAPPING_CONTEXT;
- }
+ @Override
+ protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
+ String id = super.resolveId(element, definition, parserContext);
+ return StringUtils.hasText(id) ? id : "mappingConverter";
+ }
- BeanDefinitionBuilder converterBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingMongoConverter.class);
- converterBuilder.addPropertyReference("mappingContext", ctxRef);
+ @Override
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+ BeanDefinitionRegistry registry = parserContext.getRegistry();
- String autowire = element.getAttribute("autowire");
- if (StringUtils.hasText(autowire)) {
- converterBuilder.addPropertyValue("autowirePersistentBeans", Boolean.parseBoolean(autowire));
- }
+ String ctxRef = element.getAttribute("mapping-context-ref");
+ if (!StringUtils.hasText(ctxRef)) {
+ BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class);
- // Need a reference to a Mongo instance
- String mongoRef = element.getAttribute("mongo-ref");
- converterBuilder.addPropertyReference("mongo", StringUtils.hasText(mongoRef) ? mongoRef : "mongo");
+ Set classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
+ if (classesToAdd != null) {
+ mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
+ }
- try {
- registry.getBeanDefinition(INDEX_HELPER);
- } catch (NoSuchBeanDefinitionException ignored) {
- String templateRef = element.getAttribute("mongo-template-ref");
- BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
- indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
- indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(StringUtils.hasText(templateRef) ? templateRef : TEMPLATE));
- registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
- }
+ registry.registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
+ ctxRef = MAPPING_CONTEXT;
+ }
- return converterBuilder.getBeanDefinition();
- }
-
-
- public Set getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
-
- String basePackage = element.getAttribute(BASE_PACKAGE);
-
- if (!StringUtils.hasText(basePackage)) {
- return null;
- }
-
- ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false);
- componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
- componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
-
- Set classes = new ManagedSet();
- for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
- classes.add(candidate.getBeanClassName());
- }
-
- return classes;
- }
+ try {
+ registry.getBeanDefinition(POST_PROCESSOR);
+ } catch (NoSuchBeanDefinitionException ignored) {
+ BeanDefinitionBuilder postProcBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingContextAwareBeanPostProcessor.class);
+ postProcBuilder.addPropertyValue("mappingContextBeanName", ctxRef);
+ registry.registerBeanDefinition(POST_PROCESSOR, postProcBuilder.getBeanDefinition());
+ }
+
+ BeanDefinitionBuilder converterBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingMongoConverter.class);
+ converterBuilder.addPropertyReference("mappingContext", ctxRef);
+
+ // Need a reference to a Mongo instance
+ String mongoRef = element.getAttribute("mongo-ref");
+ converterBuilder.addPropertyReference("mongo", StringUtils.hasText(mongoRef) ? mongoRef : "mongo");
+
+ try {
+ registry.getBeanDefinition(INDEX_HELPER);
+ } catch (NoSuchBeanDefinitionException ignored) {
+ String templateRef = element.getAttribute("mongo-template-ref");
+ BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
+ indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
+ indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(StringUtils.hasText(templateRef) ? templateRef : TEMPLATE));
+ registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
+ }
+
+ return converterBuilder.getBeanDefinition();
+ }
+
+
+ public Set getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
+
+ String basePackage = element.getAttribute(BASE_PACKAGE);
+
+ if (!StringUtils.hasText(basePackage)) {
+ return null;
+ }
+
+ ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false);
+ componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
+ componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
+
+ Set classes = new ManagedSet();
+ for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
+ classes.add(candidate.getBeanClassName());
+ }
+
+ return classes;
+ }
}
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 2668d6957..84ae4ca3f 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
@@ -70,617 +70,597 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
*/
public class MappingMongoConverter implements MongoConverter, ApplicationContextAware, InitializingBean {
- private static final String CUSTOM_TYPE_KEY = "_class";
- @SuppressWarnings({"unchecked"})
- 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 final GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
- protected final Map, Class>> customTypeMapping = new HashMap, Class>>();
- protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
- protected MappingContext mappingContext;
- protected ApplicationContext applicationContext;
- protected boolean autowirePersistentBeans = false;
- protected boolean useFieldAccessOnly = true;
- protected Mongo mongo;
- protected String defaultDatabase;
-
- public MappingMongoConverter() {
- initializeConverters();
- }
-
- public MappingMongoConverter(MappingContext mappingContext) {
- this.mappingContext = mappingContext;
- initializeConverters();
- }
-
- public MappingMongoConverter(MappingContext mappingContext, List> converters) {
- 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;
- }
-
- public void setMappingContext(MappingContext mappingContext) {
- this.mappingContext = mappingContext;
- }
-
- public Mongo getMongo() {
- return mongo;
- }
-
- public void setMongo(Mongo mongo) {
- this.mongo = mongo;
- }
-
- public String getDefaultDatabase() {
- return defaultDatabase;
- }
-
- public void setDefaultDatabase(String defaultDatabase) {
- this.defaultDatabase = defaultDatabase;
- }
-
- public boolean isAutowirePersistentBeans() {
- return autowirePersistentBeans;
- }
-
- public void setAutowirePersistentBeans(boolean autowirePersistentBeans) {
- this.autowirePersistentBeans = autowirePersistentBeans;
- }
-
- public boolean isUseFieldAccessOnly() {
- return useFieldAccessOnly;
- }
-
- public void setUseFieldAccessOnly(boolean useFieldAccessOnly) {
- this.useFieldAccessOnly = useFieldAccessOnly;
- }
-
- public T convertObjectId(ObjectId id, Class targetType) {
- return conversionService.convert(id, targetType);
- }
-
- public ObjectId convertObjectId(Object id) {
- return conversionService.convert(id, ObjectId.class);
- }
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- public S read(Class clazz, final DBObject dbo) {
- if (null == dbo) {
- return null;
- }
-
- if ((clazz.isArray()
- || (clazz.isAssignableFrom(Collection.class)
- || clazz.isAssignableFrom(List.class)))
- && dbo instanceof BasicDBList) {
- List l = new ArrayList();
- BasicDBList dbList = (BasicDBList) dbo;
- for (Object o : dbList) {
- if (o instanceof DBObject) {
- Object newObj = read(clazz.getComponentType(), (DBObject) o);
- if (newObj.getClass().isAssignableFrom(clazz.getComponentType())) {
- l.add(newObj);
- } else {
- l.add(conversionService.convert(newObj, clazz.getComponentType()));
- }
- } else {
- l.add(o);
- }
- }
- return conversionService.convert(l, clazz);
- }
-
- // Retrieve persistent entity info
- PersistentEntity persistentEntity = mappingContext.getPersistentEntity(clazz);
- if (persistentEntity == null) {
- persistentEntity = mappingContext.addPersistentEntity(clazz);
- }
-
- return read(persistentEntity, dbo);
- }
-
- private S read(PersistentEntity entity, final DBObject dbo) {
-
- final StandardEvaluationContext spelCtx = new StandardEvaluationContext();
- if (null != applicationContext) {
- spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext));
- }
- String[] keySet = dbo.keySet().toArray(new String[]{});
- for (String key : keySet) {
- spelCtx.setVariable(key, dbo.get(key));
- }
-
- final List ctorParamNames = new ArrayList();
- final S instance = MappingBeanHelper.constructInstance(entity, new PreferredConstructor.ParameterValueProvider() {
- public Object getParameterValue(PreferredConstructor.Parameter parameter) {
- String name = parameter.getName();
- Class> type = parameter.getType();
- Object obj = dbo.get(name);
- if (obj instanceof DBRef) {
- ctorParamNames.add(name);
- return read(type, ((DBRef) obj).fetch());
- } else if (obj instanceof DBObject) {
- ctorParamNames.add(name);
- return read(type, ((DBObject) obj));
- } else if (null != obj && obj.getClass().isAssignableFrom(type)) {
- ctorParamNames.add(name);
- return obj;
- } else if (null != obj) {
- ctorParamNames.add(name);
- return conversionService.convert(obj, type);
- }
-
- return null;
- }
- }, spelCtx);
-
- // Set the ID
- PersistentProperty idProperty = entity.getIdProperty();
- if (dbo.containsField("_id") && null != idProperty) {
- Object idObj = dbo.get("_id");
- try {
- MappingBeanHelper.setProperty(instance, idProperty, idObj, useFieldAccessOnly);
- } catch (IllegalAccessException e) {
- throw new MappingException(e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new MappingException(e.getMessage(), e);
- }
- }
-
- // Set properties not already set in the constructor
- entity.doWithProperties(new PropertyHandler() {
- public void doWithPersistentProperty(PersistentProperty prop) {
- if (ctorParamNames.contains(prop.getName())) {
- return;
- }
-
- Object obj = getValueInternal(prop, dbo, spelCtx, prop.getValueAnnotation());
- try {
- MappingBeanHelper.setProperty(instance, prop, obj, useFieldAccessOnly);
- } catch (IllegalAccessException e) {
- throw new MappingException(e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new MappingException(e.getMessage(), e);
- }
- }
- });
-
- // Handle associations
- entity.doWithAssociations(new AssociationHandler() {
- public void doWithAssociation(Association association) {
- PersistentProperty inverseProp = association.getInverse();
- Object obj = getValueInternal(inverseProp, dbo, spelCtx, inverseProp.getValueAnnotation());
- try {
- MappingBeanHelper.setProperty(instance, inverseProp, obj);
- } catch (IllegalAccessException e) {
- throw new MappingException(e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new MappingException(e.getMessage(), e);
- }
- }
- });
-
- if (null != applicationContext && autowirePersistentBeans) {
- applicationContext.getAutowireCapableBeanFactory().autowireBean(instance);
- }
- if (instance instanceof InitializingBean) {
- try {
- ((InitializingBean) instance).afterPropertiesSet();
- } catch (Exception e) {
- throw new MappingException(e.getMessage(), e);
- }
- }
-
- return instance;
- }
-
- public void write(final Object obj, final DBObject dbo) {
- if (null == obj) {
- return;
- }
-
- PersistentEntity> entity = mappingContext.getPersistentEntity(obj.getClass());
- write(obj, dbo, entity);
- }
-
- protected void write(final Object obj, final DBObject dbo, PersistentEntity> entity) {
-
- if (obj == null) {
- return;
- }
-
- if (null == entity) {
- // Must not have explictly added this entity yet
- entity = mappingContext.addPersistentEntity(obj.getClass());
- if (null == entity) {
- // We can't map this entity for some reason
- throw new MappingException("Unable to map entity " + obj);
- }
- }
-
- // Write the ID
- final PersistentProperty idProperty = entity.getIdProperty();
- if (!dbo.containsField("_id") && null != idProperty) {
- Object idObj = null;
- try {
- idObj = MappingBeanHelper.getProperty(obj, idProperty, ObjectId.class, useFieldAccessOnly);
- } catch (IllegalAccessException e) {
- throw new MappingException(e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new MappingException(e.getMessage(), e);
- }
-
- if (null != idObj) {
- dbo.put("_id", idObj);
- }
- }
-
- // Write the properties
- entity.doWithProperties(new PropertyHandler() {
- public void doWithPersistentProperty(PersistentProperty prop) {
- String name = prop.getName();
- Class> type = prop.getType();
- Object propertyObj = null;
- try {
- propertyObj = MappingBeanHelper.getProperty(obj, prop, type, useFieldAccessOnly);
- } catch (IllegalAccessException e) {
- throw new MappingException(e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new MappingException(e.getMessage(), e);
- }
- if (null != propertyObj) {
- if (!MappingBeanHelper.isSimpleType(propertyObj.getClass())) {
- writePropertyInternal(prop, propertyObj, dbo);
- } else {
- dbo.put(name, propertyObj);
- }
- }
- }
- });
-
- entity.doWithAssociations(new AssociationHandler() {
- public void doWithAssociation(Association association) {
- PersistentProperty inverseProp = association.getInverse();
- Class> type = inverseProp.getType();
- Object propertyObj = null;
- try {
- propertyObj = MappingBeanHelper.getProperty(obj, inverseProp, type, useFieldAccessOnly);
- } catch (IllegalAccessException e) {
- throw new MappingException(e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new MappingException(e.getMessage(), e);
- }
- if (null != propertyObj) {
- writePropertyInternal(inverseProp, propertyObj, dbo);
- }
- }
- });
- }
-
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
- }
-
- /**
- * Registers converters for {@link ObjectId} handling, removes plain {@link #toString()} converter and promotes the
- * configured {@link ConversionService} to {@link MappingBeanHelper}.
- */
- protected void initializeConverters() {
-
- this.conversionService.removeConvertible(Object.class, String.class);
-
- if (!conversionService.canConvert(ObjectId.class, String.class)) {
- conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
- conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
- }
- if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
- conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
- conversionService.addConverter(BigIntegerToIdConverter.INSTANCE);
- }
-
- MappingBeanHelper.setConversionService(conversionService);
- }
-
- @SuppressWarnings({"unchecked"})
- protected void writePropertyInternal(PersistentProperty prop, Object obj, DBObject dbo) {
- org.springframework.data.document.mongodb.mapping.DBRef dbref = prop.getField()
- .getAnnotation(org.springframework.data.document.mongodb.mapping.DBRef.class);
-
- String name = prop.getName();
- Class> type = prop.getType();
- if (prop.isCollection()) {
- BasicDBList dbList = new BasicDBList();
- Collection> coll;
- if (type.isArray()) {
- coll = Arrays.asList((Object[]) obj);
- } else {
- coll = (Collection>) obj;
- }
- for (Object propObjItem : coll) {
- if (null != dbref) {
- DBRef dbRef = createDBRef(propObjItem, dbref);
- dbList.add(dbRef);
- } else if (type.isArray() && MappingBeanHelper.isSimpleType(type.getComponentType())) {
- dbList.add(propObjItem);
- } else {
- BasicDBObject propDbObj = new BasicDBObject();
- write(propObjItem, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
- dbList.add(propDbObj);
- }
- }
- dbo.put(name, dbList);
- return;
- }
-
- if (null != obj && obj instanceof Map) {
- BasicDBObject mapDbObj = new BasicDBObject();
- writeMapInternal((Map