Tweaks to index creation handling.
Renamed MappingConfigurationHelper to MongoPersistentEntityIndexCreator as this is the purpose of the class. Refactored it not be ApplicationContextAware, Initializing bean but rather simply use the injected MongoMappingContext and MongoTemplate to trigger index creation. Added base-package parsing for entities annotated with @Persistent and @Document to be added to the MappingContext. Moved createPersistentEntity and createPersistentProperty methods into MongoMappingContext.
This commit is contained in:
@@ -16,26 +16,32 @@
|
|||||||
|
|
||||||
package org.springframework.data.document.mongodb.config;
|
package org.springframework.data.document.mongodb.config;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.beans.factory.support.ManagedSet;
|
||||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
|
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.convert.MappingMongoConverter;
|
||||||
import org.springframework.data.document.mongodb.mapping.MappingConfigurationHelper;
|
import org.springframework.data.document.mongodb.mapping.Document;
|
||||||
|
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator;
|
||||||
import org.springframework.data.document.mongodb.mapping.MongoMappingConfigurationBuilder;
|
import org.springframework.data.document.mongodb.mapping.MongoMappingConfigurationBuilder;
|
||||||
import org.springframework.data.document.mongodb.mapping.MongoMappingContext;
|
import org.springframework.data.document.mongodb.mapping.MongoMappingContext;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by IntelliJ IDEA.
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
* User: jbrisbin
|
* @author Oliver Gierke
|
||||||
* Date: 2/28/11
|
|
||||||
* Time: 9:26 AM
|
|
||||||
* To change this template use File | Settings | File Templates.
|
|
||||||
*/
|
*/
|
||||||
public class MongoMappingConverterParser extends AbstractBeanDefinitionParser {
|
public class MongoMappingConverterParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
@@ -65,6 +71,12 @@ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||||
if (null == ctxRef || "".equals(ctxRef)) {
|
if (null == ctxRef || "".equals(ctxRef)) {
|
||||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class);
|
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class);
|
||||||
|
|
||||||
|
Set<String> classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
|
||||||
|
if (classesToAdd != null) {
|
||||||
|
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
mappingContextBuilder.addPropertyReference("mappingConfigurationBuilder", builderRef);
|
mappingContextBuilder.addPropertyReference("mappingConfigurationBuilder", builderRef);
|
||||||
registry.registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
|
registry.registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
|
||||||
ctxRef = MAPPING_CONTEXT;
|
ctxRef = MAPPING_CONTEXT;
|
||||||
@@ -92,7 +104,7 @@ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
if (null == templateRef || "".equals(templateRef)) {
|
if (null == templateRef || "".equals(templateRef)) {
|
||||||
templateRef = TEMPLATE;
|
templateRef = TEMPLATE;
|
||||||
}
|
}
|
||||||
BeanDefinitionBuilder mappingConfigHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingConfigurationHelper.class);
|
BeanDefinitionBuilder mappingConfigHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||||
mappingConfigHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
|
mappingConfigHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
|
||||||
mappingConfigHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(templateRef));
|
mappingConfigHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(templateRef));
|
||||||
registry.registerBeanDefinition(MAPPING_CONFIGURATION_HELPER, mappingConfigHelperBuilder.getBeanDefinition());
|
registry.registerBeanDefinition(MAPPING_CONFIGURATION_HELPER, mappingConfigHelperBuilder.getBeanDefinition());
|
||||||
@@ -100,5 +112,25 @@ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
|
|
||||||
return converterBuilder.getBeanDefinition();
|
return converterBuilder.getBeanDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<String> 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<String> classes = new ManagedSet<String>();
|
||||||
|
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||||
|
classes.add(candidate.getBeanClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ import org.bson.types.ObjectId;
|
|||||||
import org.springframework.data.mapping.BasicMappingConfigurationBuilder;
|
import org.springframework.data.mapping.BasicMappingConfigurationBuilder;
|
||||||
import org.springframework.data.mapping.MappingBeanHelper;
|
import org.springframework.data.mapping.MappingBeanHelper;
|
||||||
import org.springframework.data.mapping.model.MappingConfigurationException;
|
import org.springframework.data.mapping.model.MappingConfigurationException;
|
||||||
import org.springframework.data.mapping.model.MappingContext;
|
|
||||||
import org.springframework.data.mapping.model.PersistentEntity;
|
|
||||||
import org.springframework.data.mapping.model.PersistentProperty;
|
|
||||||
import org.springframework.data.util.TypeInformation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
@@ -47,19 +43,6 @@ public class MongoMappingConfigurationBuilder extends BasicMappingConfigurationB
|
|||||||
simpleTypes.add(CodeWScope.class);
|
simpleTypes.add(CodeWScope.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PersistentProperty createPersistentProperty(Field field,
|
|
||||||
PropertyDescriptor descriptor,
|
|
||||||
TypeInformation information) throws MappingConfigurationException {
|
|
||||||
return new MongoPersistentProperty(field, descriptor, information);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> PersistentEntity<T> createPersistentEntity(TypeInformation typeInformation,
|
|
||||||
MappingContext mappingContext) throws MappingConfigurationException {
|
|
||||||
return new MongoPersistentEntity<T>(mappingContext, typeInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAssociation(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException {
|
public boolean isAssociation(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException {
|
||||||
if (field.isAnnotationPresent(DBRef.class)) {
|
if (field.isAnnotationPresent(DBRef.class)) {
|
||||||
|
|||||||
@@ -16,28 +16,39 @@
|
|||||||
|
|
||||||
package org.springframework.data.document.mongodb.mapping;
|
package org.springframework.data.document.mongodb.mapping;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.util.Set;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Collection;
|
||||||
import org.springframework.data.mapping.BasicMappingContext;
|
import org.springframework.data.mapping.BasicMappingContext;
|
||||||
|
import org.springframework.data.mapping.model.MappingConfigurationException;
|
||||||
|
import org.springframework.data.mapping.model.MappingContext;
|
||||||
|
import org.springframework.data.mapping.model.PersistentEntity;
|
||||||
|
import org.springframework.data.mapping.model.PersistentProperty;
|
||||||
|
import org.springframework.data.util.TypeInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoMappingContext extends BasicMappingContext {
|
public class MongoMappingContext extends BasicMappingContext {
|
||||||
|
|
||||||
protected Set<String> initialEntitySet = new HashSet<String>();
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mapping.BasicMappingContext#getPersistentEntities()
|
||||||
public MongoMappingContext() {
|
*/
|
||||||
builder = new MongoMappingConfigurationBuilder();
|
@Override
|
||||||
|
public Collection<MongoPersistentEntity<?>> getPersistentEntities() {
|
||||||
|
return (Collection<MongoPersistentEntity<?>>) super.getPersistentEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getInitialEntitySet() {
|
@Override
|
||||||
return initialEntitySet;
|
public PersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||||
|
TypeInformation information) throws MappingConfigurationException {
|
||||||
|
return new MongoPersistentProperty(field, descriptor, information);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInitialEntitySet(Set<String> initialEntitySet) {
|
@Override
|
||||||
this.initialEntitySet = initialEntitySet;
|
public <T> PersistentEntity<T> createPersistentEntity(TypeInformation typeInformation, MappingContext mappingContext)
|
||||||
|
throws MappingConfigurationException {
|
||||||
|
return new MongoPersistentEntity<T>(mappingContext, typeInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.google.code.morphia.mapping.MappingException;
|
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
@@ -31,11 +30,6 @@ import com.mongodb.MongoException;
|
|||||||
import com.mongodb.util.JSON;
|
import com.mongodb.util.JSON;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
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.ApplicationListener;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.document.mongodb.CollectionCallback;
|
import org.springframework.data.document.mongodb.CollectionCallback;
|
||||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||||
@@ -44,69 +38,37 @@ import org.springframework.data.document.mongodb.index.CompoundIndexes;
|
|||||||
import org.springframework.data.document.mongodb.index.IndexDirection;
|
import org.springframework.data.document.mongodb.index.IndexDirection;
|
||||||
import org.springframework.data.document.mongodb.index.Indexed;
|
import org.springframework.data.document.mongodb.index.Indexed;
|
||||||
import org.springframework.data.mapping.PropertyHandler;
|
import org.springframework.data.mapping.PropertyHandler;
|
||||||
import org.springframework.data.mapping.event.MappingContextEvent;
|
|
||||||
import org.springframework.data.mapping.model.PersistentEntity;
|
|
||||||
import org.springframework.data.mapping.model.PersistentProperty;
|
import org.springframework.data.mapping.model.PersistentProperty;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Component that inspects {@link MongoPersistentEntity} instances contained in the given {@link MongoMappingContext}
|
||||||
|
* for indexing metadata and ensures the indexes to be available.
|
||||||
|
*
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MappingConfigurationHelper implements ApplicationListener<MappingContextEvent>, ApplicationContextAware, InitializingBean {
|
public class MongoPersistentEntityIndexCreator {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MappingConfigurationHelper.class);
|
private static final Logger log = LoggerFactory.getLogger(MongoPersistentEntityIndexCreator.class);
|
||||||
|
|
||||||
private Map<String, CompoundIndex> compoundIndexes = new HashMap<String, CompoundIndex>();
|
private Map<String, CompoundIndex> compoundIndexes = new HashMap<String, CompoundIndex>();
|
||||||
private Map<String, Indexed> fieldIndexes = new HashMap<String, Indexed>();
|
private Map<String, Indexed> fieldIndexes = new HashMap<String, Indexed>();
|
||||||
private Set<Class<?>> classesSeen = Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>());
|
private Set<Class<?>> classesSeen = Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>());
|
||||||
private ApplicationContext applicationContext;
|
|
||||||
private MongoMappingContext mappingContext;
|
private final MongoTemplate mongoTemplate;
|
||||||
private MongoTemplate mongoTemplate;
|
|
||||||
|
|
||||||
public MappingConfigurationHelper(MongoMappingContext mappingContext, MongoTemplate mongoTemplate) {
|
public MongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoTemplate mongoTemplate) {
|
||||||
this.mappingContext = mappingContext;
|
|
||||||
|
Assert.notNull(mongoTemplate);
|
||||||
|
Assert.notNull(mappingContext);
|
||||||
this.mongoTemplate = mongoTemplate;
|
this.mongoTemplate = mongoTemplate;
|
||||||
}
|
|
||||||
|
for (MongoPersistentEntity<?> entity : mappingContext.getPersistentEntities()) {
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
checkForIndexes(entity);
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onApplicationEvent(MappingContextEvent event) {
|
|
||||||
PersistentEntity<?> entity = event.getPersistentEntity();
|
|
||||||
if (entity instanceof MongoPersistentEntity) {
|
|
||||||
checkForIndexes((MongoPersistentEntity<?>) entity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
for (String className : mappingContext.getInitialEntitySet()) {
|
|
||||||
try {
|
|
||||||
Class<?> clazz = Class.forName(className);
|
|
||||||
if (null == mappingContext.getPersistentEntity(clazz)) {
|
|
||||||
mappingContext.addPersistentEntity(clazz);
|
|
||||||
}
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new MappingException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoMappingContext getMappingContext() {
|
|
||||||
return mappingContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMappingContext(MongoMappingContext mappingContext) {
|
|
||||||
this.mappingContext = mappingContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoTemplate getMongoTemplate() {
|
|
||||||
return mongoTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMongoTemplate(MongoTemplate mongoTemplate) {
|
|
||||||
this.mongoTemplate = mongoTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkForIndexes(MongoPersistentEntity<?> entity) {
|
protected void checkForIndexes(MongoPersistentEntity<?> entity) {
|
||||||
Class<?> type = entity.getType();
|
Class<?> type = entity.getType();
|
||||||
if (!classesSeen.contains(type)) {
|
if (!classesSeen.contains(type)) {
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<property name="repositoryInterface" value="org.springframework.data.document.mongodb.repository.PersonRepository"/>
|
<property name="repositoryInterface" value="org.springframework.data.document.mongodb.repository.PersonRepository"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="mappingContext" class="org.springframework.data.mapping.BasicMappingContext">
|
<bean id="mappingContext" class="org.springframework.data.document.mongodb.mapping.MongoMappingContext">
|
||||||
<property name="mappingConfigurationBuilder">
|
<property name="mappingConfigurationBuilder">
|
||||||
<bean class="org.springframework.data.document.mongodb.mapping.MongoMappingConfigurationBuilder" />
|
<bean class="org.springframework.data.document.mongodb.mapping.MongoMappingConfigurationBuilder" />
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
Reference in New Issue
Block a user