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