diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java index 220e293824..a6baf3a8e7 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java @@ -37,7 +37,6 @@ import org.junit.jupiter.api.Test; import org.springframework.core.annotation.AnnotationTypeMapping.MirrorSets; import org.springframework.core.annotation.AnnotationTypeMapping.MirrorSets.MirrorSet; import org.springframework.lang.UsesSunMisc; -import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import static java.util.stream.Collectors.toList; @@ -86,6 +85,14 @@ class AnnotationTypeMappingsTests { WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class); } + @Test + void forAnnotationTypeWhenRepeatableMetaAnnotationIsFiltered() { + AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class, + Repeating.class.getName()::equals); + assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType) + .containsExactly(WithRepeatedMetaAnnotations.class); + } + @Test void forAnnotationTypeWhenSelfAnnotatedReturnsMapping() { AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SelfAnnotated.class); @@ -477,16 +484,6 @@ class AnnotationTypeMappingsTests { return result; } - @Test - void forAnnotationTypeWhenRepeatableMetaAnnotationFilterd() { - AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class, - annotationType -> - ObjectUtils.nullSafeEquals(annotationType, Repeating.class.getName())); - assertThat(getAll(mappings)).flatExtracting( - AnnotationTypeMapping::getAnnotationType).containsExactly( - WithRepeatedMetaAnnotations.class); - } - @Nullable private Method getAliasMapping(AnnotationTypeMapping mapping, int attributeIndex) { int mapped = mapping.getAliasMapping(attributeIndex); diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsRepeatableAnnotationTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsRepeatableAnnotationTests.java index 0b9fe0bbdb..40b1fdf5b8 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsRepeatableAnnotationTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsRepeatableAnnotationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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 java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.AnnotatedElement; import java.util.Set; +import java.util.stream.Stream; import org.assertj.core.api.ThrowableTypeAssert; import org.junit.jupiter.api.Test; @@ -222,14 +223,35 @@ class MergedAnnotationsRepeatableAnnotationTests { "B", "C"); } - private Set getAnnotations( - Class container, Class repeatable, - SearchStrategy searchStrategy, AnnotatedElement element) { + @Test + void typeHierarchyAnnotationsWithLocalComposedAnnotationWhoseRepeatableMetaAnnotationsAreFiltered() { + Class element = WithRepeatedMetaAnnotationsClass.class; + SearchStrategy searchStrategy = SearchStrategy.TYPE_HIERARCHY; + AnnotationFilter annotationFilter = PeteRepeat.class.getName()::equals; + + Set annotations = getAnnotations(null, PeteRepeat.class, searchStrategy, element, annotationFilter); + assertThat(annotations).isEmpty(); + + MergedAnnotations mergedAnnotations = MergedAnnotations.from(element, searchStrategy, + RepeatableContainers.standardRepeatables(), annotationFilter); + Stream> annotationTypes = mergedAnnotations.stream() + .map(MergedAnnotation::synthesize) + .map(Annotation::annotationType); + assertThat(annotationTypes).containsExactly(WithRepeatedMetaAnnotations.class, Noninherited.class, Noninherited.class); + } + + private Set getAnnotations(Class container, + Class repeatable, SearchStrategy searchStrategy, AnnotatedElement element) { + + return getAnnotations(container, repeatable, searchStrategy, element, AnnotationFilter.PLAIN); + } + + private Set getAnnotations(Class container, + Class repeatable, SearchStrategy searchStrategy, AnnotatedElement element, AnnotationFilter annotationFilter) { + RepeatableContainers containers = RepeatableContainers.of(repeatable, container); - MergedAnnotations annotations = MergedAnnotations.from(element, - searchStrategy, containers, AnnotationFilter.PLAIN); - return annotations.stream(repeatable).collect( - MergedAnnotationCollectors.toAnnotationSet()); + MergedAnnotations annotations = MergedAnnotations.from(element, searchStrategy, containers, annotationFilter); + return annotations.stream(repeatable).collect(MergedAnnotationCollectors.toAnnotationSet()); } private void nonRepeatableRequirements(Exception ex) { @@ -414,4 +436,17 @@ class MergedAnnotationsRepeatableAnnotationTests { } + @Retention(RetentionPolicy.RUNTIME) + @PeteRepeat("A") + @PeteRepeat("B") + @interface WithRepeatedMetaAnnotations { + } + + @WithRepeatedMetaAnnotations + @PeteRepeat("C") + @Noninherited("X") + @Noninherited("Y") + static class WithRepeatedMetaAnnotationsClass { + } + }