org.springframework.core.annotation.MergedAnnotation Maven / Gradle / Ivy
/*
* Copyright 2002-2022 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.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 {@link 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 {@code get} methods.
* For example, to access an {@code int} attribute the {@link #getInt(String)}
* method would be used.
*
*
Note that attribute values are not 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.
*
*
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 the annotation type
* @see MergedAnnotations
* @see MergedAnnotationPredicates
*/
public interface MergedAnnotation {
/**
* The attribute name for annotations with a single element.
*/
String VALUE = "value";
/**
* Get the {@code Class} reference for the actual annotation type.
* @return the annotation type
*/
Class getType();
/**
* 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 {@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.
* @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 {@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
* {@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
* {@code null} if the source is not known.
*
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 {@code null} if the
* annotation is not {@linkplain #isMetaPresent() meta-present}.
*
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 {@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 {@link #getRoot() root}.
*
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> getMetaTypes();
/**
* 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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @param attributeName the attribute name
* @param type the enum type
* @return the value as an enum
* @throws NoSuchElementException if there is no matching attribute
*/
> E getEnum(String attributeName, Class type) throws NoSuchElementException;
/**
* Get a required enum array attribute value from the annotation.
* @param attributeName the attribute name
* @param type the enum type
* @return the value as an enum array
* @throws NoSuchElementException if there is no matching attribute
*/
> E[] getEnumArray(String attributeName, Class type) throws NoSuchElementException;
/**
* 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
*/
MergedAnnotation getAnnotation(String attributeName, Class type)
throws NoSuchElementException;
/**
* 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
*/
MergedAnnotation[] getAnnotationArray(String attributeName, Class type)
throws NoSuchElementException;
/**
* 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