From ebd871b56669ee119ae7716842a754f8c324c90d Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 1 Mar 2017 16:24:20 +0100 Subject: [PATCH] DATACMNS-989 - Polishing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduced overload for CustomRepositoryImplementationDetector.detectCustomImplementation(…) to take a RepositoryConfiguration to simplify the invocation from the Spring container related client. Further simplification to unify invocations also from the CDI implementation to be done in 2.0. Expose getExcludeFilter() on RepositoryConfiguration to not have to inspect the configuration source on clients. Formatting and Javadoc. Missing license headers in newly created types. Original pull request: #195. --- .../repository/cdi/CdiRepositoryBean.java | 18 +++++------ ...notationRepositoryConfigurationSource.java | 10 +++--- ...ustomRepositoryImplementationDetector.java | 31 ++++++++++++++----- .../DefaultRepositoryConfiguration.java | 16 ++++++++-- .../RepositoryBeanDefinitionBuilder.java | 3 +- .../config/RepositoryConfiguration.java | 12 +++++-- .../config/RepositoryConfigurationSource.java | 5 +-- .../config/MyOtherRepositoryExtensions.java | 17 +++++++++- .../config/MyOtherRepositoryImpl.java | 28 ++++++++++++++--- .../excluded/MyOtherRepositoryImpl.java | 24 +++++++++++--- 10 files changed, 125 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java b/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java index 73805c7b1..6e3ba58f5 100644 --- a/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java +++ b/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2014 the original author or authors. + * Copyright 2011-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. @@ -246,7 +246,7 @@ public abstract class CdiRepositoryBean implements Bean, PassivationCapabl String className = getCustomImplementationClassName(repositoryType, cdiRepositoryConfiguration); AbstractBeanDefinition beanDefinition = detector.detectCustomImplementation(className, - Collections.singleton(repositoryType.getPackage().getName()), Collections.emptySet()); + Collections.singleton(repositoryType.getPackage().getName()), Collections. emptySet()); if (beanDefinition == null) { return null; @@ -255,8 +255,8 @@ public abstract class CdiRepositoryBean implements Bean, PassivationCapabl try { return Class.forName(beanDefinition.getBeanClassName()); } catch (ClassNotFoundException e) { - throw new UnsatisfiedResolutionException(String.format("Unable to resolve class for '%s'", - beanDefinition.getBeanClassName()), e); + throw new UnsatisfiedResolutionException( + String.format("Unable to resolve class for '%s'", beanDefinition.getBeanClassName()), e); } } @@ -367,9 +367,9 @@ public abstract class CdiRepositoryBean implements Bean, PassivationCapabl protected T create(CreationalContext creationalContext, Class repositoryType) { Bean customImplementationBean = getCustomImplementationBean(repositoryType, beanManager, qualifiers); - Object customImplementation = customImplementationBean == null ? null : beanManager.getReference( - customImplementationBean, customImplementationBean.getBeanClass(), - beanManager.createCreationalContext(customImplementationBean)); + Object customImplementation = customImplementationBean == null ? null + : beanManager.getReference(customImplementationBean, customImplementationBean.getBeanClass(), + beanManager.createCreationalContext(customImplementationBean)); return create(creationalContext, repositoryType, customImplementation); } @@ -393,8 +393,8 @@ public abstract class CdiRepositoryBean implements Bean, PassivationCapabl */ @Override public String toString() { - return String - .format("CdiRepositoryBean: type='%s', qualifiers=%s", repositoryType.getName(), qualifiers.toString()); + return String.format("CdiRepositoryBean: type='%s', qualifiers=%s", repositoryType.getName(), + qualifiers.toString()); } static enum DefaultCdiRepositoryConfiguration implements CdiRepositoryConfiguration { diff --git a/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java b/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java index 37952d642..f1ad95562 100644 --- a/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java +++ b/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 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. @@ -262,8 +262,8 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura for (Class filterClass : filterAttributes.getClassArray("value")) { switch (filterType) { case ANNOTATION: - Assert.isAssignable(Annotation.class, filterClass, "An error occured when processing a @ComponentScan " - + "ANNOTATION type filter: "); + Assert.isAssignable(Annotation.class, filterClass, + "An error occured when processing a @ComponentScan " + "ANNOTATION type filter: "); @SuppressWarnings("unchecked") Class annoClass = (Class) filterClass; typeFilters.add(new AnnotationTypeFilter(annoClass)); @@ -272,8 +272,8 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura typeFilters.add(new AssignableTypeFilter(filterClass)); break; case CUSTOM: - Assert.isAssignable(TypeFilter.class, filterClass, "An error occured when processing a @ComponentScan " - + "CUSTOM type filter: "); + Assert.isAssignable(TypeFilter.class, filterClass, + "An error occured when processing a @ComponentScan " + "CUSTOM type filter: "); typeFilters.add(BeanUtils.instantiateClass(filterClass, TypeFilter.class)); break; default: diff --git a/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java b/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java index 7e4f702b6..dfcd4a60b 100644 --- a/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java +++ b/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -69,14 +69,30 @@ public class CustomRepositoryImplementationDetector { this.resourceLoader = resourceLoader; } + /** + * Tries to detect a custom implementation for a repository bean by classpath scanning. + * + * @param configuration the {@link RepositoryConfiguration} to consider. + * @return the {@code AbstractBeanDefinition} of the custom implementation or {@literal null} if none found. + */ + public AbstractBeanDefinition detectCustomImplementation(RepositoryConfiguration configuration) { + + // TODO 2.0: Extract into dedicated interface for custom implementation lookup configuration. + + return detectCustomImplementation(configuration.getImplementationClassName(), // + configuration.getBasePackages(), // + configuration.getExcludeFilters()); + } + /** * Tries to detect a custom implementation for a repository bean by classpath scanning. * * @param className must not be {@literal null}. * @param basePackages must not be {@literal null}. - * @return the {@code AbstractBeanDefinition} of the custom implementation or {@literal null} if none found + * @return the {@code AbstractBeanDefinition} of the custom implementation or {@literal null} if none found. */ - public AbstractBeanDefinition detectCustomImplementation(String className, Iterable basePackages, Iterable excludeFilters) { + public AbstractBeanDefinition detectCustomImplementation(String className, Iterable basePackages, + Iterable excludeFilters) { Assert.notNull(className, "ClassName must not be null!"); Assert.notNull(basePackages, "BasePackages must not be null!"); @@ -91,7 +107,8 @@ public class CustomRepositoryImplementationDetector { provider.setResourcePattern(String.format(CUSTOM_IMPLEMENTATION_RESOURCE_PATTERN, className)); provider.setMetadataReaderFactory(metadataReaderFactory); provider.addIncludeFilter(new RegexPatternTypeFilter(pattern)); - for(TypeFilter excludeFilter : excludeFilters) { + + for (TypeFilter excludeFilter : excludeFilters) { provider.addExcludeFilter(excludeFilter); } @@ -114,8 +131,8 @@ public class CustomRepositoryImplementationDetector { implementationClassNames.add(bean.getBeanClassName()); } - throw new IllegalStateException(String.format( - "Ambiguous custom implementations detected! Found %s but expected a single implementation!", - StringUtils.collectionToCommaDelimitedString(implementationClassNames))); + throw new IllegalStateException( + String.format("Ambiguous custom implementations detected! Found %s but expected a single implementation!", + StringUtils.collectionToCommaDelimitedString(implementationClassNames))); } } diff --git a/src/main/java/org/springframework/data/repository/config/DefaultRepositoryConfiguration.java b/src/main/java/org/springframework/data/repository/config/DefaultRepositoryConfiguration.java index b1bb3a9ce..a9a22ea30 100644 --- a/src/main/java/org/springframework/data/repository/config/DefaultRepositoryConfiguration.java +++ b/src/main/java/org/springframework/data/repository/config/DefaultRepositoryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 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. @@ -16,6 +16,7 @@ package org.springframework.data.repository.config; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.core.type.filter.TypeFilter; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -26,8 +27,8 @@ import org.springframework.util.StringUtils; * * @author Oliver Gierke */ -public class DefaultRepositoryConfiguration implements - RepositoryConfiguration { +public class DefaultRepositoryConfiguration + implements RepositoryConfiguration { public static final String DEFAULT_REPOSITORY_IMPLEMENTATION_POSTFIX = "Impl"; private static final Key DEFAULT_QUERY_LOOKUP_STRATEGY = Key.CREATE_IF_NOT_FOUND; @@ -167,4 +168,13 @@ public class DefaultRepositoryConfiguration getExcludeFilters() { + return configurationSource.getExcludeFilters(); + } } 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 74907c4be..95600ee77 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java @@ -128,8 +128,7 @@ class RepositoryBeanDefinitionBuilder { return beanName; } - AbstractBeanDefinition beanDefinition = implementationDetector - .detectCustomImplementation(configuration.getImplementationClassName(), configuration.getBasePackages(), configuration.getConfigurationSource().getExcludeFilters()); + AbstractBeanDefinition beanDefinition = implementationDetector.detectCustomImplementation(configuration); if (null == beanDefinition) { return null; diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfiguration.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfiguration.java index e71f64d09..106f38f86 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfiguration.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 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. @@ -16,6 +16,7 @@ package org.springframework.data.repository.config; import org.springframework.beans.factory.FactoryBean; +import org.springframework.core.type.filter.TypeFilter; import org.springframework.data.repository.query.QueryLookupStrategy; /** @@ -101,9 +102,16 @@ public interface RepositoryConfiguration getExcludeFilters(); } diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSource.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSource.java index e475cab08..b7f02d70b 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSource.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 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. @@ -112,7 +112,8 @@ public interface RepositoryConfigurationSource { boolean usesExplicitFilters(); /** - * Return the {@link TypeFilter}s to define which types to exclude when scanning for repositories or repository implementations. + * Return the {@link TypeFilter}s to define which types to exclude when scanning for repositories or repository + * implementations. * * @return must not be {@literal null}. */ diff --git a/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryExtensions.java b/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryExtensions.java index 6652184b4..121bd2157 100644 --- a/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryExtensions.java +++ b/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryExtensions.java @@ -1,5 +1,20 @@ +/* + * 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; public interface MyOtherRepositoryExtensions { - String getImplementationId(); + String getImplementationId(); } diff --git a/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryImpl.java b/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryImpl.java index 305a0a4a9..d0ef2f452 100644 --- a/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryImpl.java +++ b/src/test/java/org/springframework/data/repository/config/MyOtherRepositoryImpl.java @@ -1,8 +1,28 @@ +/* + * 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; public class MyOtherRepositoryImpl implements MyOtherRepositoryExtensions { - @Override - public String getImplementationId() { - return getClass().getName(); - } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.MyOtherRepositoryExtensions#getImplementationId() + */ + @Override + public String getImplementationId() { + return getClass().getName(); + } } diff --git a/src/test/java/org/springframework/data/repository/config/excluded/MyOtherRepositoryImpl.java b/src/test/java/org/springframework/data/repository/config/excluded/MyOtherRepositoryImpl.java index 261110979..43b2553f2 100644 --- a/src/test/java/org/springframework/data/repository/config/excluded/MyOtherRepositoryImpl.java +++ b/src/test/java/org/springframework/data/repository/config/excluded/MyOtherRepositoryImpl.java @@ -1,10 +1,26 @@ +/* + * 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.excluded; import org.springframework.data.repository.config.MyOtherRepositoryExtensions; public class MyOtherRepositoryImpl implements MyOtherRepositoryExtensions { - @Override - public String getImplementationId() { - return getClass().getName(); - } + + @Override + public String getImplementationId() { + return getClass().getName(); + } }