/** * Get 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>get 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 #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) * @see #getMergedRepeatableAnnotations(AnnotatedElement, Class, Class) */ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return getMergedRepeatableAnnotations(element, annotationType, null); }
/** * Get 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>get 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 #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) * @see #getMergedRepeatableAnnotations(AnnotatedElement, Class, Class) */ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return getMergedRepeatableAnnotations(element, annotationType, null); }
/** * Execute SQL scripts configured via {@link Sql @Sql} for the supplied * {@link TestContext} and {@link ExecutionPhase}. */ private void executeSqlScripts(TestContext testContext, ExecutionPhase executionPhase) throws Exception { boolean classLevel = false; Set<Sql> sqlAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations( testContext.getTestMethod(), Sql.class, SqlGroup.class); if (sqlAnnotations.isEmpty()) { sqlAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations( testContext.getTestClass(), Sql.class, SqlGroup.class); if (!sqlAnnotations.isEmpty()) { classLevel = true; } } for (Sql sql : sqlAnnotations) { executeSqlScripts(sql, executionPhase, testContext, classLevel); } }
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> { Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations( method, Scheduled.class, Schedules.class); return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup<Set<JmsListener>>) method -> { Set<JmsListener> listenerMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations( method, JmsListener.class, JmsListeners.class); return (!listenerMethods.isEmpty() ? listenerMethods : null);
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> { Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations( method, Scheduled.class, Schedules.class); return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
@Test public void getInvalidRepeatableAnnotationContainerWithNonArrayValueAttribute() { expectContainerWithNonArrayValueAttribute(); getMergedRepeatableAnnotations(getClass(), InvalidRepeatable.class, ContainerWithNonArrayValueAttribute.class); }
@Test public void getInvalidRepeatableAnnotationContainerWithArrayValueAttributeButWrongComponentType() { expectContainerWithArrayValueAttributeButWrongComponentType(); getMergedRepeatableAnnotations(getClass(), InvalidRepeatable.class, ContainerWithArrayValueAttributeButWrongComponentType.class); }
@Test public void getNonRepeatableAnnotation() { expectNonRepeatableAnnotation(); getMergedRepeatableAnnotations(getClass(), NonRepeatable.class); }
@Test public void getInvalidRepeatableAnnotationContainerMissingValueAttribute() { expectContainerMissingValueAttribute(); getMergedRepeatableAnnotations(getClass(), InvalidRepeatable.class, ContainerMissingValueAttribute.class); }
@Test public void getNoninheritedComposedRepeatableAnnotationsOnClass() { Class<?> element = NoninheritedRepeatableClass.class; Set<Noninherited> annotations = getMergedRepeatableAnnotations(element, Noninherited.class); assertNoninheritedRepeatableAnnotations(annotations); }
@Test public void getNoninheritedComposedRepeatableAnnotationsOnSuperclass() { Class<?> element = SubNoninheritedRepeatableClass.class; Set<Noninherited> annotations = getMergedRepeatableAnnotations(element, Noninherited.class); assertNotNull(annotations); assertEquals(0, annotations.size()); }
private void assertGetRepeatableAnnotations(AnnotatedElement element) { assertNotNull(element); Set<PeteRepeat> peteRepeats = getMergedRepeatableAnnotations(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()); }
/** * Get 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>get 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 #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) * @see #getMergedRepeatableAnnotations(AnnotatedElement, Class, Class) */ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return getMergedRepeatableAnnotations(element, annotationType, null); }
/** * Get 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>get 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 #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) * @see #getMergedRepeatableAnnotations(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> getMergedRepeatableAnnotations(AnnotatedElement element, Class<A> annotationType) { return getMergedRepeatableAnnotations(element, annotationType, null); }
/** * Execute SQL scripts configured via {@link Sql @Sql} for the supplied * {@link TestContext} and {@link ExecutionPhase}. */ private void executeSqlScripts(TestContext testContext, ExecutionPhase executionPhase) throws Exception { boolean classLevel = false; Set<Sql> sqlAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations( testContext.getTestMethod(), Sql.class, SqlGroup.class); if (sqlAnnotations.isEmpty()) { sqlAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations( testContext.getTestClass(), Sql.class, SqlGroup.class); if (!sqlAnnotations.isEmpty()) { classLevel = true; } } for (Sql sql : sqlAnnotations) { executeSqlScripts(sql, executionPhase, testContext, classLevel); } }
/** * Execute SQL scripts configured via {@link Sql @Sql} for the supplied * {@link TestContext} and {@link ExecutionPhase}. */ private void executeSqlScripts(TestContext testContext, ExecutionPhase executionPhase) throws Exception { boolean classLevel = false; Set<Sql> sqlAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations( testContext.getTestMethod(), Sql.class, SqlGroup.class); if (sqlAnnotations.isEmpty()) { sqlAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations( testContext.getTestClass(), Sql.class, SqlGroup.class); if (!sqlAnnotations.isEmpty()) { classLevel = true; } } for (Sql sql : sqlAnnotations) { executeSqlScripts(sql, executionPhase, testContext, classLevel); } }
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup<Set<JmsListener>>) method -> { Set<JmsListener> listenerMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations( method, JmsListener.class, JmsListeners.class); return (!listenerMethods.isEmpty() ? listenerMethods : null);
(MethodIntrospector.MetadataLookup<Set<AzureMessageListener>>) method -> { Set<AzureMessageListener> listenerMethods = AnnotatedElementUtils .getMergedRepeatableAnnotations(method, AzureMessageListener.class, AzureMessageListeners.class); return (!listenerMethods.isEmpty() ? listenerMethods : null);
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> { Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations( method, Scheduled.class, Schedules.class); return (!scheduledMethods.isEmpty() ? scheduledMethods : null);