DATACMNS-989 - Polishing.

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.
This commit is contained in:
Oliver Gierke
2017-03-01 16:24:20 +01:00
parent 3ca77831e1
commit ebd871b566
10 changed files with 125 additions and 39 deletions

View File

@@ -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<T> implements Bean<T>, PassivationCapabl
String className = getCustomImplementationClassName(repositoryType, cdiRepositoryConfiguration);
AbstractBeanDefinition beanDefinition = detector.detectCustomImplementation(className,
Collections.singleton(repositoryType.getPackage().getName()), Collections.<TypeFilter>emptySet());
Collections.singleton(repositoryType.getPackage().getName()), Collections.<TypeFilter> emptySet());
if (beanDefinition == null) {
return null;
@@ -255,8 +255,8 @@ public abstract class CdiRepositoryBean<T> implements Bean<T>, 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<T> implements Bean<T>, PassivationCapabl
protected T create(CreationalContext<T> creationalContext, Class<T> 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<T> implements Bean<T>, 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 {

View File

@@ -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<Annotation> annoClass = (Class<Annotation>) 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:

View File

@@ -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<String> basePackages, Iterable<TypeFilter> excludeFilters) {
public AbstractBeanDefinition detectCustomImplementation(String className, Iterable<String> basePackages,
Iterable<TypeFilter> 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)));
}
}

View File

@@ -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<T extends RepositoryConfigurationSource> implements
RepositoryConfiguration<T> {
public class DefaultRepositoryConfiguration<T extends RepositoryConfigurationSource>
implements RepositoryConfiguration<T> {
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<T extends RepositoryConfigurationSou
public boolean isLazyInit() {
return definition.isLazyInit();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfiguration#getExcludeFilters()
*/
@Override
public Iterable<TypeFilter> getExcludeFilters() {
return configurationSource.getExcludeFilters();
}
}

View File

@@ -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;

View File

@@ -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<T extends RepositoryConfigurationSource
T getConfigurationSource();
/**
* Returns whether to inititialize the repository proxy lazily.
* Returns whether to initialize the repository proxy lazily.
*
* @return
*/
boolean isLazyInit();
/**
* Returns the {@link TypeFilter}s to be used to exclude packages from repository scanning.
*
* @return
*/
Iterable<TypeFilter> getExcludeFilters();
}

View File

@@ -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}.
*/