diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java index 75f0d7ead..f351b8707 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java @@ -31,6 +31,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; +import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReaderFactory; @@ -175,7 +176,8 @@ class RepositoryBeanDefinitionBuilder { ClassMetadata classMetadata = getClassMetadata(configuration.getRepositoryInterface()); - return Arrays.stream(classMetadata.getInterfaceNames()) + return Arrays.stream(classMetadata.getInterfaceNames()) // + .filter(this::isFragmentInterfaceCandidate) // .map(it -> detectRepositoryFragmentConfiguration(configuration, it)) // .filter(Optional::isPresent) // .map(Optional::get) // @@ -184,6 +186,13 @@ class RepositoryBeanDefinitionBuilder { .collect(Collectors.toList()); } + private boolean isFragmentInterfaceCandidate(String interfaceName) { + + AnnotationMetadata metadata = getAnnotationMetadata(interfaceName); + + return !metadata.hasAnnotation(NoRepositoryBean.class.getName()); + } + private Optional detectRepositoryFragmentConfiguration( RepositoryConfiguration configuration, String fragmentInterfaceName) { @@ -253,6 +262,15 @@ class RepositoryBeanDefinitionBuilder { } } + private AnnotationMetadata getAnnotationMetadata(String className) { + + try { + return metadataReaderFactory.getMetadataReader(className).getAnnotationMetadata(); + } catch (IOException e) { + throw new BeanDefinitionStoreException(String.format("Cannot parse %s metadata.", className), e); + } + } + private static List getExclusions(RepositoryConfiguration configuration) { return Stream diff --git a/src/test/java/org/springframework/data/repository/config/ExcludedRepository.java b/src/test/java/org/springframework/data/repository/config/ExcludedRepository.java new file mode 100644 index 000000000..cee0b362d --- /dev/null +++ b/src/test/java/org/springframework/data/repository/config/ExcludedRepository.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017 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.repository.config; + +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.Repository; + +/** + * Interface specifying customizations for a base repository implementation. + * + * @author Mark Paluch + */ +@NoRepositoryBean +public interface ExcludedRepository extends Repository { + String getImplementationId(); +} diff --git a/src/test/java/org/springframework/data/repository/config/ExcludedRepositoryImpl.java b/src/test/java/org/springframework/data/repository/config/ExcludedRepositoryImpl.java new file mode 100644 index 000000000..dfff64da1 --- /dev/null +++ b/src/test/java/org/springframework/data/repository/config/ExcludedRepositoryImpl.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017 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.repository.config; + +/** + * @author Mark Paluch + */ +public class ExcludedRepositoryImpl implements ExcludedRepository { + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.ExcludedRepository#getImplementationId() + */ + @Override + public String getImplementationId() { + return getClass().getName(); + } +} diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java b/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java index 2da112164..5add796e4 100755 --- a/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java @@ -28,6 +28,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.FilterType; import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.type.AnnotationMetadata; @@ -71,6 +73,17 @@ public class RepositoryBeanDefinitionRegistrarSupportUnitTests { assertNoBeanDefinitionRegisteredFor("profileRepository"); } + @Test // DATACMNS-1147 + public void registersBeanDefinitionWithoutFragmentImplementations() { + + AnnotationMetadata metadata = new StandardAnnotationMetadata(FragmentExclusionConfiguration.class, true); + + registrar.registerBeanDefinitions(metadata, registry); + + assertBeanDefinitionRegisteredFor("repositoryWithFragmentExclusion"); + assertNoBeanDefinitionRegisteredFor("excludedRepositoryImpl"); + } + @Test // DATACMNS-360 public void registeredProfileRepositoriesIfProfileActivated() { @@ -135,4 +148,11 @@ public class RepositoryBeanDefinitionRegistrarSupportUnitTests { return "commons"; } } + + @EnableRepositories( + includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = RepositoryWithFragmentExclusion.class), + basePackageClasses = RepositoryWithFragmentExclusion.class) + static class FragmentExclusionConfiguration { + + } } diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryWithFragmentExclusion.java b/src/test/java/org/springframework/data/repository/config/RepositoryWithFragmentExclusion.java new file mode 100644 index 000000000..8b053ca29 --- /dev/null +++ b/src/test/java/org/springframework/data/repository/config/RepositoryWithFragmentExclusion.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017 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.repository.config; + +import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSourceUnitTests.Person; + +/** + * Repository with customized base base interface. + * + * @author Mark Paluch + */ +public interface RepositoryWithFragmentExclusion extends ExcludedRepository {} diff --git a/src/test/java/org/springframework/data/repository/config/SampleConfiguration.java b/src/test/java/org/springframework/data/repository/config/SampleConfiguration.java index 9f30af2a9..df83b742e 100644 --- a/src/test/java/org/springframework/data/repository/config/SampleConfiguration.java +++ b/src/test/java/org/springframework/data/repository/config/SampleConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 the original author or authors. + * Copyright 2012-2017 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,7 +18,10 @@ package org.springframework.data.repository.config; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.FilterType; -@EnableRepositories(excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyOtherRepository.class), basePackageClasses = AnnotationRepositoryConfigurationSourceUnitTests.class) +@EnableRepositories( + excludeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyOtherRepository.class), + @Filter(type = FilterType.ASSIGNABLE_TYPE, value = ExcludedRepository.class) }, + basePackageClasses = AnnotationRepositoryConfigurationSourceUnitTests.class) class SampleConfiguration { }