/** * Find all <em>repeatable annotations</em> of the specified {@code annotationType} * within the annotation hierarchy <em>above</em> the supplied {@code element}; * and for each annotation found, merge that annotation's attributes with * <em>matching</em> attributes from annotations in lower levels of the annotation * hierarchy and synthesize the results back into an annotation of the specified * {@code annotationType}. * <p>The container type that holds the repeatable annotations will be looked up * via {@link java.lang.annotation.Repeatable}. * <p>{@link AliasFor @AliasFor} semantics are fully supported, both within a * single annotation and within annotation hierarchies. * <p>This method follows <em>find semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element (never {@code null}) * @param annotationType the annotation type to find (never {@code null}) * @return the set of all merged repeatable {@code Annotations} found, * or an empty set if none were found * @throws IllegalArgumentException if the {@code element} or {@code annotationType} * is {@code null}, or if the container type cannot be resolved * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #findAllMergedAnnotations(AnnotatedElement, Class) * @see #findMergedRepeatableAnnotations(AnnotatedElement, Class, Class) */ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return findMergedRepeatableAnnotations(element, annotationType, null); }
/** * Find all <em>repeatable annotations</em> of the specified {@code annotationType} * within the annotation hierarchy <em>above</em> the supplied {@code element}; * and for each annotation found, merge that annotation's attributes with * <em>matching</em> attributes from annotations in lower levels of the annotation * hierarchy and synthesize the results back into an annotation of the specified * {@code annotationType}. * <p>The container type that holds the repeatable annotations will be looked up * via {@link java.lang.annotation.Repeatable}. * <p>{@link AliasFor @AliasFor} semantics are fully supported, both within a * single annotation and within annotation hierarchies. * <p>This method follows <em>find semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element (never {@code null}) * @param annotationType the annotation type to find (never {@code null}) * @return the set of all merged repeatable {@code Annotations} found, * or an empty set if none were found * @throws IllegalArgumentException if the {@code element} or {@code annotationType} * is {@code null}, or if the container type cannot be resolved * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #findAllMergedAnnotations(AnnotatedElement, Class) * @see #findMergedRepeatableAnnotations(AnnotatedElement, Class, Class) */ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return findMergedRepeatableAnnotations(element, annotationType, null); }
@Test public void findNonRepeatableAnnotation() { expectNonRepeatableAnnotation(); findMergedRepeatableAnnotations(getClass(), NonRepeatable.class); }
@Test public void findInvalidRepeatableAnnotationContainerMissingValueAttribute() { expectContainerMissingValueAttribute(); findMergedRepeatableAnnotations(getClass(), InvalidRepeatable.class, ContainerMissingValueAttribute.class); }
@Test public void findInvalidRepeatableAnnotationContainerWithNonArrayValueAttribute() { expectContainerWithNonArrayValueAttribute(); findMergedRepeatableAnnotations(getClass(), InvalidRepeatable.class, ContainerWithNonArrayValueAttribute.class); }
@Test public void findInvalidRepeatableAnnotationContainerWithArrayValueAttributeButWrongComponentType() { expectContainerWithArrayValueAttributeButWrongComponentType(); findMergedRepeatableAnnotations(getClass(), InvalidRepeatable.class, ContainerWithArrayValueAttributeButWrongComponentType.class); }
@Test public void findNoninheritedComposedRepeatableAnnotationsOnSuperclass() { Class<?> element = SubNoninheritedRepeatableClass.class; Set<Noninherited> annotations = findMergedRepeatableAnnotations(element, Noninherited.class); assertNoninheritedRepeatableAnnotations(annotations); }
@Test public void findNoninheritedComposedRepeatableAnnotationsOnClass() { Class<?> element = NoninheritedRepeatableClass.class; Set<Noninherited> annotations = findMergedRepeatableAnnotations(element, Noninherited.class); assertNoninheritedRepeatableAnnotations(annotations); }
private void assertFindRepeatableAnnotations(AnnotatedElement element) { assertNotNull(element); Set<PeteRepeat> peteRepeats = findMergedRepeatableAnnotations(element, PeteRepeat.class); assertNotNull(peteRepeats); assertEquals(3, peteRepeats.size()); Iterator<PeteRepeat> iterator = peteRepeats.iterator(); assertEquals("A", iterator.next().value()); assertEquals("B", iterator.next().value()); assertEquals("C", iterator.next().value()); }
/** * Find all <em>repeatable annotations</em> of the specified {@code annotationType} * within the annotation hierarchy <em>above</em> the supplied {@code element}; * and for each annotation found, merge that annotation's attributes with * <em>matching</em> attributes from annotations in lower levels of the annotation * hierarchy and synthesize the results back into an annotation of the specified * {@code annotationType}. * <p>The container type that holds the repeatable annotations will be looked up * via {@link java.lang.annotation.Repeatable}. * <p>{@link AliasFor @AliasFor} semantics are fully supported, both within a * single annotation and within annotation hierarchies. * <p>This method follows <em>find semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element (never {@code null}) * @param annotationType the annotation type to find (never {@code null}) * @return the set of all merged repeatable {@code Annotations} found, * or an empty set if none were found * @throws IllegalArgumentException if the {@code element} or {@code annotationType} * is {@code null}, or if the container type cannot be resolved * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #findAllMergedAnnotations(AnnotatedElement, Class) * @see #findMergedRepeatableAnnotations(AnnotatedElement, Class, Class) */ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return findMergedRepeatableAnnotations(element, annotationType, null); }
/** * Find all <em>repeatable annotations</em> of the specified {@code annotationType} * within the annotation hierarchy <em>above</em> the supplied {@code element}; * and for each annotation found, merge that annotation's attributes with * <em>matching</em> attributes from annotations in lower levels of the annotation * hierarchy and synthesize the results back into an annotation of the specified * {@code annotationType}. * <p>The container type that holds the repeatable annotations will be looked up * via {@link java.lang.annotation.Repeatable}. * <p>{@link AliasFor @AliasFor} semantics are fully supported, both within a * single annotation and within annotation hierarchies. * <p>This method follows <em>find semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element (never {@code null}) * @param annotationType the annotation type to find (never {@code null}) * @return the set of all merged repeatable {@code Annotations} found, * or an empty set if none were found * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #findAllMergedAnnotations(AnnotatedElement, Class) * @see #findMergedRepeatableAnnotations(AnnotatedElement, Class, Class) * @throws IllegalArgumentException if the {@code element} or {@code annotationType} * is {@code null}, or if the container type cannot be resolved */ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return findMergedRepeatableAnnotations(element, annotationType, null); }
@SuppressWarnings("unchecked") public <A extends Annotation> Set<A> findAnnotations(final Class<A> annotationType) { return (Set<A>) repeatableAnnotationCache.computeIfAbsent(annotationType, it -> AnnotatedElementUtils.findMergedRepeatableAnnotations(getType(), it)); }
@SuppressWarnings("unchecked") public <A extends Annotation> Set<A> findAnnotations(final Class<A> annotationType) { return (Set<A>) repeatableAnnotationCache.computeIfAbsent(annotationType, it -> AnnotatedElementUtils.findMergedRepeatableAnnotations(getType(), it)); }
Class<A> annotationType) { return findMergedRepeatableAnnotations(element, annotationType, null);