diff --git a/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfiguration.java b/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfiguration.java index 29a1c4889..07f085072 100644 --- a/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfiguration.java +++ b/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfiguration.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. @@ -15,43 +15,71 @@ */ package org.springframework.data.auditing.config; -import org.springframework.data.auditing.DateTimeProvider; -import org.springframework.data.domain.AuditorAware; +import java.lang.annotation.Annotation; + +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.Assert; /** - * Configuration information for auditing. + * Default implementation for {@link AuditingConfiguration}. * * @author Ranie Jade Ramiso * @author Thomas Darimont * @author Oliver Gierke */ -public interface AnnotationAuditingConfiguration { +public class AnnotationAuditingConfiguration implements AuditingConfiguration { + + private final AnnotationAttributes attributes; /** - * Returns the bean name of the {@link AuditorAware} instance to be used.. + * Creates a new instance of {@link AnnotationAuditingConfiguration} for the given {@link AnnotationMetadata} and + * annotation type. * - * @return + * @param metadata must not be {@literal null}. + * @param annotation must not be {@literal null}. */ - String getAuditorAwareRef(); + public AnnotationAuditingConfiguration(AnnotationMetadata metadata, Class annotation) { - /** - * Returns whether the creation and modification dates shall be set. Defaults to {@literal true}. - * - * @return - */ - boolean isSetDates(); + Assert.notNull(metadata, "AnnotationMetadata must not be null!"); + Assert.notNull(annotation, "Annotation must not be null!"); - /** - * Returns whether the entity shall be marked as modified on creation. Defaults to {@literal true}. - * - * @return - */ - boolean isModifyOnCreate(); + this.attributes = new AnnotationAttributes(metadata.getAnnotationAttributes(annotation.getName())); + } - /** - * Returns the bean name of the {@link DateTimeProvider} to be used. - * - * @return + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingConfiguration#getAuditorAwareRef() */ - String getDateTimeProviderRef(); + @Override + public String getAuditorAwareRef() { + return attributes.getString("auditorAwareRef"); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingConfiguration#isSetDates() + */ + @Override + public boolean isSetDates() { + return attributes.getBoolean("setDates"); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingConfiguration#getDateTimeProviderRef() + */ + @Override + public String getDateTimeProviderRef() { + return attributes.getString("dateTimeProviderRef"); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingConfiguration#isModifyOnCreate() + */ + @Override + public boolean isModifyOnCreate() { + return attributes.getBoolean("modifyOnCreate"); + } } diff --git a/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfigurationSupport.java b/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfigurationSupport.java deleted file mode 100644 index 498c3da33..000000000 --- a/src/main/java/org/springframework/data/auditing/config/AnnotationAuditingConfigurationSupport.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.auditing.config; - -import java.lang.annotation.Annotation; - -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.Assert; - -/** - * Default implementation for {@link AnnotationAuditingConfiguration}. - * - * @author Ranie Jade Ramiso - * @author Thomas Darimont - * @author Oliver Gierke - */ -public class AnnotationAuditingConfigurationSupport implements AnnotationAuditingConfiguration { - - private final AnnotationAttributes attributes; - - /** - * Creates a new instance of {@link AnnotationAuditingConfigurationSupport} for the given {@link AnnotationMetadata} - * and annotation type. - * - * @param metadata must not be {@literal null}. - * @param annotation must not be {@literal null}. - */ - public AnnotationAuditingConfigurationSupport(AnnotationMetadata metadata, Class annotation) { - - Assert.notNull(metadata, "AnnotationMetadata must not be null!"); - Assert.notNull(annotation, "Annotation must not be null!"); - - this.attributes = new AnnotationAttributes(metadata.getAnnotationAttributes(annotation.getName())); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AnnotationAuditingConfiguration#getAuditorAwareRef() - */ - @Override - public String getAuditorAwareRef() { - return attributes.getString("auditorAwareRef"); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AnnotationAuditingConfiguration#isSetDates() - */ - @Override - public boolean isSetDates() { - return attributes.getBoolean("setDates"); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AnnotationAuditingConfiguration#getDateTimeProviderRef() - */ - @Override - public String getDateTimeProviderRef() { - return attributes.getString("dateTimeProviderRef"); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AnnotationAuditingConfiguration#isModifyOnCreate() - */ - @Override - public boolean isModifyOnCreate() { - return attributes.getBoolean("modifyOnCreate"); - } -} diff --git a/src/main/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupport.java b/src/main/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupport.java index 75675433f..9dda8e044 100644 --- a/src/main/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupport.java +++ b/src/main/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupport.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. @@ -25,7 +25,6 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; @@ -37,7 +36,7 @@ import org.springframework.util.StringUtils; /** * A {@link ImportBeanDefinitionRegistrar} that serves as a base class for store specific implementations for * configuring audit support. Registers a {@link AuditingHandler} based on the provided configuration( - * {@link AnnotationAuditingConfiguration}). + * {@link AuditingConfiguration}). * * @author Ranie Jade Ramiso * @author Thomas Darimont @@ -72,13 +71,13 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe * @return */ private AbstractBeanDefinition registerAuditHandlerBeanDefinition(BeanDefinitionRegistry registry, - AnnotationAuditingConfiguration configuration) { + AuditingConfiguration configuration) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); - Assert.notNull(configuration, "AnnotationAuditingConfiguration must not be null!"); + Assert.notNull(configuration, "AuditingConfiguration must not be null!"); AbstractBeanDefinition ahbd = getAuditHandlerBeanDefinitionBuilder(configuration).getBeanDefinition(); - registry.registerBeanDefinition(BeanDefinitionReaderUtils.generateBeanName(ahbd, registry), ahbd); + registry.registerBeanDefinition(getAuditingHandlerBeanName(), ahbd); return ahbd; } @@ -89,9 +88,9 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe * @param configuration must not be {@literal null}. * @return */ - 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(AuditingHandler.class)); @@ -99,13 +98,13 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe /** * Configures the given {@link BeanDefinitionBuilder} with the default attributes from the given - * {@link AnnotationAuditingConfiguration}. + * {@link AuditingConfiguration}. * * @param configuration must not be {@literal null}. * @param builder must not be {@literal null}. * @return the builder with the audit attributes configured. */ - protected BeanDefinitionBuilder configureDefaultAuditHandlerAttributes(AnnotationAuditingConfiguration configuration, + protected BeanDefinitionBuilder configureDefaultAuditHandlerAttributes(AuditingConfiguration configuration, BeanDefinitionBuilder builder) { if (StringUtils.hasText(configuration.getAuditorAwareRef())) { @@ -124,6 +123,8 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe builder.addPropertyValue(DATE_TIME_PROVIDER, CurrentDateTimeProvider.INSTANCE); } + builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE); + return builder; } @@ -133,8 +134,8 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe * @param annotationMetadata will never be {@literal null}. * @return */ - protected AnnotationAuditingConfiguration getConfiguration(AnnotationMetadata annotationMetadata) { - return new AnnotationAuditingConfigurationSupport(annotationMetadata, getAnnotation()); + protected AuditingConfiguration getConfiguration(AnnotationMetadata annotationMetadata) { + return new AnnotationAuditingConfiguration(annotationMetadata, getAnnotation()); } /** @@ -145,12 +146,21 @@ public abstract class AuditingBeanDefinitionRegistrarSupport implements ImportBe protected abstract Class getAnnotation(); /** - * @param auditingHandlerDefinition - * @param registry + * Register the listener to eventually trigger the {@link AuditingHandler}. + * + * @param auditingHandlerDefinition will never be {@literal null}. + * @param registry will never be {@literal null}. */ protected abstract void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition, BeanDefinitionRegistry registry); + /** + * Return the name to be used to register the {@link AuditingHandler} under. + * + * @return + */ + protected abstract String getAuditingHandlerBeanName(); + /** * Registers the given {@link AbstractBeanDefinition} as infrastructure bean under the given id. * diff --git a/src/main/java/org/springframework/data/auditing/config/AuditingConfiguration.java b/src/main/java/org/springframework/data/auditing/config/AuditingConfiguration.java new file mode 100644 index 000000000..d751b1811 --- /dev/null +++ b/src/main/java/org/springframework/data/auditing/config/AuditingConfiguration.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.auditing.config; + +import org.springframework.data.auditing.DateTimeProvider; +import org.springframework.data.domain.AuditorAware; + +/** + * Configuration information for auditing. + * + * @author Ranie Jade Ramiso + * @author Thomas Darimont + * @author Oliver Gierke + */ +public interface AuditingConfiguration { + + /** + * Returns the bean name of the {@link AuditorAware} instance to be used.. + * + * @return + */ + String getAuditorAwareRef(); + + /** + * Returns whether the creation and modification dates shall be set. Defaults to {@literal true}. + * + * @return + */ + boolean isSetDates(); + + /** + * Returns whether the entity shall be marked as modified on creation. Defaults to {@literal true}. + * + * @return + */ + boolean isModifyOnCreate(); + + /** + * Returns the bean name of the {@link DateTimeProvider} to be used. + * + * @return + */ + String getDateTimeProviderRef(); +} diff --git a/src/main/java/org/springframework/data/config/AuditingHandlerBeanDefinitionParser.java b/src/main/java/org/springframework/data/config/AuditingHandlerBeanDefinitionParser.java index fe0ac7dd8..99f879925 100644 --- a/src/main/java/org/springframework/data/config/AuditingHandlerBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/config/AuditingHandlerBeanDefinitionParser.java @@ -63,6 +63,7 @@ public class AuditingHandlerBeanDefinitionParser extends AbstractSingleBeanDefin protected void doParse(Element element, BeanDefinitionBuilder builder) { String auditorAwareRef = element.getAttribute(AUDITOR_AWARE_REF); + if (StringUtils.hasText(auditorAwareRef)) { builder.addPropertyValue("auditorAware", createLazyInitTargetSourceBeanDefinition(auditorAwareRef)); } diff --git a/src/main/java/org/springframework/data/config/IsNewAwareAuditingHandlerBeanDefinitionParser.java b/src/main/java/org/springframework/data/config/IsNewAwareAuditingHandlerBeanDefinitionParser.java index 8dbf35984..15fcd594b 100644 --- a/src/main/java/org/springframework/data/config/IsNewAwareAuditingHandlerBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/config/IsNewAwareAuditingHandlerBeanDefinitionParser.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.config; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; import org.springframework.data.auditing.IsNewAwareAuditingHandler; import org.springframework.util.Assert; import org.w3c.dom.Element; @@ -29,6 +32,7 @@ import org.w3c.dom.Element; public class IsNewAwareAuditingHandlerBeanDefinitionParser extends AuditingHandlerBeanDefinitionParser { private final String isNewStrategyFactoryBeanId; + private String resolvedBeanName; /** * Creates a new {@link IsNewAwareAuditingHandlerBeanDefinitionParser}. @@ -41,6 +45,15 @@ public class IsNewAwareAuditingHandlerBeanDefinitionParser extends AuditingHandl this.isNewStrategyFactoryBeanId = isNewStrategyFactoryBeanId; } + /** + * Returns the bean name that was used to register the {@link IsNewAwareAuditingHandler}. + * + * @return the resolvedBeanName + */ + public String getResolvedBeanName() { + return resolvedBeanName; + } + /* * (non-Javadoc) * @see org.springframework.data.config.AuditingHandlerBeanDefinitionParser#getBeanClass(org.w3c.dom.Element) @@ -58,7 +71,18 @@ public class IsNewAwareAuditingHandlerBeanDefinitionParser extends AuditingHandl protected void doParse(Element element, BeanDefinitionBuilder builder) { builder.addConstructorArgReference(isNewStrategyFactoryBeanId); - super.doParse(element, builder); } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext) + */ + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) + throws BeanDefinitionStoreException { + + this.resolvedBeanName = super.resolveId(element, definition, parserContext); + return resolvedBeanName; + } } diff --git a/src/main/java/org/springframework/data/config/ParsingUtils.java b/src/main/java/org/springframework/data/config/ParsingUtils.java index dc2aaba51..ac729de4a 100644 --- a/src/main/java/org/springframework/data/config/ParsingUtils.java +++ b/src/main/java/org/springframework/data/config/ParsingUtils.java @@ -16,6 +16,7 @@ package org.springframework.data.config; 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.xml.BeanDefinitionParser; @@ -127,4 +128,23 @@ public abstract class ParsingUtils { definition.setSource(source); return definition; } + + /** + * Returns a {@link BeanDefinition} for an {@link ObjectFactoryCreatingFactoryBean} pointing to the bean with the + * given name. + * + * @param targetBeanName must not be {@literal null} or empty. + * @param source + * @return + */ + public static AbstractBeanDefinition getObjectFactoryBeanDefinition(String targetBeanName, Object source) { + + Assert.hasText(targetBeanName, "Target bean name must not be null or empty!"); + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ObjectFactoryCreatingFactoryBean.class); + builder.addPropertyValue("targetBeanName", targetBeanName); + builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE); + + return getSourceBeanDefinition(builder, source); + } } diff --git a/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java b/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java index fb63a228b..ae1ccb846 100644 --- a/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java +++ b/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.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. * You may obtain a copy of the License at @@ -30,14 +30,20 @@ import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.data.auditing.EnableAuditing; /** + * Unit tests for {@link AuditingBeanDefinitionRegistrarSupport}. + * * @author Ranie Jade Ramiso * @author Thomas Darimont + * @author Oliver Gierke */ @RunWith(MockitoJUnitRunner.class) public class AuditingBeanDefinitionRegistrarSupportUnitTests { - @Mock private BeanDefinitionRegistry registry; + @Mock BeanDefinitionRegistry registry; + /** + * @see DATCMNS-389 + */ @Test public void testRegisterBeanDefinitions() { @@ -62,9 +68,9 @@ public class AuditingBeanDefinitionRegistrarSupportUnitTests { } @Override - protected AnnotationAuditingConfiguration getConfiguration(AnnotationMetadata annotationMetadata) { + protected AuditingConfiguration getConfiguration(AnnotationMetadata annotationMetadata) { - return new AnnotationAuditingConfiguration() { + return new AuditingConfiguration() { public String getAuditorAwareRef() { return "auditor"; } @@ -82,5 +88,14 @@ public class AuditingBeanDefinitionRegistrarSupportUnitTests { } }; } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName() + */ + @Override + protected String getAuditingHandlerBeanName() { + return "auditingHandler"; + } } }