|
|
|
@ -23,7 +23,6 @@ import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.function.BiPredicate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.BridgeMethodResolver; |
|
|
|
import org.springframework.core.BridgeMethodResolver; |
|
|
|
import org.springframework.core.Ordered; |
|
|
|
import org.springframework.core.Ordered; |
|
|
|
@ -75,70 +74,49 @@ abstract class AnnotationsScanner { |
|
|
|
static <C, R> R scan(C context, AnnotatedElement source, SearchStrategy searchStrategy, |
|
|
|
static <C, R> R scan(C context, AnnotatedElement source, SearchStrategy searchStrategy, |
|
|
|
AnnotationsProcessor<C, R> processor) { |
|
|
|
AnnotationsProcessor<C, R> processor) { |
|
|
|
|
|
|
|
|
|
|
|
return scan(context, source, searchStrategy, processor, null); |
|
|
|
R result = process(context, source, searchStrategy, processor); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Scan the hierarchy of the specified element for relevant annotations and |
|
|
|
|
|
|
|
* call the processor as required. |
|
|
|
|
|
|
|
* @param context an optional context object that will be passed back to the |
|
|
|
|
|
|
|
* processor |
|
|
|
|
|
|
|
* @param source the source element to scan |
|
|
|
|
|
|
|
* @param searchStrategy the search strategy to use |
|
|
|
|
|
|
|
* @param processor the processor that receives the annotations |
|
|
|
|
|
|
|
* @param classFilter an optional filter that can be used to entirely filter |
|
|
|
|
|
|
|
* out a specific class from the hierarchy |
|
|
|
|
|
|
|
* @return the result of {@link AnnotationsProcessor#finish(Object)} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
static <C, R> R scan(C context, AnnotatedElement source, SearchStrategy searchStrategy, |
|
|
|
|
|
|
|
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
R result = process(context, source, searchStrategy, processor, classFilter); |
|
|
|
|
|
|
|
return processor.finish(result); |
|
|
|
return processor.finish(result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R process(C context, AnnotatedElement source, |
|
|
|
private static <C, R> R process(C context, AnnotatedElement source, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor) { |
|
|
|
@Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (source instanceof Class) { |
|
|
|
if (source instanceof Class) { |
|
|
|
return processClass(context, (Class<?>) source, searchStrategy, processor, classFilter); |
|
|
|
return processClass(context, (Class<?>) source, searchStrategy, processor); |
|
|
|
} |
|
|
|
} |
|
|
|
if (source instanceof Method) { |
|
|
|
if (source instanceof Method) { |
|
|
|
return processMethod(context, (Method) source, searchStrategy, processor, classFilter); |
|
|
|
return processMethod(context, (Method) source, searchStrategy, processor); |
|
|
|
} |
|
|
|
} |
|
|
|
return processElement(context, source, processor, classFilter); |
|
|
|
return processElement(context, source, processor); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processClass(C context, Class<?> source, |
|
|
|
private static <C, R> R processClass(C context, Class<?> source, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor) { |
|
|
|
@Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (searchStrategy) { |
|
|
|
switch (searchStrategy) { |
|
|
|
case DIRECT: |
|
|
|
case DIRECT: |
|
|
|
return processElement(context, source, processor, classFilter); |
|
|
|
return processElement(context, source, processor); |
|
|
|
case INHERITED_ANNOTATIONS: |
|
|
|
case INHERITED_ANNOTATIONS: |
|
|
|
return processClassInheritedAnnotations(context, source, searchStrategy, processor, classFilter); |
|
|
|
return processClassInheritedAnnotations(context, source, searchStrategy, processor); |
|
|
|
case SUPERCLASS: |
|
|
|
case SUPERCLASS: |
|
|
|
return processClassHierarchy(context, source, processor, classFilter, false, false); |
|
|
|
return processClassHierarchy(context, source, processor, false, false); |
|
|
|
case TYPE_HIERARCHY: |
|
|
|
case TYPE_HIERARCHY: |
|
|
|
return processClassHierarchy(context, source, processor, classFilter, true, false); |
|
|
|
return processClassHierarchy(context, source, processor, true, false); |
|
|
|
case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES: |
|
|
|
case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES: |
|
|
|
return processClassHierarchy(context, source, processor, classFilter, true, true); |
|
|
|
return processClassHierarchy(context, source, processor, true, true); |
|
|
|
} |
|
|
|
} |
|
|
|
throw new IllegalStateException("Unsupported search strategy " + searchStrategy); |
|
|
|
throw new IllegalStateException("Unsupported search strategy " + searchStrategy); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processClassInheritedAnnotations(C context, Class<?> source, |
|
|
|
private static <C, R> R processClassInheritedAnnotations(C context, Class<?> source, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor) { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
if (isWithoutHierarchy(source, searchStrategy)) { |
|
|
|
if (isWithoutHierarchy(source, searchStrategy)) { |
|
|
|
return processElement(context, source, processor, classFilter); |
|
|
|
return processElement(context, source, processor); |
|
|
|
} |
|
|
|
} |
|
|
|
Annotation[] relevant = null; |
|
|
|
Annotation[] relevant = null; |
|
|
|
int remaining = Integer.MAX_VALUE; |
|
|
|
int remaining = Integer.MAX_VALUE; |
|
|
|
@ -150,14 +128,7 @@ abstract class AnnotationsScanner { |
|
|
|
if (result != null) { |
|
|
|
if (result != null) { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
if (isFiltered(source, context, classFilter)) { |
|
|
|
Annotation[] declaredAnnotations = getDeclaredAnnotations(source, true); |
|
|
|
// Skip the current level in the class hierarchy.
|
|
|
|
|
|
|
|
source = source.getSuperclass(); |
|
|
|
|
|
|
|
aggregateIndex++; |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Annotation[] declaredAnnotations = |
|
|
|
|
|
|
|
getDeclaredAnnotations(context, source, classFilter, true); |
|
|
|
|
|
|
|
if (relevant == null && declaredAnnotations.length > 0) { |
|
|
|
if (relevant == null && declaredAnnotations.length > 0) { |
|
|
|
relevant = root.getAnnotations(); |
|
|
|
relevant = root.getAnnotations(); |
|
|
|
remaining = relevant.length; |
|
|
|
remaining = relevant.length; |
|
|
|
@ -195,17 +166,15 @@ abstract class AnnotationsScanner { |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processClassHierarchy(C context, Class<?> source, |
|
|
|
private static <C, R> R processClassHierarchy(C context, Class<?> source, |
|
|
|
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter, |
|
|
|
AnnotationsProcessor<C, R> processor, boolean includeInterfaces, boolean includeEnclosing) { |
|
|
|
boolean includeInterfaces, boolean includeEnclosing) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return processClassHierarchy(context, new int[] {0}, source, processor, |
|
|
|
return processClassHierarchy(context, new int[] {0}, source, processor, |
|
|
|
classFilter, includeInterfaces, includeEnclosing); |
|
|
|
includeInterfaces, includeEnclosing); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processClassHierarchy(C context, int[] aggregateIndex, Class<?> source, |
|
|
|
private static <C, R> R processClassHierarchy(C context, int[] aggregateIndex, Class<?> source, |
|
|
|
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter, |
|
|
|
AnnotationsProcessor<C, R> processor, boolean includeInterfaces, boolean includeEnclosing) { |
|
|
|
boolean includeInterfaces, boolean includeEnclosing) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
R result = processor.doWithAggregate(context, aggregateIndex[0]); |
|
|
|
R result = processor.doWithAggregate(context, aggregateIndex[0]); |
|
|
|
@ -215,7 +184,7 @@ abstract class AnnotationsScanner { |
|
|
|
if (hasPlainJavaAnnotationsOnly(source)) { |
|
|
|
if (hasPlainJavaAnnotationsOnly(source)) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
Annotation[] annotations = getDeclaredAnnotations(context, source, classFilter, false); |
|
|
|
Annotation[] annotations = getDeclaredAnnotations(source, false); |
|
|
|
result = processor.doWithAnnotations(context, aggregateIndex[0], source, annotations); |
|
|
|
result = processor.doWithAnnotations(context, aggregateIndex[0], source, annotations); |
|
|
|
if (result != null) { |
|
|
|
if (result != null) { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
@ -224,7 +193,7 @@ abstract class AnnotationsScanner { |
|
|
|
if (includeInterfaces) { |
|
|
|
if (includeInterfaces) { |
|
|
|
for (Class<?> interfaceType : source.getInterfaces()) { |
|
|
|
for (Class<?> interfaceType : source.getInterfaces()) { |
|
|
|
R interfacesResult = processClassHierarchy(context, aggregateIndex, |
|
|
|
R interfacesResult = processClassHierarchy(context, aggregateIndex, |
|
|
|
interfaceType, processor, classFilter, true, includeEnclosing); |
|
|
|
interfaceType, processor, true, includeEnclosing); |
|
|
|
if (interfacesResult != null) { |
|
|
|
if (interfacesResult != null) { |
|
|
|
return interfacesResult; |
|
|
|
return interfacesResult; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -233,7 +202,7 @@ abstract class AnnotationsScanner { |
|
|
|
Class<?> superclass = source.getSuperclass(); |
|
|
|
Class<?> superclass = source.getSuperclass(); |
|
|
|
if (superclass != Object.class && superclass != null) { |
|
|
|
if (superclass != Object.class && superclass != null) { |
|
|
|
R superclassResult = processClassHierarchy(context, aggregateIndex, |
|
|
|
R superclassResult = processClassHierarchy(context, aggregateIndex, |
|
|
|
superclass, processor, classFilter, includeInterfaces, includeEnclosing); |
|
|
|
superclass, processor, includeInterfaces, includeEnclosing); |
|
|
|
if (superclassResult != null) { |
|
|
|
if (superclassResult != null) { |
|
|
|
return superclassResult; |
|
|
|
return superclassResult; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -248,7 +217,7 @@ abstract class AnnotationsScanner { |
|
|
|
Class<?> enclosingClass = source.getEnclosingClass(); |
|
|
|
Class<?> enclosingClass = source.getEnclosingClass(); |
|
|
|
if (enclosingClass != null) { |
|
|
|
if (enclosingClass != null) { |
|
|
|
R enclosingResult = processClassHierarchy(context, aggregateIndex, |
|
|
|
R enclosingResult = processClassHierarchy(context, aggregateIndex, |
|
|
|
enclosingClass, processor, classFilter, includeInterfaces, true); |
|
|
|
enclosingClass, processor, includeInterfaces, true); |
|
|
|
if (enclosingResult != null) { |
|
|
|
if (enclosingResult != null) { |
|
|
|
return enclosingResult; |
|
|
|
return enclosingResult; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -267,32 +236,31 @@ abstract class AnnotationsScanner { |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processMethod(C context, Method source, |
|
|
|
private static <C, R> R processMethod(C context, Method source, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor, |
|
|
|
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor) { |
|
|
|
@Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (searchStrategy) { |
|
|
|
switch (searchStrategy) { |
|
|
|
case DIRECT: |
|
|
|
case DIRECT: |
|
|
|
case INHERITED_ANNOTATIONS: |
|
|
|
case INHERITED_ANNOTATIONS: |
|
|
|
return processMethodInheritedAnnotations(context, source, processor, classFilter); |
|
|
|
return processMethodInheritedAnnotations(context, source, processor); |
|
|
|
case SUPERCLASS: |
|
|
|
case SUPERCLASS: |
|
|
|
return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(), |
|
|
|
return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(), |
|
|
|
processor, classFilter, source, false); |
|
|
|
processor, source, false); |
|
|
|
case TYPE_HIERARCHY: |
|
|
|
case TYPE_HIERARCHY: |
|
|
|
case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES: |
|
|
|
case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES: |
|
|
|
return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(), |
|
|
|
return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(), |
|
|
|
processor, classFilter, source, true); |
|
|
|
processor, source, true); |
|
|
|
} |
|
|
|
} |
|
|
|
throw new IllegalStateException("Unsupported search strategy " + searchStrategy); |
|
|
|
throw new IllegalStateException("Unsupported search strategy " + searchStrategy); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processMethodInheritedAnnotations(C context, Method source, |
|
|
|
private static <C, R> R processMethodInheritedAnnotations(C context, Method source, |
|
|
|
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
AnnotationsProcessor<C, R> processor) { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
R result = processor.doWithAggregate(context, 0); |
|
|
|
R result = processor.doWithAggregate(context, 0); |
|
|
|
return (result != null ? result : |
|
|
|
return (result != null ? result : |
|
|
|
processMethodAnnotations(context, 0, source, processor, classFilter)); |
|
|
|
processMethodAnnotations(context, 0, source, processor)); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Throwable ex) { |
|
|
|
catch (Throwable ex) { |
|
|
|
AnnotationUtils.handleIntrospectionFailure(source, ex); |
|
|
|
AnnotationUtils.handleIntrospectionFailure(source, ex); |
|
|
|
@ -302,8 +270,7 @@ abstract class AnnotationsScanner { |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processMethodHierarchy(C context, int[] aggregateIndex, |
|
|
|
private static <C, R> R processMethodHierarchy(C context, int[] aggregateIndex, |
|
|
|
Class<?> sourceClass, AnnotationsProcessor<C, R> processor, |
|
|
|
Class<?> sourceClass, AnnotationsProcessor<C, R> processor, Method rootMethod, |
|
|
|
@Nullable BiPredicate<C, Class<?>> classFilter, Method rootMethod, |
|
|
|
|
|
|
|
boolean includeInterfaces) { |
|
|
|
boolean includeInterfaces) { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
@ -317,17 +284,17 @@ abstract class AnnotationsScanner { |
|
|
|
boolean calledProcessor = false; |
|
|
|
boolean calledProcessor = false; |
|
|
|
if (sourceClass == rootMethod.getDeclaringClass()) { |
|
|
|
if (sourceClass == rootMethod.getDeclaringClass()) { |
|
|
|
result = processMethodAnnotations(context, aggregateIndex[0], |
|
|
|
result = processMethodAnnotations(context, aggregateIndex[0], |
|
|
|
rootMethod, processor, classFilter); |
|
|
|
rootMethod, processor); |
|
|
|
calledProcessor = true; |
|
|
|
calledProcessor = true; |
|
|
|
if (result != null) { |
|
|
|
if (result != null) { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
for (Method candidateMethod : getBaseTypeMethods(context, sourceClass, classFilter)) { |
|
|
|
for (Method candidateMethod : getBaseTypeMethods(context, sourceClass)) { |
|
|
|
if (candidateMethod != null && isOverride(rootMethod, candidateMethod)) { |
|
|
|
if (candidateMethod != null && isOverride(rootMethod, candidateMethod)) { |
|
|
|
result = processMethodAnnotations(context, aggregateIndex[0], |
|
|
|
result = processMethodAnnotations(context, aggregateIndex[0], |
|
|
|
candidateMethod, processor, classFilter); |
|
|
|
candidateMethod, processor); |
|
|
|
calledProcessor = true; |
|
|
|
calledProcessor = true; |
|
|
|
if (result != null) { |
|
|
|
if (result != null) { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
@ -344,7 +311,7 @@ abstract class AnnotationsScanner { |
|
|
|
if (includeInterfaces) { |
|
|
|
if (includeInterfaces) { |
|
|
|
for (Class<?> interfaceType : sourceClass.getInterfaces()) { |
|
|
|
for (Class<?> interfaceType : sourceClass.getInterfaces()) { |
|
|
|
R interfacesResult = processMethodHierarchy(context, aggregateIndex, |
|
|
|
R interfacesResult = processMethodHierarchy(context, aggregateIndex, |
|
|
|
interfaceType, processor, classFilter, rootMethod, true); |
|
|
|
interfaceType, processor, rootMethod, true); |
|
|
|
if (interfacesResult != null) { |
|
|
|
if (interfacesResult != null) { |
|
|
|
return interfacesResult; |
|
|
|
return interfacesResult; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -353,7 +320,7 @@ abstract class AnnotationsScanner { |
|
|
|
Class<?> superclass = sourceClass.getSuperclass(); |
|
|
|
Class<?> superclass = sourceClass.getSuperclass(); |
|
|
|
if (superclass != Object.class && superclass != null) { |
|
|
|
if (superclass != Object.class && superclass != null) { |
|
|
|
R superclassResult = processMethodHierarchy(context, aggregateIndex, |
|
|
|
R superclassResult = processMethodHierarchy(context, aggregateIndex, |
|
|
|
superclass, processor, classFilter, rootMethod, includeInterfaces); |
|
|
|
superclass, processor, rootMethod, includeInterfaces); |
|
|
|
if (superclassResult != null) { |
|
|
|
if (superclassResult != null) { |
|
|
|
return superclassResult; |
|
|
|
return superclassResult; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -365,11 +332,8 @@ abstract class AnnotationsScanner { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static <C> Method[] getBaseTypeMethods( |
|
|
|
private static <C> Method[] getBaseTypeMethods(C context, Class<?> baseType) { |
|
|
|
C context, Class<?> baseType, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
if (baseType == Object.class || hasPlainJavaAnnotationsOnly(baseType)) { |
|
|
|
|
|
|
|
|
|
|
|
if (baseType == Object.class || hasPlainJavaAnnotationsOnly(baseType) || |
|
|
|
|
|
|
|
isFiltered(baseType, context, classFilter)) { |
|
|
|
|
|
|
|
return NO_METHODS; |
|
|
|
return NO_METHODS; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -433,16 +397,16 @@ abstract class AnnotationsScanner { |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processMethodAnnotations(C context, int aggregateIndex, Method source, |
|
|
|
private static <C, R> R processMethodAnnotations(C context, int aggregateIndex, Method source, |
|
|
|
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
AnnotationsProcessor<C, R> processor) { |
|
|
|
|
|
|
|
|
|
|
|
Annotation[] annotations = getDeclaredAnnotations(context, source, classFilter, false); |
|
|
|
Annotation[] annotations = getDeclaredAnnotations(source, false); |
|
|
|
R result = processor.doWithAnnotations(context, aggregateIndex, source, annotations); |
|
|
|
R result = processor.doWithAnnotations(context, aggregateIndex, source, annotations); |
|
|
|
if (result != null) { |
|
|
|
if (result != null) { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(source); |
|
|
|
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(source); |
|
|
|
if (bridgedMethod != source) { |
|
|
|
if (bridgedMethod != source) { |
|
|
|
Annotation[] bridgedAnnotations = getDeclaredAnnotations(context, bridgedMethod, classFilter, true); |
|
|
|
Annotation[] bridgedAnnotations = getDeclaredAnnotations(bridgedMethod, true); |
|
|
|
for (int i = 0; i < bridgedAnnotations.length; i++) { |
|
|
|
for (int i = 0; i < bridgedAnnotations.length; i++) { |
|
|
|
if (ObjectUtils.containsElement(annotations, bridgedAnnotations[i])) { |
|
|
|
if (ObjectUtils.containsElement(annotations, bridgedAnnotations[i])) { |
|
|
|
bridgedAnnotations[i] = null; |
|
|
|
bridgedAnnotations[i] = null; |
|
|
|
@ -455,12 +419,12 @@ abstract class AnnotationsScanner { |
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private static <C, R> R processElement(C context, AnnotatedElement source, |
|
|
|
private static <C, R> R processElement(C context, AnnotatedElement source, |
|
|
|
AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
AnnotationsProcessor<C, R> processor) { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
R result = processor.doWithAggregate(context, 0); |
|
|
|
R result = processor.doWithAggregate(context, 0); |
|
|
|
return (result != null ? result : processor.doWithAnnotations( |
|
|
|
return (result != null ? result : processor.doWithAnnotations( |
|
|
|
context, 0, source, getDeclaredAnnotations(context, source, classFilter, false))); |
|
|
|
context, 0, source, getDeclaredAnnotations(source, false))); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Throwable ex) { |
|
|
|
catch (Throwable ex) { |
|
|
|
AnnotationUtils.handleIntrospectionFailure(source, ex); |
|
|
|
AnnotationUtils.handleIntrospectionFailure(source, ex); |
|
|
|
@ -468,18 +432,6 @@ abstract class AnnotationsScanner { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static <C, R> Annotation[] getDeclaredAnnotations(C context, |
|
|
|
|
|
|
|
AnnotatedElement source, @Nullable BiPredicate<C, Class<?>> classFilter, boolean copy) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (source instanceof Class && isFiltered((Class<?>) source, context, classFilter)) { |
|
|
|
|
|
|
|
return NO_ANNOTATIONS; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (source instanceof Method && isFiltered(((Method) source).getDeclaringClass(), context, classFilter)) { |
|
|
|
|
|
|
|
return NO_ANNOTATIONS; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return getDeclaredAnnotations(source, copy); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
static <A extends Annotation> A getDeclaredAnnotation(AnnotatedElement source, Class<A> annotationType) { |
|
|
|
static <A extends Annotation> A getDeclaredAnnotation(AnnotatedElement source, Class<A> annotationType) { |
|
|
|
@ -525,12 +477,6 @@ abstract class AnnotationsScanner { |
|
|
|
return annotations.clone(); |
|
|
|
return annotations.clone(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static <C> boolean isFiltered( |
|
|
|
|
|
|
|
Class<?> sourceClass, C context, @Nullable BiPredicate<C, Class<?>> classFilter) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (classFilter != null && classFilter.test(context, sourceClass)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static boolean isIgnorable(Class<?> annotationType) { |
|
|
|
private static boolean isIgnorable(Class<?> annotationType) { |
|
|
|
return AnnotationFilter.PLAIN.matches(annotationType); |
|
|
|
return AnnotationFilter.PLAIN.matches(annotationType); |
|
|
|
} |
|
|
|
} |
|
|
|
|