From ec03cc5b944c63da9651b299dcdd5f2a88acf040 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 21 Jun 2016 19:44:45 -0700 Subject: [PATCH] SGF-504 - Support Repositories with multiple Spring Data modules on the class path. (cherry picked from commit 8423cdbe8578e0cdb7dd39017231f3f5c755cd33) Signed-off-by: John Blum --- ...mfireRepositoryConfigurationExtension.java | 91 ++++++++++------ ...eRepositoryConfigurationExtensionTest.java | 101 +++++++++++------- 2 files changed, 122 insertions(+), 70 deletions(-) diff --git a/src/main/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtension.java index deaf2669..b0d95d4f 100644 --- a/src/main/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtension.java @@ -13,12 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.data.gemfire.repository.config; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Collections; + import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.data.gemfire.mapping.GemfireMappingContext; +import org.springframework.data.gemfire.mapping.Region; +import org.springframework.data.gemfire.repository.GemfireRepository; import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; import org.springframework.data.repository.config.RepositoryConfigurationExtension; @@ -28,21 +35,48 @@ import org.springframework.data.repository.config.XmlRepositoryConfigurationSour import org.springframework.util.StringUtils; /** - * {@link RepositoryConfigurationExtension} implementation to add Gemfire specific extensions to the repository XML - * namespace and annotation based configuration. - * + * {@link RepositoryConfigurationExtension} implementation handling GemFire specific extensions to the Repository XML + * namespace and annotation-based configuration meta-data. + * * @author Oliver Gierke * @author John Blum */ public class GemfireRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { - private static final String ANNOTATION_MAPPING_CONTEXT_REF = "mappingContextRef"; private static final String MAPPING_CONTEXT_PROPERTY_NAME = "gemfireMappingContext"; - private static final String XML_MAPPING_CONTEXT_REF = "mapping-context-ref"; - + private static final String MAPPING_CONTEXT_REF_ANNOTATION_ATTRIBUTE = "mappingContextRef"; + private static final String MAPPING_CONTEXT_REF_XML_ATTRIBUTE = "mapping-context-ref"; + static final String DEFAULT_MAPPING_CONTEXT_BEAN_NAME = String.format("%1$s.%2$s", GemfireMappingContext.class.getName(), "DEFAULT"); + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingAnnotations() + */ + @Override + protected Collection> getIdentifyingAnnotations() { + return Collections.>singleton(Region.class); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingTypes() + */ + @Override + protected Collection> getIdentifyingTypes() { + return Collections.>singleton(GemfireRepository.class); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() + */ + @Override + protected String getModulePrefix() { + return "gemfire"; + } + /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getRepositoryFactoryClassName() @@ -52,32 +86,6 @@ public class GemfireRepositoryConfigurationExtension extends RepositoryConfigura return GemfireRepositoryFactoryBean.class.getName(); } - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() - */ - @Override - protected String getModulePrefix() { - return "gemfire"; - } - - /* - * (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) { - - super.registerBeansForRoot(registry, configurationSource); - - String attribute = configurationSource.getAttribute(ANNOTATION_MAPPING_CONTEXT_REF); - - if (!StringUtils.hasText(attribute)) { - registry.registerBeanDefinition(DEFAULT_MAPPING_CONTEXT_BEAN_NAME, - new RootBeanDefinition(GemfireMappingContext.class)); - } - } - /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource) @@ -85,7 +93,7 @@ public class GemfireRepositoryConfigurationExtension extends RepositoryConfigura @Override public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) { - String mappingContextRef = config.getAttribute(ANNOTATION_MAPPING_CONTEXT_REF); + String mappingContextRef = config.getAttribute(MAPPING_CONTEXT_REF_ANNOTATION_ATTRIBUTE); builder.addPropertyReference(MAPPING_CONTEXT_PROPERTY_NAME, getDefaultedMappingContextBeanName(mappingContextRef)); } @@ -96,11 +104,26 @@ public class GemfireRepositoryConfigurationExtension extends RepositoryConfigura @Override public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) { - String mappingContextRef = config.getElement().getAttribute(XML_MAPPING_CONTEXT_REF); + String mappingContextRef = config.getElement().getAttribute(MAPPING_CONTEXT_REF_XML_ATTRIBUTE); builder.addPropertyReference(MAPPING_CONTEXT_PROPERTY_NAME, getDefaultedMappingContextBeanName(mappingContextRef)); } private static String getDefaultedMappingContextBeanName(String source) { return StringUtils.hasText(source) ? source : DEFAULT_MAPPING_CONTEXT_BEAN_NAME; } + + /* + * (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) { + + super.registerBeansForRoot(registry, configurationSource); + + if (!StringUtils.hasText(configurationSource.getAttribute(MAPPING_CONTEXT_REF_ANNOTATION_ATTRIBUTE))) { + registry.registerBeanDefinition(DEFAULT_MAPPING_CONTEXT_BEAN_NAME, + new RootBeanDefinition(GemfireMappingContext.class)); + } + } } diff --git a/src/test/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtensionTest.java b/src/test/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtensionTest.java index 67aed0df..0ff8a045 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtensionTest.java +++ b/src/test/java/org/springframework/data/gemfire/repository/config/GemfireRepositoryConfigurationExtensionTest.java @@ -16,24 +16,35 @@ package org.springframework.data.gemfire.repository.config; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.annotation.Annotation; +import java.util.Collection; import org.junit.Before; import org.junit.Test; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.data.gemfire.mapping.Region; +import org.springframework.data.gemfire.repository.GemfireRepository; import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; import org.springframework.data.repository.config.XmlRepositoryConfigurationSource; import org.w3c.dom.Element; /** - * The GemfireRepositoryConfigurationExtensionTest class is a test suite of test cases testing the contract - * and functionality of the GemfireRepositoryConfigurationExtension class. + * Test suite of test cases testing the contract and functionality of the + * {@link GemfireRepositoryConfigurationExtension} class. * * @author John Blum * @see org.junit.Test @@ -44,7 +55,9 @@ import org.w3c.dom.Element; public class GemfireRepositoryConfigurationExtensionTest { private GemfireRepositoryConfigurationExtension repositoryConfigurationExtension; - private RuntimeBeanReference defaultMappingContextReference = new RuntimeBeanReference(GemfireRepositoryConfigurationExtension.DEFAULT_MAPPING_CONTEXT_BEAN_NAME); + + private RuntimeBeanReference defaultMappingContextReference = new RuntimeBeanReference( + GemfireRepositoryConfigurationExtension.DEFAULT_MAPPING_CONTEXT_BEAN_NAME); @Before public void setup() { @@ -52,9 +65,20 @@ public class GemfireRepositoryConfigurationExtensionTest { } @Test - public void repositoryFactoryClassNameIsGemfireRepositoryFactoryBean() { - assertThat(repositoryConfigurationExtension.getRepositoryFactoryClassName(), - is(equalTo(GemfireRepositoryFactoryBean.class.getName()))); + public void identifyingAnnotationsIncludesRegionAnnotation() { + Collection> identifyingAnnotations = + repositoryConfigurationExtension.getIdentifyingAnnotations(); + + assertThat(identifyingAnnotations, is(notNullValue(Collection.class))); + assertThat(identifyingAnnotations.contains(Region.class), is(true)); + } + + @Test + public void identifyingTypesContainsGemfireRepositoryAnnotation() { + Collection> identifyingTypes = repositoryConfigurationExtension.getIdentifyingTypes(); + + assertThat(identifyingTypes, is(notNullValue(Collection.class))); + assertThat(identifyingTypes.contains(GemfireRepository.class), is(true)); } @Test @@ -62,6 +86,12 @@ public class GemfireRepositoryConfigurationExtensionTest { assertThat(repositoryConfigurationExtension.getModulePrefix(), is(equalTo("gemfire"))); } + @Test + public void repositoryFactoryClassNameIsGemfireRepositoryFactoryBean() { + assertThat(repositoryConfigurationExtension.getRepositoryFactoryClassName(), + is(equalTo(GemfireRepositoryFactoryBean.class.getName()))); + } + @Test public void postProcessWithAnnotationRepositoryConfigurationSource() { AnnotationRepositoryConfigurationSource mockRepositoryConfigurationSource = @@ -83,7 +113,7 @@ public class GemfireRepositoryConfigurationExtensionTest { } @Test - public void postProcessWithAnnotationRepositoryConfigurationSourceHaingNoMappingContextRefAttribute() { + public void postProcessWithAnnotationRepositoryConfigurationSourceHavingNoMappingContextRefAttribute() { AnnotationRepositoryConfigurationSource mockRepositoryConfigurationSource = mock(AnnotationRepositoryConfigurationSource.class); @@ -96,36 +126,13 @@ public class GemfireRepositoryConfigurationExtensionTest { PropertyValue mappingContextRef = beanDefinitionBuilder.getRawBeanDefinition().getPropertyValues() .getPropertyValue("gemfireMappingContext"); - assertThat(mappingContextRef.getValue(), is((Object) defaultMappingContextReference)); + assertThat(mappingContextRef.getValue(), is(equalTo((Object) defaultMappingContextReference))); verify(mockRepositoryConfigurationSource, times(1)).getAttribute(eq("mappingContextRef")); } @Test - public void postProcessWithXmlRepositoryConfigurationSourceHavingNoMappingContextRefAttribute() { - Element mockElement = mock(Element.class); - - XmlRepositoryConfigurationSource mockRepositoryConfigurationSource = - mock(XmlRepositoryConfigurationSource.class); - - when(mockRepositoryConfigurationSource.getElement()).thenReturn(mockElement); - when(mockElement.getAttribute(eq("mapping-context-ref"))).thenReturn(null); - - BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(); - - repositoryConfigurationExtension.postProcess(beanDefinitionBuilder, mockRepositoryConfigurationSource); - - PropertyValue mappingContextRef = beanDefinitionBuilder.getRawBeanDefinition().getPropertyValues() - .getPropertyValue("gemfireMappingContext"); - - assertThat(mappingContextRef.getValue(), is((Object) defaultMappingContextReference)); - - verify(mockRepositoryConfigurationSource, times(1)).getElement(); - verify(mockElement, times(1)).getAttribute(eq("mapping-context-ref")); - } - - @Test - public void postProcessWithXmlRepositoryConfigurationSourceWith() { + public void postProcessWithXmlRepositoryConfigurationSource() { Element mockElement = mock(Element.class); XmlRepositoryConfigurationSource mockRepositoryConfigurationSource = @@ -148,4 +155,26 @@ public class GemfireRepositoryConfigurationExtensionTest { verify(mockElement, times(1)).getAttribute(eq("mapping-context-ref")); } + @Test + public void postProcessWithXmlRepositoryConfigurationSourceHavingNoMappingContextRefAttribute() { + Element mockElement = mock(Element.class); + + XmlRepositoryConfigurationSource mockRepositoryConfigurationSource = + mock(XmlRepositoryConfigurationSource.class); + + when(mockRepositoryConfigurationSource.getElement()).thenReturn(mockElement); + when(mockElement.getAttribute(eq("mapping-context-ref"))).thenReturn(null); + + BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(); + + repositoryConfigurationExtension.postProcess(beanDefinitionBuilder, mockRepositoryConfigurationSource); + + PropertyValue mappingContextRef = beanDefinitionBuilder.getRawBeanDefinition().getPropertyValues() + .getPropertyValue("gemfireMappingContext"); + + assertThat(mappingContextRef.getValue(), is(equalTo((Object) defaultMappingContextReference))); + + verify(mockRepositoryConfigurationSource, times(1)).getElement(); + verify(mockElement, times(1)).getAttribute(eq("mapping-context-ref")); + } }