/** * Post-process the supplied {@link AnnotationAttributes}, preserving nested * annotations as {@code Annotation} instances. * <p>Specifically, this method enforces <em>attribute alias</em> semantics * for annotation attributes that are annotated with {@link AliasFor @AliasFor} * and replaces default value placeholders with their original default values. * @param annotatedElement the element that is annotated with an annotation or * annotation hierarchy from which the supplied attributes were created; * may be {@code null} if unknown * @param attributes the annotation attributes to post-process * @param classValuesAsString whether to convert Class references into Strings (for * compatibility with {@link org.springframework.core.type.AnnotationMetadata}) * or to preserve them as Class references * @since 4.3.2 * @see #postProcessAnnotationAttributes(Object, AnnotationAttributes, boolean, boolean) * @see #getDefaultValue(Class, String) */ public static void postProcessAnnotationAttributes(@Nullable Object annotatedElement, AnnotationAttributes attributes, boolean classValuesAsString) { postProcessAnnotationAttributes(annotatedElement, attributes, classValuesAsString, false); }
private static AnnotationAttributes getAnnotationAttributes(@Nullable Object annotatedElement, Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = retrieveAnnotationAttributes(annotatedElement, annotation, classValuesAsString, nestedAnnotationsAsMap); postProcessAnnotationAttributes(annotatedElement, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; }
/** * Post-process the supplied {@link AnnotationAttributes}, preserving nested * annotations as {@code Annotation} instances. * <p>Specifically, this method enforces <em>attribute alias</em> semantics * for annotation attributes that are annotated with {@link AliasFor @AliasFor} * and replaces default value placeholders with their original default values. * @param annotatedElement the element that is annotated with an annotation or * annotation hierarchy from which the supplied attributes were created; * may be {@code null} if unknown * @param attributes the annotation attributes to post-process * @param classValuesAsString whether to convert Class references into Strings (for * compatibility with {@link org.springframework.core.type.AnnotationMetadata}) * or to preserve them as Class references * @since 4.3.2 * @see #postProcessAnnotationAttributes(Object, AnnotationAttributes, boolean, boolean) * @see #getDefaultValue(Class, String) */ public static void postProcessAnnotationAttributes(@Nullable Object annotatedElement, AnnotationAttributes attributes, boolean classValuesAsString) { postProcessAnnotationAttributes(annotatedElement, attributes, classValuesAsString, false); }
private static AnnotationAttributes getAnnotationAttributes(@Nullable Object annotatedElement, Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = retrieveAnnotationAttributes(annotatedElement, annotation, classValuesAsString, nestedAnnotationsAsMap); postProcessAnnotationAttributes(annotatedElement, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; }
/** * Post-process the aggregated results into a set of synthesized annotations. * @param element the annotated element * @param aggregatedResults the aggregated results for the given element * @return the set of annotations */ @SuppressWarnings("unchecked") private static <A extends Annotation> Set<A> postProcessAndSynthesizeAggregatedResults( AnnotatedElement element, List<AnnotationAttributes> aggregatedResults) { Set<A> annotations = new LinkedHashSet<>(); for (AnnotationAttributes attributes : aggregatedResults) { AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false); Class<? extends Annotation> annType = attributes.annotationType(); if (annType != null) { annotations.add((A) AnnotationUtils.synthesizeAnnotation(attributes, annType, element)); } } return annotations; }
/** * 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; }
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes;
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes;
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes;
/** * Post-process the aggregated results into a set of synthesized annotations. * @param element the annotated element * @param aggregatedResults the aggregated results for the given element * @return the set of annotations */ @SuppressWarnings("unchecked") private static <A extends Annotation> Set<A> postProcessAndSynthesizeAggregatedResults( AnnotatedElement element, List<AnnotationAttributes> aggregatedResults) { Set<A> annotations = new LinkedHashSet<>(); for (AnnotationAttributes attributes : aggregatedResults) { AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false); Class<? extends Annotation> annType = attributes.annotationType(); if (annType != null) { annotations.add((A) AnnotationUtils.synthesizeAnnotation(attributes, annType, element)); } } return annotations; }
/** * 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; }
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes;
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes;
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes;
AnnotationUtils.postProcessAnnotationAttributes(annotatedElement, result, classValuesAsString);
AnnotationUtils.postProcessAnnotationAttributes(annotatedElement, result, classValuesAsString);
@Test public void getAliasedStringWithImplicitAliases() { String value = "metaverse"; List<String> aliases = Arrays.asList("value", "location1", "location2", "location3", "xmlFile", "groovyScript"); attributes = new AnnotationAttributes(ImplicitAliasesContextConfig.class); attributes.put("value", value); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertEquals(value, attributes.getString(alias))); attributes = new AnnotationAttributes(ImplicitAliasesContextConfig.class); attributes.put("location1", value); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertEquals(value, attributes.getString(alias))); attributes = new AnnotationAttributes(ImplicitAliasesContextConfig.class); attributes.put("value", value); attributes.put("location1", value); attributes.put("xmlFile", value); attributes.put("groovyScript", value); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertEquals(value, attributes.getString(alias))); }
AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertArrayEquals(value, attributes.getStringArray(alias))); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertArrayEquals(value, attributes.getStringArray(alias))); attributes.put("location1", value); attributes.put("value", value); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertArrayEquals(value, attributes.getStringArray(alias))); attributes.put("location1", value); AnnotationUtils.registerDefaultValues(attributes); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertArrayEquals(value, attributes.getStringArray(alias))); attributes.put("value", value); AnnotationUtils.registerDefaultValues(attributes); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertArrayEquals(value, attributes.getStringArray(alias))); AnnotationUtils.postProcessAnnotationAttributes(null, attributes, false); aliases.stream().forEach(alias -> assertArrayEquals(new String[] {""}, attributes.getStringArray(alias)));
private static AnnotationAttributes getAnnotationAttributes(@Nullable Object annotatedElement, Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = retrieveAnnotationAttributes(annotatedElement, annotation, classValuesAsString, nestedAnnotationsAsMap); postProcessAnnotationAttributes(annotatedElement, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; }
private static AnnotationAttributes getAnnotationAttributes(@Nullable Object annotatedElement, Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = retrieveAnnotationAttributes(annotatedElement, annotation, classValuesAsString, nestedAnnotationsAsMap); postProcessAnnotationAttributes(annotatedElement, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; }