diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java index 04d2dd16a..e3da27751 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,13 +24,14 @@ package org.springframework.data.mongodb.config; */ public abstract class BeanNames { - static final String MAPPING_CONTEXT = "mappingContext"; - static final String INDEX_HELPER = "indexCreationHelper"; - static final String MONGO = "mongo"; - static final String DB_FACTORY = "mongoDbFactory"; - static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener"; - static final String IS_NEW_STRATEGY_FACTORY = "isNewStrategyFactory"; + public static final String MAPPING_CONTEXT_BEAN_NAME = "mongoMappingContext"; + + static final String INDEX_HELPER_BEAN_NAME = "indexCreationHelper"; + static final String MONGO_BEAN_NAME = "mongo"; + static final String DB_FACTORY_BEAN_NAME = "mongoDbFactory"; + static final String VALIDATING_EVENT_LISTENER_BEAN_NAME = "validatingMongoEventListener"; + static final String IS_NEW_STRATEGY_FACTORY_BEAN_NAME = "isNewStrategyFactory"; static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter"; - static final String MONGO_TEMPLATE = "mongoTemplate"; - static final String GRID_FS_TEMPLATE = "gridFsTemplate"; + static final String MONGO_TEMPLATE_BEAN_NAME = "mongoTemplate"; + static final String GRID_FS_TEMPLATE_BEAN_NAME = "gridFsTemplate"; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java index 04b99dd9c..83da976e1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java @@ -43,7 +43,7 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser { throws BeanDefinitionStoreException { String id = super.resolveId(element, definition, parserContext); - return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE; + return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE_BEAN_NAME; } /* @@ -64,7 +64,7 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser { if (StringUtils.hasText(dbFactoryRef)) { gridFsTemplateBuilder.addConstructorArgReference(dbFactoryRef); } else { - gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY); + gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME); } if (StringUtils.hasText(converterRef)) { @@ -77,7 +77,7 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser { gridFsTemplateBuilder.addConstructorArgValue(bucket); } - return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE) + return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE_BEAN_NAME) .getBeanDefinition(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java index 46491f6a3..6b601c66d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java @@ -86,7 +86,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { BeanDefinitionRegistry registry = parserContext.getRegistry(); String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE); - id = StringUtils.hasText(id) ? id : "mappingConverter"; + id = StringUtils.hasText(id) ? id : DEFAULT_CONVERTER_BEAN_NAME; parserContext.pushContainingComponent(new CompositeComponentDefinition("Mapping Mongo Converter", element)); @@ -98,7 +98,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { // Need a reference to a Mongo instance String dbFactoryRef = element.getAttribute("db-factory-ref"); if (!StringUtils.hasText(dbFactoryRef)) { - dbFactoryRef = DB_FACTORY; + dbFactoryRef = DB_FACTORY_BEAN_NAME; } // Converter @@ -116,10 +116,10 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { } try { - registry.getBeanDefinition(INDEX_HELPER); + registry.getBeanDefinition(INDEX_HELPER_BEAN_NAME); } catch (NoSuchBeanDefinitionException ignored) { if (!StringUtils.hasText(dbFactoryRef)) { - dbFactoryRef = DB_FACTORY; + dbFactoryRef = DB_FACTORY_BEAN_NAME; } BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder .genericBeanDefinition(MongoPersistentEntityIndexCreator.class); @@ -128,14 +128,14 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { indexHelperBuilder.addDependsOn(ctxRef); parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(), - INDEX_HELPER)); + INDEX_HELPER_BEAN_NAME)); } BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext); if (validatingMongoEventListener != null) { parserContext.registerBeanComponent(new BeanComponentDefinition(validatingMongoEventListener, - VALIDATING_EVENT_LISTENER)); + VALIDATING_EVENT_LISTENER_BEAN_NAME)); } parserContext.registerBeanComponent(new BeanComponentDefinition(converterBuilder.getBeanDefinition(), id)); @@ -180,7 +180,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { return new RuntimeBeanReference(validatorName); } - static String potentiallyCreateMappingContext(Element element, ParserContext parserContext, + public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext, BeanDefinition conversionsDefinition, String converterId) { String ctxRef = element.getAttribute("mapping-context-ref"); @@ -215,7 +215,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { CamelCaseAbbreviatingFieldNamingStrategy.class)); } - ctxRef = converterId + "." + MAPPING_CONTEXT; + ctxRef = converterId == null || DEFAULT_CONVERTER_BEAN_NAME.equals(converterId) ? MAPPING_CONTEXT_BEAN_NAME + : converterId + "." + MAPPING_CONTEXT_BEAN_NAME; parserContext.registerBeanComponent(componentDefinitionBuilder.getComponent(mappingContextBuilder, ctxRef)); return ctxRef; @@ -310,9 +311,10 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { mappingContextStrategyFactoryBuilder.addConstructorArgReference(mappingContextRef); BeanComponentDefinitionBuilder builder = new BeanComponentDefinitionBuilder(element, context); - context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder, IS_NEW_STRATEGY_FACTORY)); + context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder, + IS_NEW_STRATEGY_FACTORY_BEAN_NAME)); - return IS_NEW_STRATEGY_FACTORY; + return IS_NEW_STRATEGY_FACTORY_BEAN_NAME; } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java index bed915ce5..7d227f1aa 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 the original author or authors. + * Copyright 2012-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,10 @@ */ package org.springframework.data.mongodb.config; -import org.springframework.beans.factory.config.BeanDefinition; +import static org.springframework.data.config.ParsingUtils.*; +import static org.springframework.data.mongodb.config.BeanNames.*; +import static org.springframework.data.mongodb.config.MappingMongoConverterParser.*; + import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; @@ -60,21 +63,23 @@ public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinit BeanDefinitionRegistry registry = parserContext.getRegistry(); - if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY)) { + String isNewStrategyFactoryName = IS_NEW_STRATEGY_FACTORY_BEAN_NAME; + String mappingContextName = MAPPING_CONTEXT_BEAN_NAME; - String mappingContextName = BeanNames.MAPPING_CONTEXT; + if (!registry.containsBeanDefinition(isNewStrategyFactoryName)) { - if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT)) { - mappingContextName = MappingMongoConverterParser.potentiallyCreateMappingContext(element, parserContext, null, - BeanNames.DEFAULT_CONVERTER_BEAN_NAME); + if (!registry.containsBeanDefinition(mappingContextName)) { + mappingContextName = potentiallyCreateMappingContext(element, parserContext, null, null); } - MappingMongoConverterParser.createIsNewStrategyFactoryBeanDefinition(mappingContextName, parserContext, element); + isNewStrategyFactoryName = createIsNewStrategyFactoryBeanDefinition(mappingContextName, parserContext, element); } - BeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(BeanNames.IS_NEW_STRATEGY_FACTORY); - BeanDefinition handlerBeanDefinition = parser.parse(element, parserContext); + IsNewAwareAuditingHandlerBeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser( + isNewStrategyFactoryName); + parser.parse(element, parserContext); - builder.addConstructorArgValue(handlerBeanDefinition); + builder.addConstructorArgValue(getObjectFactoryBeanDefinition(parser.getResolvedBeanName(), + parserContext.extractSource(element))); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java index e3dac7934..f381fd9f5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,13 +18,15 @@ package org.springframework.data.mongodb.config; import java.lang.annotation.Annotation; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean; +import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.auditing.IsNewAwareAuditingHandler; -import org.springframework.data.auditing.config.AnnotationAuditingConfiguration; import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport; +import org.springframework.data.auditing.config.AuditingConfiguration; import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory; import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener; import org.springframework.data.support.IsNewStrategyFactory; @@ -47,6 +49,15 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { return EnableMongoAuditing.class; } + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName() + */ + @Override + protected String getAuditingHandlerBeanName() { + return "mongoAuditingHandler"; + } + /* * (non-Javadoc) * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry) @@ -63,16 +74,16 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { /* * (non-Javadoc) - * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AnnotationAuditingConfiguration) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration) */ @Override - protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AnnotationAuditingConfiguration configuration) { + protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) { - Assert.notNull(configuration, "AnnotationAuditingConfiguration must not be null!"); + Assert.notNull(configuration, "AuditingConfiguration must not be null!"); - return configureDefaultAuditHandlerAttributes(configuration, - BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class)).addConstructorArgReference( - BeanNames.IS_NEW_STRATEGY_FACTORY); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class); + builder.addConstructorArgReference(BeanNames.IS_NEW_STRATEGY_FACTORY_BEAN_NAME); + return configureDefaultAuditHandlerAttributes(configuration, builder); } /* @@ -86,8 +97,15 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!"); Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); - registerInfrastructureBeanWithId(BeanDefinitionBuilder.rootBeanDefinition(AuditingEventListener.class) - .addConstructorArgValue(auditingHandlerDefinition).getRawBeanDefinition(), + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ObjectFactoryCreatingFactoryBean.class); + builder.addPropertyValue("targetBeanName", getAuditingHandlerBeanName()); + builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE); + + BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder + .rootBeanDefinition(AuditingEventListener.class); + listenerBeanDefinitionBuilder.addConstructorArgValue(builder.getBeanDefinition()); + + registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(), AuditingEventListener.class.getName(), registry); } @@ -96,10 +114,10 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { */ private void registerIsNewStrategyFactoryIfNecessary(BeanDefinitionRegistry registry) { - if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY)) { - registry.registerBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY, + if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY_BEAN_NAME)) { + registry.registerBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY_BEAN_NAME, BeanDefinitionBuilder.rootBeanDefinition(MappingContextIsNewStrategyFactory.class) - .addConstructorArgReference(BeanNames.MAPPING_CONTEXT).getBeanDefinition()); + .addConstructorArgReference(BeanNames.MAPPING_CONTEXT_BEAN_NAME).getBeanDefinition()); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java index be6c1ff9e..7a23c03fe 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 by the original author(s). + * Copyright 2011-2014 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { throws BeanDefinitionStoreException { String id = super.resolveId(element, definition, parserContext); - return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY; + return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY_BEAN_NAME; } /* @@ -103,7 +103,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder); parserContext.registerBeanComponent(component); - return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY) + return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY_BEAN_NAME) .getBeanDefinition(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java index f03f9c697..ca605a02e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ public class MongoParser implements BeanDefinitionParser { MongoParsingUtils.parseMongoOptions(element, builder); MongoParsingUtils.parseReplicaSet(element, builder); - String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO; + String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME; parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source)); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java index 0990fdd76..cfc5fdabc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import org.w3c.dom.Element; * {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s. * * @author Martin Baumgartner + * @author Oliver Gierke */ class MongoTemplateParser extends AbstractBeanDefinitionParser { @@ -47,7 +48,7 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser { throws BeanDefinitionStoreException { String id = super.resolveId(element, definition, parserContext); - return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE; + return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE_BEAN_NAME; } /* @@ -68,7 +69,7 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser { if (StringUtils.hasText(dbFactoryRef)) { mongoTemplateBuilder.addConstructorArgReference(dbFactoryRef); } else { - mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY); + mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME); } if (StringUtils.hasText(converterRef)) { @@ -80,7 +81,7 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser { BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder); parserContext.registerBeanComponent(component); - return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder, BeanNames.MONGO_TEMPLATE) - .getBeanDefinition(); + return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder, + BeanNames.MONGO_TEMPLATE_BEAN_NAME).getBeanDefinition(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java index 0d6d4c287..be7a0837b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core.mapping.event; +import org.springframework.beans.factory.ObjectFactory; import org.springframework.context.ApplicationListener; import org.springframework.data.auditing.AuditingHandler; import org.springframework.data.auditing.IsNewAwareAuditingHandler; @@ -25,20 +26,22 @@ import org.springframework.util.Assert; * Event listener to populate auditing related fields on an entity about to be saved. * * @author Oliver Gierke + * @author Thomas Darimont */ public class AuditingEventListener implements ApplicationListener> { - private final IsNewAwareAuditingHandler auditingHandler; + private final ObjectFactory auditingHandlerFactory; /** - * Creates a new {@link AuditingEventListener} using the given {@link MappingContext} and {@link AuditingHandler}. + * Creates a new {@link AuditingEventListener} using the given {@link MappingContext} and {@link AuditingHandler} + * provided by the given {@link ObjectFactory}. * - * @param auditingHandler must not be {@literal null}. + * @param auditingHandlerFactory must not be {@literal null}. */ - public AuditingEventListener(IsNewAwareAuditingHandler auditingHandler) { + public AuditingEventListener(ObjectFactory auditingHandlerFactory) { - Assert.notNull(auditingHandler, "IsNewAwareAuditingHandler must not be null!"); - this.auditingHandler = auditingHandler; + Assert.notNull(auditingHandlerFactory, "IsNewAwareAuditingHandler must not be null!"); + this.auditingHandlerFactory = auditingHandlerFactory; } /* @@ -48,6 +51,6 @@ public class AuditingEventListener implements ApplicationListener event) { Object entity = event.getSource(); - auditingHandler.markAudited(entity); + auditingHandlerFactory.getObject().markAudited(entity); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java index 6963a9fa1..003bfeb4f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java @@ -15,13 +15,19 @@ */ package org.springframework.data.mongodb.repository.config; +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.RootBeanDefinition; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.data.config.ParsingUtils; +import org.springframework.data.mongodb.config.BeanNames; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; import org.springframework.data.repository.config.RepositoryConfigurationExtension; import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; +import org.springframework.data.repository.config.RepositoryConfigurationSource; import org.springframework.data.repository.config.XmlRepositoryConfigurationSource; import org.w3c.dom.Element; @@ -35,6 +41,8 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati private static final String MONGO_TEMPLATE_REF = "mongo-template-ref"; private static final String CREATE_QUERY_INDEXES = "create-query-indexes"; + private boolean fallbackMappingContextCreated = false; + /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() @@ -52,6 +60,18 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati return MongoRepositoryFactoryBean.class.getName(); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.RepositoryConfigurationSource) + */ + @Override + public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) { + + if (fallbackMappingContextCreated) { + builder.addPropertyReference("mappingContext", BeanNames.MAPPING_CONTEXT_BEAN_NAME); + } + } + /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.XmlRepositoryConfigurationSource) @@ -77,4 +97,21 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati builder.addPropertyReference("mongoOperations", attributes.getString("mongoTemplateRef")); builder.addPropertyValue("createIndexesForQueryMethods", attributes.getBoolean("createIndexesForQueryMethods")); } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#registerBeansForRoot(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.data.repository.config.RepositoryConfigurationSource) + */ + @Override + public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { + + if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME)) { + + RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class); + definition.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE); + definition.setSource(configurationSource.getSource()); + + registry.registerBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME, definition); + } + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java index 523b63c94..abaee0270 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support; import java.io.Serializable; +import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.repository.Repository; @@ -34,6 +35,7 @@ public class MongoRepositoryFactoryBean, S, ID exten private MongoOperations operations; private boolean createIndexesForQueryMethods = false; + private boolean mappingContextConfigured = false; /** * Configures the {@link MongoOperations} to be used. @@ -42,7 +44,6 @@ public class MongoRepositoryFactoryBean, S, ID exten */ public void setMongoOperations(MongoOperations operations) { this.operations = operations; - setMappingContext(operations.getConverter().getMappingContext()); } /** @@ -54,6 +55,17 @@ public class MongoRepositoryFactoryBean, S, ID exten this.createIndexesForQueryMethods = createIndexesForQueryMethods; } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setMappingContext(org.springframework.data.mapping.context.MappingContext) + */ + @Override + protected void setMappingContext(MappingContext mappingContext) { + + super.setMappingContext(mappingContext); + this.mappingContextConfigured = true; + } + /* * (non-Javadoc) * @@ -95,5 +107,9 @@ public class MongoRepositoryFactoryBean, S, ID exten super.afterPropertiesSet(); Assert.notNull(operations, "MongoTemplate must not be null!"); + + if (!mappingContextConfigured) { + setMappingContext(operations.getConverter().getMappingContext()); + } } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java index df5d7a412..112789824 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,24 +19,26 @@ import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import java.net.UnknownHostException; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.AuditorAware; import org.springframework.data.mongodb.core.AuditablePerson; -import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; -import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.stereotype.Repository; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import com.mongodb.Mongo; import com.mongodb.MongoClient; /** @@ -56,16 +58,16 @@ public class AuditingViaJavaConfigRepositoriesTests { @Configuration @EnableMongoAuditing(auditorAwareRef = "auditorProvider") @EnableMongoRepositories(basePackageClasses = AuditablePersonRepository.class, considerNestedRepositories = true) - static class Config { + static class Config extends AbstractMongoConfiguration { - @Bean - public MongoOperations mongoTemplate() throws Exception { - return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database")); + @Override + protected String getDatabaseName() { + return "database"; } - @Bean - public MongoMappingContext mappingContext() { - return new MongoMappingContext(); + @Override + public Mongo mongo() throws Exception { + return new MongoClient(); } @Bean @@ -81,6 +83,9 @@ public class AuditingViaJavaConfigRepositoriesTests { this.auditor = auditablePersonRepository.save(new AuditablePerson("auditor")); } + /** + * @DATAMONGO-792 + */ @Test public void basicAuditing() { @@ -89,13 +94,32 @@ public class AuditingViaJavaConfigRepositoriesTests { AuditablePerson user = new AuditablePerson("user"); AuditablePerson savedUser = auditablePersonRepository.save(user); - System.out.println(savedUser); AuditablePerson createdBy = savedUser.getCreatedBy(); assertThat(createdBy, is(notNullValue())); assertThat(createdBy.getFirstname(), is(this.auditor.getFirstname())); } + /** + * @see DATAMONGO-843 + */ + @Test + @SuppressWarnings("resource") + public void auditingUsesFallbackMappingContextIfNoneConfigured() { + new AnnotationConfigApplicationContext(SimpleConfig.class); + } + @Repository static interface AuditablePersonRepository extends MongoRepository {} + + @Configuration + @EnableMongoRepositories + @EnableMongoAuditing + static class SimpleConfig { + + @Bean + public MongoTemplate mongoTemplate() throws UnknownHostException { + return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database")); + } + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java index e8bc74bab..5a7951f1e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +57,9 @@ public class MappingMongoConverterParserIntegrationTests { reader.loadBeanDefinitions(new ClassPathResource("namespace/converter.xml")); } + /** + * @see DATAMONGO-243 + */ @Test public void allowsDbFactoryRefAttribute() { @@ -64,6 +67,9 @@ public class MappingMongoConverterParserIntegrationTests { factory.getBean("converter"); } + /** + * @see DATAMONGO-725 + */ @Test public void hasCustomTypeMapper() { @@ -73,6 +79,9 @@ public class MappingMongoConverterParserIntegrationTests { assertThat(converter.getTypeMapper(), is(customMongoTypeMapper)); } + /** + * @see DATAMONGO-301 + */ @Test public void scansForConverterAndSetsUpCustomConversionsAccordingly() { @@ -87,7 +96,7 @@ public class MappingMongoConverterParserIntegrationTests { @Test public void activatesAbbreviatingPropertiesCorrectly() { - BeanDefinition definition = factory.getBeanDefinition("abbreviatingConverter.mappingContext"); + BeanDefinition definition = factory.getBeanDefinition("abbreviatingConverter.mongoMappingContext"); Object value = definition.getPropertyValues().getPropertyValue("fieldNamingStrategy").getValue(); assertThat(value, is(instanceOf(BeanDefinition.class))); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserValidationIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserValidationIntegrationTests.java index f89bb1d65..d9f34df89 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserValidationIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserValidationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ import org.springframework.core.io.ClassPathResource; * @see DATAMONGO-36 * @author Maciej Walkowiak * @author Thomas Darimont + * @author Oliver Gierke */ public class MappingMongoConverterParserValidationIntegrationTests { @@ -46,31 +47,43 @@ public class MappingMongoConverterParserValidationIntegrationTests { reader = new XmlBeanDefinitionReader(factory); } + /** + * @see DATAMONGO-36 + */ @Test public void validatingEventListenerCreatedWithDefaultConfig() { reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-default.xml")); - assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue()))); + assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME), is(not(nullValue()))); } + /** + * @see DATAMONGO-36 + */ @Test public void validatingEventListenerCreatedWhenValidationEnabled() { reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-enabled.xml")); - assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue()))); + assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME), is(not(nullValue()))); } + /** + * @see DATAMONGO-36 + */ @Test(expected = NoSuchBeanDefinitionException.class) public void validatingEventListenersIsNotCreatedWhenDisabled() { reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-disabled.xml")); - factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER); + factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME); } + /** + * @see DATAMONGO-36 + */ @Test public void validatingEventListenerCreatedWithCustomTypeMapperConfig() { reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-custom-typeMapper.xml")); - assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue()))); + assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME), is(not(nullValue()))); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListenerUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListenerUnitTests.java index 9f59e19f4..f5c44bc6f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListenerUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListenerUnitTests.java @@ -23,6 +23,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.ObjectFactory; import org.springframework.data.annotation.Id; import org.springframework.data.auditing.IsNewAwareAuditingHandler; import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory; @@ -33,6 +35,7 @@ import org.springframework.data.support.IsNewStrategyFactory; * Unit tests for {@link AuditingEventListener}. * * @author Oliver Gierke + * @author Thomas Darimont */ @RunWith(MockitoJUnitRunner.class) public class AuditingEventListenerUnitTests { @@ -52,14 +55,26 @@ public class AuditingEventListenerUnitTests { doNothing().when(handler).markCreated(Mockito.any(Object.class)); doNothing().when(handler).markModified(Mockito.any(Object.class)); - listener = new AuditingEventListener(handler); + listener = new AuditingEventListener(new ObjectFactory() { + + @Override + public IsNewAwareAuditingHandler getObject() throws BeansException { + return handler; + } + }); } + /** + * @see DATAMONGO-577 + */ @Test(expected = IllegalArgumentException.class) public void rejectsNullAuditingHandler() { new AuditingEventListener(null); } + /** + * @see DATAMONGO-577 + */ @Test public void triggersCreationMarkForObjectWithEmptyId() { @@ -70,6 +85,9 @@ public class AuditingEventListenerUnitTests { verify(handler, times(0)).markModified(any(Sample.class)); } + /** + * @see DATAMONGO-577 + */ @Test public void triggersModificationMarkForObjectWithSetId() {