/** * Determine if an annotation of the specified {@code annotationName} is * <em>present</em> on the supplied {@link AnnotatedElement} or within the * annotation hierarchy <em>above</em> the specified element. * <p>If this method returns {@code true}, then {@link #getMergedAnnotationAttributes} * will return a non-null value. * <p>This method follows <em>get semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element * @param annotationName the fully qualified class name of the annotation type to find * @return {@code true} if a matching annotation is present */ public static boolean isAnnotated(AnnotatedElement element, String annotationName) { return Boolean.TRUE.equals(searchWithGetSemantics(element, null, annotationName, alwaysTrueAnnotationProcessor)); }
private static boolean hasMetaAnnotationTypes( AnnotatedElement element, @Nullable Class<? extends Annotation> annotationType, @Nullable String annotationName) { return Boolean.TRUE.equals( searchWithGetSemantics(element, annotationType, annotationName, new SimpleAnnotationProcessor<Boolean>() { @Override @Nullable public Boolean process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { return (metaDepth > 0 ? Boolean.TRUE : CONTINUE); } })); }
/** * Determine if an annotation of the specified {@code annotationType} * is <em>present</em> on the supplied {@link AnnotatedElement} or * within the annotation hierarchy <em>above</em> the specified element. * <p>If this method returns {@code true}, then {@link #getMergedAnnotationAttributes} * will return a non-null value. * <p>This method follows <em>get semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element * @param annotationType the annotation type to find * @return {@code true} if a matching annotation is present * @since 4.2.3 * @see #hasAnnotation(AnnotatedElement, Class) */ public static boolean isAnnotated(AnnotatedElement element, Class<? extends Annotation> annotationType) { // Shortcut: directly present on the element, with no processing needed? if (element.isAnnotationPresent(annotationType)) { return true; } return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationType, null, alwaysTrueAnnotationProcessor)); }
/** * Search for annotations of the specified {@code annotationName} or * {@code annotationType} on the specified {@code element}, following * <em>get semantics</em>. * @param element the annotated element * @param annotationType the annotation type to find * @param annotationName the fully qualified class name of the annotation * type to find (as an alternative to {@code annotationType}) * @param processor the processor to delegate to * @return the result of the processor (potentially {@code null}) */ @Nullable private static <T> T searchWithGetSemantics(AnnotatedElement element, @Nullable Class<? extends Annotation> annotationType, @Nullable String annotationName, Processor<T> processor) { return searchWithGetSemantics(element, (annotationType != null ? Collections.singleton(annotationType) : Collections.emptySet()), annotationName, null, processor); }
/** * Determine if an annotation of the specified {@code annotationName} is * <em>present</em> on the supplied {@link AnnotatedElement} or within the * annotation hierarchy <em>above</em> the specified element. * <p>If this method returns {@code true}, then {@link #getMergedAnnotationAttributes} * will return a non-null value. * <p>This method follows <em>get semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element * @param annotationName the fully qualified class name of the annotation type to find * @return {@code true} if a matching annotation is present */ public static boolean isAnnotated(AnnotatedElement element, String annotationName) { return Boolean.TRUE.equals(searchWithGetSemantics(element, null, annotationName, alwaysTrueAnnotationProcessor)); }
private static boolean hasMetaAnnotationTypes( AnnotatedElement element, @Nullable Class<? extends Annotation> annotationType, @Nullable String annotationName) { return Boolean.TRUE.equals( searchWithGetSemantics(element, annotationType, annotationName, new SimpleAnnotationProcessor<Boolean>() { @Override @Nullable public Boolean process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { return (metaDepth > 0 ? Boolean.TRUE : CONTINUE); } })); }
private static Set<String> getMetaAnnotationTypes(AnnotatedElement element, @Nullable Annotation composed) { if (composed == null) { return Collections.emptySet(); } try { final Set<String> types = new LinkedHashSet<>(); searchWithGetSemantics(composed.annotationType(), Collections.emptySet(), null, null, new SimpleAnnotationProcessor<Object>(true) { @Override @Nullable public Object process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { types.add(annotation.annotationType().getName()); return CONTINUE; } }, new HashSet<>(), 1); return types; } catch (Throwable ex) { AnnotationUtils.rethrowAnnotationConfigurationException(ex); throw new IllegalStateException("Failed to introspect annotations on " + element, ex); } }
/** * Determine if an annotation of the specified {@code annotationType} * is <em>present</em> on the supplied {@link AnnotatedElement} or * within the annotation hierarchy <em>above</em> the specified element. * <p>If this method returns {@code true}, then {@link #getMergedAnnotationAttributes} * will return a non-null value. * <p>This method follows <em>get semantics</em> as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. * @param element the annotated element * @param annotationType the annotation type to find * @return {@code true} if a matching annotation is present * @since 4.2.3 * @see #hasAnnotation(AnnotatedElement, Class) */ public static boolean isAnnotated(AnnotatedElement element, Class<? extends Annotation> annotationType) { // Shortcut: directly present on the element, with no processing needed? if (element.isAnnotationPresent(annotationType)) { return true; } return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationType, null, alwaysTrueAnnotationProcessor)); }
/** * Search for annotations of the specified {@code annotationName} or * {@code annotationType} on the specified {@code element}, following * <em>get semantics</em>. * @param element the annotated element * @param annotationTypes the annotation types to find * @param annotationName the fully qualified class name of the annotation * type to find (as an alternative to {@code annotationType}) * @param containerType the type of the container that holds repeatable * annotations, or {@code null} if the annotation is not repeatable * @param processor the processor to delegate to * @return the result of the processor (potentially {@code null}) * @since 4.3 */ @Nullable private static <T> T searchWithGetSemantics(AnnotatedElement element, Set<Class<? extends Annotation>> annotationTypes, @Nullable String annotationName, @Nullable Class<? extends Annotation> containerType, Processor<T> processor) { try { return searchWithGetSemantics(element, annotationTypes, annotationName, containerType, processor, new HashSet<>(), 0); } catch (Throwable ex) { AnnotationUtils.rethrowAnnotationConfigurationException(ex); throw new IllegalStateException("Failed to introspect annotations on " + element, ex); } }
searchWithGetSemantics(element, null, annotationName, new SimpleAnnotationProcessor<Object>() { @Override @Nullable
/** * Search for annotations of the specified {@code annotationName} or * {@code annotationType} on the specified {@code element}, following * <em>get semantics</em>. * @param element the annotated element * @param annotationType the annotation type to find * @param annotationName the fully qualified class name of the annotation * type to find (as an alternative to {@code annotationType}) * @param processor the processor to delegate to * @return the result of the processor (potentially {@code null}) */ @Nullable private static <T> T searchWithGetSemantics(AnnotatedElement element, @Nullable Class<? extends Annotation> annotationType, @Nullable String annotationName, Processor<T> processor) { return searchWithGetSemantics(element, (annotationType != null ? Collections.singleton(annotationType) : Collections.emptySet()), annotationName, null, processor); }
/** * Get the first annotation of the specified {@code annotationType} within * the annotation hierarchy <em>above</em> the supplied {@code element} and * merge that annotation's attributes with <em>matching</em> attributes from * annotations in lower levels of the annotation hierarchy. * <p>{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. * <p>This method delegates to {@link #getMergedAnnotationAttributes(AnnotatedElement, String)}. * @param element the annotated element * @param annotationType the annotation type to find * @return the merged {@code AnnotationAttributes}, or {@code null} if not found * @since 4.2 * @see #getMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean) * @see #findMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean) * @see #getMergedAnnotation(AnnotatedElement, Class) * @see #findMergedAnnotation(AnnotatedElement, Class) */ @Nullable public static AnnotationAttributes getMergedAnnotationAttributes( AnnotatedElement element, Class<? extends Annotation> annotationType) { AnnotationAttributes attributes = searchWithGetSemantics(element, annotationType, null, new MergedAnnotationAttributesProcessor()); AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false); return attributes; }
private static Set<String> getMetaAnnotationTypes(AnnotatedElement element, @Nullable Annotation composed) { if (composed == null) { return Collections.emptySet(); } try { final Set<String> types = new LinkedHashSet<>(); searchWithGetSemantics(composed.annotationType(), Collections.emptySet(), null, null, new SimpleAnnotationProcessor<Object>(true) { @Override @Nullable public Object process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { types.add(annotation.annotationType().getName()); return CONTINUE; } }, new HashSet<>(), 1); return types; } catch (Throwable ex) { AnnotationUtils.rethrowAnnotationConfigurationException(ex); throw new IllegalStateException("Failed to introspect annotations on " + element, ex); } }
String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = searchWithGetSemantics(element, null, annotationName, new MergedAnnotationAttributesProcessor(classValuesAsString, nestedAnnotationsAsMap)); AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap);
/** * Get <strong>all</strong> annotations of the specified {@code annotationTypes} * 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 corresponding {@code annotationType}. * <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 annotationTypes the annotation types to find * @return the set of all merged, synthesized {@code Annotations} found, * or an empty set if none were found * @since 5.1 * @see #getAllMergedAnnotations(AnnotatedElement, Class) */ public static Set<Annotation> getAllMergedAnnotations(AnnotatedElement element, Set<Class<? extends Annotation>> annotationTypes) { MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true); searchWithGetSemantics(element, annotationTypes, null, null, processor); return postProcessAndSynthesizeAggregatedResults(element, processor.getAggregatedResults()); }
/** * Get the first annotation of the specified {@code annotationType} within * the annotation hierarchy <em>above</em> the supplied {@code element} and * merge that annotation's attributes with <em>matching</em> attributes from * annotations in lower levels of the annotation hierarchy. * <p>{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. * <p>This method delegates to {@link #getMergedAnnotationAttributes(AnnotatedElement, String)}. * @param element the annotated element * @param annotationType the annotation type to find * @return the merged {@code AnnotationAttributes}, or {@code null} if not found * @since 4.2 * @see #getMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean) * @see #findMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean) * @see #getMergedAnnotation(AnnotatedElement, Class) * @see #findMergedAnnotation(AnnotatedElement, Class) */ @Nullable public static AnnotationAttributes getMergedAnnotationAttributes( AnnotatedElement element, Class<? extends Annotation> annotationType) { AnnotationAttributes attributes = searchWithGetSemantics(element, annotationType, null, new MergedAnnotationAttributesProcessor()); AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false); return attributes; }
/** * Get <strong>all</strong> annotations 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>{@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, synthesized {@code Annotations} found, * or an empty set if none were found * @since 4.3 * @see #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllAnnotationAttributes(AnnotatedElement, String) * @see #findAllMergedAnnotations(AnnotatedElement, Class) */ public static <A extends Annotation> Set<A> getAllMergedAnnotations(AnnotatedElement element, Class<A> annotationType) { MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true); searchWithGetSemantics(element, annotationType, null, processor); return postProcessAndSynthesizeAggregatedResults(element, processor.getAggregatedResults()); }
searchWithGetSemantics(element, Collections.singleton(annotationType), null, containerType, processor); return postProcessAndSynthesizeAggregatedResults(element, processor.getAggregatedResults());
Class<? extends Annotation> currentAnnotationType = annotation.annotationType(); if (!AnnotationUtils.hasPlainJavaAnnotationsOnly(currentAnnotationType)) { T result = searchWithGetSemantics(currentAnnotationType, annotationTypes, annotationName, containerType, processor, visited, metaDepth + 1); if (result != null) {
/** * Get <strong>all</strong> annotations of the specified {@code annotationTypes} * 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 corresponding {@code annotationType}. * <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 annotationTypes the annotation types to find * @return the set of all merged, synthesized {@code Annotations} found, * or an empty set if none were found * @since 5.1 * @see #getAllMergedAnnotations(AnnotatedElement, Class) */ public static Set<Annotation> getAllMergedAnnotations(AnnotatedElement element, Set<Class<? extends Annotation>> annotationTypes) { MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true); searchWithGetSemantics(element, annotationTypes, null, null, processor); return postProcessAndSynthesizeAggregatedResults(element, processor.getAggregatedResults()); }