/*
 * 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.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Proxy;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;

import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.lang.Nullable;

A single merged annotation returned from a MergedAnnotations collection. Presents a view onto an annotation where attribute values may have been "merged" from different source values.

Attribute values may be accessed using the various get methods. For example, to access an int attribute the getInt(String) method would be used.

Note that attribute values are not converted when accessed. For example, it is not possible to call getString(String) if the underlying attribute is an int. The only exception to this rule is Class and Class[] values which may be accessed as String and String[] respectively to prevent potential early class initialization.

If necessary, a MergedAnnotation can be synthesized back into an actual Annotation.

Author:Phillip Webb, Juergen Hoeller, Sam Brannen
Type parameters:
  • <A> – the annotation type
See Also:
Since:5.2
/** * A single merged annotation returned from a {@link MergedAnnotations} * collection. Presents a view onto an annotation where attribute values may * have been "merged" from different source values. * * <p>Attribute values may be accessed using the various {@code get} methods. * For example, to access an {@code int} attribute the {@link #getInt(String)} * method would be used. * * <p>Note that attribute values are <b>not</b> converted when accessed. * For example, it is not possible to call {@link #getString(String)} if the * underlying attribute is an {@code int}. The only exception to this rule is * {@code Class} and {@code Class[]} values which may be accessed as * {@code String} and {@code String[]} respectively to prevent potential early * class initialization. * * <p>If necessary, a {@code MergedAnnotation} can be {@linkplain #synthesize() * synthesized} back into an actual {@link java.lang.annotation.Annotation}. * * @author Phillip Webb * @author Juergen Hoeller * @author Sam Brannen * @since 5.2 * @param <A> the annotation type * @see MergedAnnotations * @see MergedAnnotationPredicates */
public interface MergedAnnotation<A extends Annotation> {
The attribute name for annotations with a single element.
/** * The attribute name for annotations with a single element. */
String VALUE = "value";
Get the Class reference for the actual annotation type.
Returns:the annotation type
/** * Get the {@code Class} reference for the actual annotation type. * @return the annotation type */
Class<A> getType();
Determine if the annotation is present on the source. Considers directly present and meta-present annotations within the context of the SearchStrategy used.
Returns:true if the annotation is present
/** * Determine if the annotation is present on the source. Considers * {@linkplain #isDirectlyPresent() directly present} and * {@linkplain #isMetaPresent() meta-present} annotations within the context * of the {@link SearchStrategy} used. * @return {@code true} if the annotation is present */
boolean isPresent();
Determine if the annotation is directly present on the source.

A directly present annotation is one that the user has explicitly declared and not one that is meta-present or @Inherited.

Returns:true if the annotation is directly present
/** * Determine if the annotation is directly present on the source. * <p>A directly present annotation is one that the user has explicitly * declared and not one that is {@linkplain #isMetaPresent() meta-present} * or {@link Inherited @Inherited}. * @return {@code true} if the annotation is directly present */
boolean isDirectlyPresent();
Determine if the annotation is meta-present on the source.

A meta-present annotation is an annotation that the user hasn't explicitly declared, but has been used as a meta-annotation somewhere in the annotation hierarchy.

Returns:true if the annotation is meta-present
/** * Determine if the annotation is meta-present on the source. * <p>A meta-present annotation is an annotation that the user hasn't * explicitly declared, but has been used as a meta-annotation somewhere in * the annotation hierarchy. * @return {@code true} if the annotation is meta-present */
boolean isMetaPresent();
Get the distance of this annotation related to its use as a meta-annotation.

A directly declared annotation has a distance of 0, a meta-annotation has a distance of 1, a meta-annotation on a meta-annotation has a distance of 2, etc. A missing annotation will always return a distance of -1.

Returns:the annotation distance or -1 if the annotation is missing
/** * Get the distance of this annotation related to its use as a * meta-annotation. * <p>A directly declared annotation has a distance of {@code 0}, a * meta-annotation has a distance of {@code 1}, a meta-annotation on a * meta-annotation has a distance of {@code 2}, etc. A {@linkplain #missing() * missing} annotation will always return a distance of {@code -1}. * @return the annotation distance or {@code -1} if the annotation is missing */
int getDistance();
Get the index of the aggregate collection containing this annotation.

Can be used to reorder a stream of annotations, for example, to give a higher priority to annotations declared on a superclass or interface. A missing annotation will always return an aggregate index of -1.

Returns:the aggregate index (starting at 0) or -1 if the annotation is missing
/** * Get the index of the aggregate collection containing this annotation. * <p>Can be used to reorder a stream of annotations, for example, to give a * higher priority to annotations declared on a superclass or interface. A * {@linkplain #missing() missing} annotation will always return an aggregate * index of {@code -1}. * @return the aggregate index (starting at {@code 0}) or {@code -1} if the * annotation is missing */
int getAggregateIndex();
Get the source that ultimately declared the root annotation, or null if the source is not known.

If this merged annotation was created from an AnnotatedElement then this source will be an element of the same type. If the annotation was loaded without using reflection, the source can be of any type, but should have a sensible toString(). Meta-annotations will always return the same source as the root.

Returns:the source, or null
/** * Get the source that ultimately declared the root annotation, or * {@code null} if the source is not known. * <p>If this merged annotation was created * {@link MergedAnnotations#from(AnnotatedElement) from} an * {@link AnnotatedElement} then this source will be an element of the same * type. If the annotation was loaded without using reflection, the source * can be of any type, but should have a sensible {@code toString()}. * Meta-annotations will always return the same source as the * {@link #getRoot() root}. * @return the source, or {@code null} */
@Nullable Object getSource();
Get the source of the meta-annotation, or null if the annotation is not meta-present.

The meta-source is the annotation that was meta-annotated with this annotation.

See Also:
Returns:the meta-annotation source or null
/** * Get the source of the meta-annotation, or {@code null} if the * annotation is not {@linkplain #isMetaPresent() meta-present}. * <p>The meta-source is the annotation that was meta-annotated with this * annotation. * @return the meta-annotation source or {@code null} * @see #getRoot() */
@Nullable MergedAnnotation<?> getMetaSource();
Get the root annotation, i.e. the distance 0 annotation as directly declared on the source.
See Also:
Returns:the root annotation
/** * Get the root annotation, i.e. the {@link #getDistance() distance} {@code 0} * annotation as directly declared on the source. * @return the root annotation * @see #getMetaSource() */
MergedAnnotation<?> getRoot();
Get the complete list of annotation types within the annotation hierarchy from this annotation to the root.

Provides a useful way to uniquely identify a merged annotation instance.

See Also:
Returns:the meta types for the annotation
/** * Get the complete list of annotation types within the annotation hierarchy * from this annotation to the {@link #getRoot() root}. * <p>Provides a useful way to uniquely identify a merged annotation instance. * @return the meta types for the annotation * @see MergedAnnotationPredicates#unique(Function) * @see #getRoot() * @see #getMetaSource() */
List<Class<? extends Annotation>> getMetaTypes();
Determine if the specified attribute name has a non-default value when compared to the annotation declaration.
Params:
  • attributeName – the attribute name
Returns:true if the attribute value is different from the default value
/** * Determine if the specified attribute name has a non-default value when * compared to the annotation declaration. * @param attributeName the attribute name * @return {@code true} if the attribute value is different from the default * value */
boolean hasNonDefaultValue(String attributeName);
Determine if the specified attribute name has a default value when compared to the annotation declaration.
Params:
  • attributeName – the attribute name
Returns:true if the attribute value is the same as the default value
/** * Determine if the specified attribute name has a default value when compared * to the annotation declaration. * @param attributeName the attribute name * @return {@code true} if the attribute value is the same as the default * value */
boolean hasDefaultValue(String attributeName) throws NoSuchElementException;
Get a required byte attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a byte
/** * Get a required byte attribute value from the annotation. * @param attributeName the attribute name * @return the value as a byte * @throws NoSuchElementException if there is no matching attribute */
byte getByte(String attributeName) throws NoSuchElementException;
Get a required byte array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a byte array
/** * Get a required byte array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a byte array * @throws NoSuchElementException if there is no matching attribute */
byte[] getByteArray(String attributeName) throws NoSuchElementException;
Get a required boolean attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a boolean
/** * Get a required boolean attribute value from the annotation. * @param attributeName the attribute name * @return the value as a boolean * @throws NoSuchElementException if there is no matching attribute */
boolean getBoolean(String attributeName) throws NoSuchElementException;
Get a required boolean array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a boolean array
/** * Get a required boolean array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a boolean array * @throws NoSuchElementException if there is no matching attribute */
boolean[] getBooleanArray(String attributeName) throws NoSuchElementException;
Get a required char attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a char
/** * Get a required char attribute value from the annotation. * @param attributeName the attribute name * @return the value as a char * @throws NoSuchElementException if there is no matching attribute */
char getChar(String attributeName) throws NoSuchElementException;
Get a required char array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a char array
/** * Get a required char array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a char array * @throws NoSuchElementException if there is no matching attribute */
char[] getCharArray(String attributeName) throws NoSuchElementException;
Get a required short attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a short
/** * Get a required short attribute value from the annotation. * @param attributeName the attribute name * @return the value as a short * @throws NoSuchElementException if there is no matching attribute */
short getShort(String attributeName) throws NoSuchElementException;
Get a required short array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a short array
/** * Get a required short array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a short array * @throws NoSuchElementException if there is no matching attribute */
short[] getShortArray(String attributeName) throws NoSuchElementException;
Get a required int attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as an int
/** * Get a required int attribute value from the annotation. * @param attributeName the attribute name * @return the value as an int * @throws NoSuchElementException if there is no matching attribute */
int getInt(String attributeName) throws NoSuchElementException;
Get a required int array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as an int array
/** * Get a required int array attribute value from the annotation. * @param attributeName the attribute name * @return the value as an int array * @throws NoSuchElementException if there is no matching attribute */
int[] getIntArray(String attributeName) throws NoSuchElementException;
Get a required long attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a long
/** * Get a required long attribute value from the annotation. * @param attributeName the attribute name * @return the value as a long * @throws NoSuchElementException if there is no matching attribute */
long getLong(String attributeName) throws NoSuchElementException;
Get a required long array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a long array
/** * Get a required long array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a long array * @throws NoSuchElementException if there is no matching attribute */
long[] getLongArray(String attributeName) throws NoSuchElementException;
Get a required double attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a double
/** * Get a required double attribute value from the annotation. * @param attributeName the attribute name * @return the value as a double * @throws NoSuchElementException if there is no matching attribute */
double getDouble(String attributeName) throws NoSuchElementException;
Get a required double array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a double array
/** * Get a required double array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a double array * @throws NoSuchElementException if there is no matching attribute */
double[] getDoubleArray(String attributeName) throws NoSuchElementException;
Get a required float attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a float
/** * Get a required float attribute value from the annotation. * @param attributeName the attribute name * @return the value as a float * @throws NoSuchElementException if there is no matching attribute */
float getFloat(String attributeName) throws NoSuchElementException;
Get a required float array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a float array
/** * Get a required float array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a float array * @throws NoSuchElementException if there is no matching attribute */
float[] getFloatArray(String attributeName) throws NoSuchElementException;
Get a required string attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a string
/** * Get a required string attribute value from the annotation. * @param attributeName the attribute name * @return the value as a string * @throws NoSuchElementException if there is no matching attribute */
String getString(String attributeName) throws NoSuchElementException;
Get a required string array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a string array
/** * Get a required string array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a string array * @throws NoSuchElementException if there is no matching attribute */
String[] getStringArray(String attributeName) throws NoSuchElementException;
Get a required class attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a class
/** * Get a required class attribute value from the annotation. * @param attributeName the attribute name * @return the value as a class * @throws NoSuchElementException if there is no matching attribute */
Class<?> getClass(String attributeName) throws NoSuchElementException;
Get a required class array attribute value from the annotation.
Params:
  • attributeName – the attribute name
Throws:
Returns:the value as a class array
/** * Get a required class array attribute value from the annotation. * @param attributeName the attribute name * @return the value as a class array * @throws NoSuchElementException if there is no matching attribute */
Class<?>[] getClassArray(String attributeName) throws NoSuchElementException;
Get a required enum attribute value from the annotation.
Params:
  • attributeName – the attribute name
  • type – the enum type
Throws:
Returns:the value as a enum
/** * Get a required enum attribute value from the annotation. * @param attributeName the attribute name * @param type the enum type * @return the value as a enum * @throws NoSuchElementException if there is no matching attribute */
<E extends Enum<E>> E getEnum(String attributeName, Class<E> type) throws NoSuchElementException;
Get a required enum array attribute value from the annotation.
Params:
  • attributeName – the attribute name
  • type – the enum type
Throws:
Returns:the value as a enum array
/** * Get a required enum array attribute value from the annotation. * @param attributeName the attribute name * @param type the enum type * @return the value as a enum array * @throws NoSuchElementException if there is no matching attribute */
<E extends Enum<E>> E[] getEnumArray(String attributeName, Class<E> type) throws NoSuchElementException;
Get a required annotation attribute value from the annotation.
Params:
  • attributeName – the attribute name
  • type – the annotation type
Throws:
Returns:the value as a MergedAnnotation
/** * Get a required annotation attribute value from the annotation. * @param attributeName the attribute name * @param type the annotation type * @return the value as a {@link MergedAnnotation} * @throws NoSuchElementException if there is no matching attribute */
<T extends Annotation> MergedAnnotation<T> getAnnotation(String attributeName, Class<T> type) throws NoSuchElementException;
Get a required annotation array attribute value from the annotation.
Params:
  • attributeName – the attribute name
  • type – the annotation type
Throws:
Returns:the value as a MergedAnnotation array
/** * Get a required annotation array attribute value from the annotation. * @param attributeName the attribute name * @param type the annotation type * @return the value as a {@link MergedAnnotation} array * @throws NoSuchElementException if there is no matching attribute */
<T extends Annotation> MergedAnnotation<T>[] getAnnotationArray(String attributeName, Class<T> type) throws NoSuchElementException;
Get an optional attribute value from the annotation.
Params:
  • attributeName – the attribute name
Returns:an optional value or Optional.empty() if there is no matching attribute
/** * Get an optional attribute value from the annotation. * @param attributeName the attribute name * @return an optional value or {@link Optional#empty()} if there is no * matching attribute */
Optional<Object> getValue(String attributeName);
Get an optional attribute value from the annotation.
Params:
  • attributeName – the attribute name
  • type – the attribute type. Must be compatible with the underlying attribute type or Object.class.
Returns:an optional value or Optional.empty() if there is no matching attribute
/** * Get an optional attribute value from the annotation. * @param attributeName the attribute name * @param type the attribute type. Must be compatible with the underlying * attribute type or {@code Object.class}. * @return an optional value or {@link Optional#empty()} if there is no * matching attribute */
<T> Optional<T> getValue(String attributeName, Class<T> type);
Get the default attribute value from the annotation as specified in the annotation declaration.
Params:
  • attributeName – the attribute name
Returns:an optional of the default value or Optional.empty() if there is no matching attribute or no defined default
/** * Get the default attribute value from the annotation as specified in * the annotation declaration. * @param attributeName the attribute name * @return an optional of the default value or {@link Optional#empty()} if * there is no matching attribute or no defined default */
Optional<Object> getDefaultValue(String attributeName);
Get the default attribute value from the annotation as specified in the annotation declaration.
Params:
  • attributeName – the attribute name
  • type – the attribute type. Must be compatible with the underlying attribute type or Object.class.
Returns:an optional of the default value or Optional.empty() if there is no matching attribute or no defined default
/** * Get the default attribute value from the annotation as specified in * the annotation declaration. * @param attributeName the attribute name * @param type the attribute type. Must be compatible with the underlying * attribute type or {@code Object.class}. * @return an optional of the default value or {@link Optional#empty()} if * there is no matching attribute or no defined default */
<T> Optional<T> getDefaultValue(String attributeName, Class<T> type);
Create a new view of the annotation with all attributes that have default values removed.
See Also:
Returns:a filtered view of the annotation without any attributes that have a default value
/** * Create a new view of the annotation with all attributes that have default * values removed. * @return a filtered view of the annotation without any attributes that * have a default value * @see #filterAttributes(Predicate) */
MergedAnnotation<A> filterDefaultValues();
Create a new view of the annotation with only attributes that match the given predicate.
Params:
  • predicate – a predicate used to filter attribute names
See Also:
Returns:a filtered view of the annotation
/** * Create a new view of the annotation with only attributes that match the * given predicate. * @param predicate a predicate used to filter attribute names * @return a filtered view of the annotation * @see #filterDefaultValues() * @see MergedAnnotationPredicates */
MergedAnnotation<A> filterAttributes(Predicate<String> predicate);
Create a new view of the annotation that exposes non-merged attribute values.

Methods from this view will return attribute values with only alias mirroring rules applied. Aliases to meta-source attributes will not be applied.

Returns:a non-merged view of the annotation
/** * Create a new view of the annotation that exposes non-merged attribute values. * <p>Methods from this view will return attribute values with only alias mirroring * rules applied. Aliases to {@link #getMetaSource() meta-source} attributes will * not be applied. * @return a non-merged view of the annotation */
MergedAnnotation<A> withNonMergedAttributes();
Create a new mutable AnnotationAttributes instance from this merged annotation.

The adaptations may be used to change the way that values are added.

Params:
  • adaptations – the adaptations that should be applied to the annotation values
Returns:an immutable map containing the attributes and values
/** * Create a new mutable {@link AnnotationAttributes} instance from this * merged annotation. * <p>The {@link Adapt adaptations} may be used to change the way that values * are added. * @param adaptations the adaptations that should be applied to the annotation values * @return an immutable map containing the attributes and values */
AnnotationAttributes asAnnotationAttributes(Adapt... adaptations);
Get an immutable Map that contains all the annotation attributes.

The adaptations may be used to change the way that values are added.

Params:
  • adaptations – the adaptations that should be applied to the annotation values
Returns:an immutable map containing the attributes and values
/** * Get an immutable {@link Map} that contains all the annotation attributes. * <p>The {@link Adapt adaptations} may be used to change the way that values are added. * @param adaptations the adaptations that should be applied to the annotation values * @return an immutable map containing the attributes and values */
Map<String, Object> asMap(Adapt... adaptations);
Create a new Map instance of the given type that contains all the annotation attributes.

The adaptations may be used to change the way that values are added.

Params:
  • factory – a map factory
  • adaptations – the adaptations that should be applied to the annotation values
Returns:a map containing the attributes and values
/** * Create a new {@link Map} instance of the given type that contains all the annotation * attributes. * <p>The {@link Adapt adaptations} may be used to change the way that values are added. * @param factory a map factory * @param adaptations the adaptations that should be applied to the annotation values * @return a map containing the attributes and values */
<T extends Map<String, Object>> T asMap(Function<MergedAnnotation<?>, T> factory, Adapt... adaptations);
Create a type-safe synthesized version of this merged annotation that can be used directly in code.

The result is synthesized using a JDK Proxy and as a result may incur a computational cost when first invoked.

If this merged annotation was created from an annotation instance, that annotation will be returned unmodified if it is not synthesizable. An annotation is considered synthesizable if one of the following is true.

