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 93d3c7a2b..e82979670 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 @@ -16,26 +16,32 @@ package org.springframework.data.document.mongodb.config; +import java.util.Set; + import org.springframework.beans.factory.BeanDefinitionStoreException; 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.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; 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.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.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.MongoMappingContext; +import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** - * Created by IntelliJ IDEA. - * User: jbrisbin - * Date: 2/28/11 - * Time: 9:26 AM - * To change this template use File | Settings | File Templates. + * @author Jon Brisbin + * @author Oliver Gierke */ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser { @@ -65,6 +71,12 @@ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser { String ctxRef = element.getAttribute("mapping-context-ref"); if (null == ctxRef || "".equals(ctxRef)) { BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class); + + Set classesToAdd = getInititalEntityClasses(element, mappingContextBuilder); + if (classesToAdd != null) { + mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd); + } + mappingContextBuilder.addPropertyReference("mappingConfigurationBuilder", builderRef); registry.registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition()); ctxRef = MAPPING_CONTEXT; @@ -92,7 +104,7 @@ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser { if (null == templateRef || "".equals(templateRef)) { templateRef = TEMPLATE; } - BeanDefinitionBuilder mappingConfigHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingConfigurationHelper.class); + BeanDefinitionBuilder mappingConfigHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class); mappingConfigHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef)); mappingConfigHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(templateRef)); registry.registerBeanDefinition(MAPPING_CONFIGURATION_HELPER, mappingConfigHelperBuilder.getBeanDefinition()); @@ -100,5 +112,25 @@ public class MongoMappingConverterParser extends AbstractBeanDefinitionParser { 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/mapping/MongoMappingConfigurationBuilder.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java index c75f4794c..6b94eda13 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java @@ -25,10 +25,6 @@ import org.bson.types.ObjectId; import org.springframework.data.mapping.BasicMappingConfigurationBuilder; import org.springframework.data.mapping.MappingBeanHelper; 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 @@ -47,19 +43,6 @@ public class MongoMappingConfigurationBuilder extends BasicMappingConfigurationB simpleTypes.add(CodeWScope.class); } - @Override - public PersistentProperty createPersistentProperty(Field field, - PropertyDescriptor descriptor, - TypeInformation information) throws MappingConfigurationException { - return new MongoPersistentProperty(field, descriptor, information); - } - - @Override - public PersistentEntity createPersistentEntity(TypeInformation typeInformation, - MappingContext mappingContext) throws MappingConfigurationException { - return new MongoPersistentEntity(mappingContext, typeInformation); - } - @Override public boolean isAssociation(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException { if (field.isAnnotationPresent(DBRef.class)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingContext.java index dabeca864..11752d799 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingContext.java @@ -16,28 +16,39 @@ package org.springframework.data.document.mongodb.mapping; -import java.util.HashSet; -import java.util.Set; - +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.util.Collection; 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 + * @author Oliver Gierke */ public class MongoMappingContext extends BasicMappingContext { - protected Set initialEntitySet = new HashSet(); - - public MongoMappingContext() { - builder = new MongoMappingConfigurationBuilder(); + /* (non-Javadoc) + * @see org.springframework.data.mapping.BasicMappingContext#getPersistentEntities() + */ + @Override + public Collection> getPersistentEntities() { + return (Collection>) super.getPersistentEntities(); } - public Set getInitialEntitySet() { - return initialEntitySet; + @Override + public PersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, + TypeInformation information) throws MappingConfigurationException { + return new MongoPersistentProperty(field, descriptor, information); } - public void setInitialEntitySet(Set initialEntitySet) { - this.initialEntitySet = initialEntitySet; + @Override + public PersistentEntity createPersistentEntity(TypeInformation typeInformation, MappingContext mappingContext) + throws MappingConfigurationException { + return new MongoPersistentEntity(mappingContext, typeInformation); } - } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java similarity index 71% rename from spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java rename to spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java index c347d2b63..234fb9539 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MappingConfigurationHelper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import com.google.code.morphia.mapping.MappingException; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBObject; @@ -31,11 +30,6 @@ import com.mongodb.MongoException; import com.mongodb.util.JSON; import org.slf4j.Logger; 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.data.document.mongodb.CollectionCallback; 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.Indexed; 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.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 + * @author Oliver Gierke */ -public class MappingConfigurationHelper implements ApplicationListener, 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 compoundIndexes = new HashMap(); private Map fieldIndexes = new HashMap(); private Set> classesSeen = Collections.newSetFromMap(new ConcurrentHashMap, Boolean>()); - private ApplicationContext applicationContext; - private MongoMappingContext mappingContext; - private MongoTemplate mongoTemplate; + + private final MongoTemplate mongoTemplate; - public MappingConfigurationHelper(MongoMappingContext mappingContext, MongoTemplate mongoTemplate) { - this.mappingContext = mappingContext; + public MongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoTemplate mongoTemplate) { + + Assert.notNull(mongoTemplate); + Assert.notNull(mappingContext); this.mongoTemplate = mongoTemplate; - } - - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - 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); - } + + for (MongoPersistentEntity entity : mappingContext.getPersistentEntities()) { + checkForIndexes(entity); } } - 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) { Class type = entity.getType(); if (!classesSeen.contains(type)) { diff --git a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml index ddc714bfb..9483517e6 100644 --- a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml +++ b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml @@ -11,7 +11,7 @@ - +