From d5d51cd35f875a0d64d1d57bdfc6e17a616b31fa Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 12 Feb 2014 12:14:01 +0100 Subject: [PATCH] DATACMNS-439 - AnnotationRepositoryConfigSource now evaluates REGEX and ASPECTJ filters. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now leniently detect AspectJ and regular expression filters in an @Filter annotation in @Enable…Repositories annotations. --- ...notationRepositoryConfigurationSource.java | 45 +++++++++++++++++-- ...ositoryBeanDefinitionRegistrarSupport.java | 2 +- ...epositoryConfigurationSourceUnitTests.java | 16 ++++--- 3 files changed, 53 insertions(+), 10 deletions(-) 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 23715d0c0..a5d6b0ccc 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-2013 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. @@ -22,14 +22,18 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.regex.Pattern; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.FilterType; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.env.Environment; +import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.core.type.filter.AspectJTypeFilter; import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.core.type.filter.RegexPatternTypeFilter; import org.springframework.core.type.filter.TypeFilter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -51,6 +55,7 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura private final AnnotationMetadata metadata; private final AnnotationAttributes attributes; + private final ResourceLoader resourceLoader; /** * Creates a new {@link AnnotationRepositoryConfigurationSource} from the given {@link AnnotationMetadata} and @@ -58,18 +63,21 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura * * @param metadata must not be {@literal null}. * @param annotation must not be {@literal null}. + * @param resourceLoader must not be {@literal null}. * @param environment */ public AnnotationRepositoryConfigurationSource(AnnotationMetadata metadata, Class annotation, - Environment environment) { + ResourceLoader resourceLoader, Environment environment) { super(environment); Assert.notNull(metadata); Assert.notNull(annotation); + Assert.notNull(resourceLoader); this.attributes = new AnnotationAttributes(metadata.getAnnotationAttributes(annotation.getName())); this.metadata = metadata; + this.resourceLoader = resourceLoader; } /* @@ -196,6 +204,7 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura * @return */ private List typeFiltersFor(AnnotationAttributes filterAttributes) { + List typeFilters = new ArrayList(); FilterType filterType = filterAttributes.getEnum("type"); @@ -217,9 +226,39 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura typeFilters.add(BeanUtils.instantiateClass(filterClass, TypeFilter.class)); break; default: - throw new IllegalArgumentException("unknown filter type " + filterType); + throw new IllegalArgumentException("Unknown filter type " + filterType); } } + + for (String expression : getPatterns(filterAttributes)) { + + String rawName = filterType.toString(); + + if ("REGEX".equals(rawName)) { + typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression))); + } else if ("ASPECTJ".equals(rawName)) { + typeFilters.add(new AspectJTypeFilter(expression, this.resourceLoader.getClassLoader())); + } else { + throw new IllegalArgumentException("Unknown filter type " + filterType); + } + } + return typeFilters; } + + /** + * Safely reads the {@code pattern} attribute from the given {@link AnnotationAttributes} and returns an empty list if + * the attribute is not present. + * + * @param filterAttributes must not be {@literal null}. + * @return + */ + private String[] getPatterns(AnnotationAttributes filterAttributes) { + + try { + return filterAttributes.getStringArray("pattern"); + } catch (IllegalArgumentException o_O) { + return new String[0]; + } + } } diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupport.java index fe0fddcfb..4de153ae2 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupport.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupport.java @@ -88,7 +88,7 @@ public abstract class RepositoryBeanDefinitionRegistrarSupport implements Import defaultExternalResources(registry); AnnotationRepositoryConfigurationSource configuration = new AnnotationRepositoryConfigurationSource( - annotationMetadata, getAnnotation(), environment); + annotationMetadata, getAnnotation(), resourceLoader, environment); RepositoryConfigurationExtension extension = getExtension(); extension.registerBeansForRoot(registry, configuration); diff --git a/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java b/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java index e217f3218..5fd33eec6 100644 --- a/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 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. @@ -25,6 +25,7 @@ import org.junit.Test; import org.springframework.core.env.Environment; import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.StandardAnnotationMetadata; @@ -37,13 +38,16 @@ public class AnnotationRepositoryConfigurationSourceUnitTests { RepositoryConfigurationSource source; Environment environment; + ResourceLoader resourceLoader; @Before public void setUp() { AnnotationMetadata annotationMetadata = new StandardAnnotationMetadata(SampleConfiguration.class, true); environment = new StandardEnvironment(); - source = new AnnotationRepositoryConfigurationSource(annotationMetadata, EnableRepositories.class, environment); + resourceLoader = new DefaultResourceLoader(); + source = new AnnotationRepositoryConfigurationSource(annotationMetadata, EnableRepositories.class, resourceLoader, + environment); } @Test @@ -65,8 +69,8 @@ public class AnnotationRepositoryConfigurationSourceUnitTests { public void defaultsToPackageOfAnnotatedClass() { AnnotationMetadata metadata = new StandardAnnotationMetadata(DefaultConfiguration.class); - RepositoryConfigurationSource source = new AnnotationRepositoryConfigurationSource(metadata, - EnableRepositories.class, environment); + AnnotationRepositoryConfigurationSource source = new AnnotationRepositoryConfigurationSource(metadata, + EnableRepositories.class, resourceLoader, environment); Iterable packages = source.getBasePackages(); assertThat(packages, hasItem(DefaultConfiguration.class.getPackage().getName())); @@ -76,8 +80,8 @@ public class AnnotationRepositoryConfigurationSourceUnitTests { public void returnsConfiguredBasePackage() { AnnotationMetadata metadata = new StandardAnnotationMetadata(DefaultConfigurationWithBasePackage.class); - RepositoryConfigurationSource source = new AnnotationRepositoryConfigurationSource(metadata, - EnableRepositories.class, environment); + AnnotationRepositoryConfigurationSource source = new AnnotationRepositoryConfigurationSource(metadata, + EnableRepositories.class, resourceLoader, environment); Iterable packages = source.getBasePackages(); assertThat(packages, hasItem("foo"));