Support nested meta-annotations in AnnotationUtils

Prior to this commit, AnnotationUtils.findAnnotation(Class, Class)
claimed to recursively search through annotations; however, only one
level of annotations was supported by the algorithm.

This commit alters the search algorithm so that nested meta-annotations
(i.e., meta-annotations on meta-annotations) are also supported.

Issue: SPR-11448
This commit is contained in:
Sam Brannen
2014-02-19 18:27:44 +01:00
parent 8f0849f328
commit 42a36349e9
2 changed files with 102 additions and 23 deletions

View File

@@ -111,6 +111,33 @@ public class AnnotationUtilsTests {
assertEquals("meta1", component.value());
}
@Test
public void findAnnotationOnMetaMetaAnnotatedClass() {
Component component = AnnotationUtils.findAnnotation(MetaMetaAnnotatedClass.class, Component.class);
assertNotNull("Should find meta-annotation on composed annotation on class", component);
assertEquals("meta2", component.value());
}
@Test
public void findAnnotationOnMetaMetaMetaAnnotatedClass() {
Component component = AnnotationUtils.findAnnotation(MetaMetaMetaAnnotatedClass.class, Component.class);
assertNotNull("Should find meta-annotation on meta-annotation on composed annotation on class", component);
assertEquals("meta2", component.value());
}
@Test
public void findAnnotationOnAnnotatedClassWithMissingTargetMetaAnnotation() {
// TransactionalClass is NOT annotated or meta-annotated with @Component
Component component = AnnotationUtils.findAnnotation(TransactionalClass.class, Component.class);
assertNull("Should not find @Component on TransactionalClass", component);
}
@Test
public void findAnnotationOnMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() {
Component component = AnnotationUtils.findAnnotation(MetaCycleAnnotatedClass.class, Component.class);
assertNull("Should not find @Component on MetaCycleAnnotatedClass", component);
}
@Test
public void testFindAnnotationDeclaringClass() throws Exception {
// no class-level annotation
@@ -335,6 +362,31 @@ public class AnnotationUtilsTests {
@interface Meta2 {
}
@Meta2
@Retention(RetentionPolicy.RUNTIME)
@interface MetaMeta {
}
@MetaMeta
@Retention(RetentionPolicy.RUNTIME)
@interface MetaMetaMeta {
}
@MetaCycle3
@Retention(RetentionPolicy.RUNTIME)
@interface MetaCycle1 {
}
@MetaCycle1
@Retention(RetentionPolicy.RUNTIME)
@interface MetaCycle2 {
}
@MetaCycle2
@Retention(RetentionPolicy.RUNTIME)
@interface MetaCycle3 {
}
@Meta1
static interface InterfaceWithMetaAnnotation {
}
@@ -343,6 +395,17 @@ public class AnnotationUtilsTests {
static class ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface implements InterfaceWithMetaAnnotation {
}
@MetaMeta
static class MetaMetaAnnotatedClass {
}
@MetaMetaMeta
static class MetaMetaMetaAnnotatedClass {
}
@MetaCycle3
static class MetaCycleAnnotatedClass {
}
public static interface AnnotatedInterface {