  • The annotation declares attributes annotated with @AliasFor.
  • The annotation is a composed annotation that relies on convention-based annotation attribute overrides in meta-annotations.
  • The annotation declares attributes that are annotations or arrays of annotations that are themselves synthesizable.
Throws:
Returns:a synthesized version of the annotation or the original annotation unmodified
/** * Create a type-safe synthesized version of this merged annotation that can * be used directly in code. * <p>The result is synthesized using a JDK {@link Proxy} and as a result may * incur a computational cost when first invoked. * <p>If this merged annotation was created {@linkplain #from(Annotation) from} * an annotation instance, that annotation will be returned unmodified if it is * not <em>synthesizable</em>. An annotation is considered synthesizable if * one of the following is true. * <ul> * <li>The annotation declares attributes annotated with {@link AliasFor @AliasFor}.</li> * <li>The annotation is a composed annotation that relies on convention-based * annotation attribute overrides in meta-annotations.</li> * <li>The annotation declares attributes that are annotations or arrays of * annotations that are themselves synthesizable.</li> * </ul> * @return a synthesized version of the annotation or the original annotation * unmodified * @throws NoSuchElementException on a missing annotation */
A synthesize() throws NoSuchElementException;
Optionally create a type-safe synthesized version of this annotation based on a condition predicate.

The result is synthesized using a JDK Proxy and as a result may incur a computational cost when first invoked.

Consult the documentation for synthesize() for an explanation of what is considered synthesizable.

Params:
  • condition – the test to determine if the annotation can be synthesized
Throws:
See Also:
Returns:an optional containing the synthesized version of the annotation or an empty optional if the condition doesn't match
/** * Optionally create a type-safe synthesized version of this annotation based * on a condition predicate. * <p>The result is synthesized using a JDK {@link Proxy} and as a result may * incur a computational cost when first invoked. * <p>Consult the documentation for {@link #synthesize()} for an explanation * of what is considered synthesizable. * @param condition the test to determine if the annotation can be synthesized * @return an optional containing the synthesized version of the annotation or * an empty optional if the condition doesn't match * @throws NoSuchElementException on a missing annotation * @see MergedAnnotationPredicates */
Optional<A> synthesize(Predicate<? super MergedAnnotation<A>> condition) throws NoSuchElementException;
Create a MergedAnnotation that represents a missing annotation (i.e. one that is not present).
Returns:an instance representing a missing annotation
/** * Create a {@link MergedAnnotation} that represents a missing annotation * (i.e. one that is not present). * @return an instance representing a missing annotation */
static <A extends Annotation> MergedAnnotation<A> missing() { return MissingMergedAnnotation.getInstance(); }
Create a new MergedAnnotation instance from the specified annotation.
Params:
  • annotation – the annotation to include
Returns:a MergedAnnotation instance containing the annotation
/** * Create a new {@link MergedAnnotation} instance from the specified * annotation. * @param annotation the annotation to include * @return a {@link MergedAnnotation} instance containing the annotation */
static <A extends Annotation> MergedAnnotation<A> from(A annotation) { return from(null, annotation); }
Create a new MergedAnnotation instance from the specified annotation.
Params:
  • source – the source for the annotation. This source is used only for information and logging. It does not need to actually contain the specified annotations, and it will not be searched.
  • annotation – the annotation to include
Returns:a MergedAnnotation instance for the annotation
/** * Create a new {@link MergedAnnotation} instance from the specified * annotation. * @param source the source for the annotation. This source is used only for * information and logging. It does not need to <em>actually</em> contain * the specified annotations, and it will not be searched. * @param annotation the annotation to include * @return a {@link MergedAnnotation} instance for the annotation */
static <A extends Annotation> MergedAnnotation<A> from(@Nullable Object source, A annotation) { return TypeMappedAnnotation.from(source, annotation); }
Create a new MergedAnnotation instance of the specified annotation type. The resulting annotation will not have any attribute values but may still be used to query default values.
Params:
  • annotationType – the annotation type
Returns:a MergedAnnotation instance for the annotation
/** * Create a new {@link MergedAnnotation} instance of the specified * annotation type. The resulting annotation will not have any attribute * values but may still be used to query default values. * @param annotationType the annotation type * @return a {@link MergedAnnotation} instance for the annotation */
static <A extends Annotation> MergedAnnotation<A> of(Class<A> annotationType) { return of(null, annotationType, null); }
Create a new MergedAnnotation instance of the specified annotation type with attribute values supplied by a map.
Params:
  • annotationType – the annotation type
  • attributes – the annotation attributes or null if just default values should be used
See Also:
Returns:a MergedAnnotation instance for the annotation and attributes
/** * Create a new {@link MergedAnnotation} instance of the specified * annotation type with attribute values supplied by a map. * @param annotationType the annotation type * @param attributes the annotation attributes or {@code null} if just default * values should be used * @return a {@link MergedAnnotation} instance for the annotation and attributes * @see #of(AnnotatedElement, Class, Map) */
static <A extends Annotation> MergedAnnotation<A> of( Class<A> annotationType, @Nullable Map<String, ?> attributes) { return of(null, annotationType, attributes); }
Create a new MergedAnnotation instance of the specified annotation type with attribute values supplied by a map.
Params:
  • source – the source for the annotation. This source is used only for information and logging. It does not need to actually contain the specified annotations and it will not be searched.
  • annotationType – the annotation type
  • attributes – the annotation attributes or null if just default values should be used
Returns:a MergedAnnotation instance for the annotation and attributes
/** * Create a new {@link MergedAnnotation} instance of the specified * annotation type with attribute values supplied by a map. * @param source the source for the annotation. This source is used only for * information and logging. It does not need to <em>actually</em> contain * the specified annotations and it will not be searched. * @param annotationType the annotation type * @param attributes the annotation attributes or {@code null} if just default * values should be used * @return a {@link MergedAnnotation} instance for the annotation and attributes */
static <A extends Annotation> MergedAnnotation<A> of( @Nullable AnnotatedElement source, Class<A> annotationType, @Nullable Map<String, ?> attributes) { return of(null, source, annotationType, attributes); }
Create a new MergedAnnotation instance of the specified annotation type with attribute values supplied by a map.
Params:
  • classLoader – the class loader used to resolve class attributes
  • source – the source for the annotation. This source is used only for information and logging. It does not need to actually contain the specified annotations and it will not be searched.
  • annotationType – the annotation type
  • attributes – the annotation attributes or null if just default values should be used
Returns:a MergedAnnotation instance for the annotation and attributes
/** * Create a new {@link MergedAnnotation} instance of the specified * annotation type with attribute values supplied by a map. * @param classLoader the class loader used to resolve class attributes * @param source the source for the annotation. This source is used only for * information and logging. It does not need to <em>actually</em> contain * the specified annotations and it will not be searched. * @param annotationType the annotation type * @param attributes the annotation attributes or {@code null} if just default * values should be used * @return a {@link MergedAnnotation} instance for the annotation and attributes */
static <A extends Annotation> MergedAnnotation<A> of( @Nullable ClassLoader classLoader, @Nullable Object source, Class<A> annotationType, @Nullable Map<String, ?> attributes) { return TypeMappedAnnotation.of(classLoader, source, annotationType, attributes); }
Adaptations that can be applied to attribute values when creating Maps or AnnotationAttributes.
/** * Adaptations that can be applied to attribute values when creating * {@linkplain MergedAnnotation#asMap(Adapt...) Maps} or * {@link MergedAnnotation#asAnnotationAttributes(Adapt...) AnnotationAttributes}. */
enum Adapt {
Adapt class or class array attributes to strings.
/** * Adapt class or class array attributes to strings. */
CLASS_TO_STRING,
Adapt nested annotation or annotation arrays to maps rather than synthesizing the values.
/** * Adapt nested annotation or annotation arrays to maps rather * than synthesizing the values. */
ANNOTATION_TO_MAP; protected final boolean isIn(Adapt... adaptations) { for (Adapt candidate : adaptations) { if (candidate == this) { return true; } } return false; }
Factory method to create an Adapt array from a set of boolean flags.
Params:
Returns:a new Adapt array
/** * Factory method to create an {@link Adapt} array from a set of boolean flags. * @param classToString if {@link Adapt#CLASS_TO_STRING} is included * @param annotationsToMap if {@link Adapt#ANNOTATION_TO_MAP} is included * @return a new {@link Adapt} array */
public static Adapt[] values(boolean classToString, boolean annotationsToMap) { EnumSet<Adapt> result = EnumSet.noneOf(Adapt.class); addIfTrue(result, Adapt.CLASS_TO_STRING, classToString); addIfTrue(result, Adapt.ANNOTATION_TO_MAP, annotationsToMap); return result.toArray(new Adapt[0]); } private static <T> void addIfTrue(Set<T> result, T value, boolean test) { if (test) { result.add(value); } } } }