29
29
30
30
import org .springframework .core .BridgeMethodResolver ;
31
31
import org .springframework .util .Assert ;
32
+ import org .springframework .util .CollectionUtils ;
32
33
import org .springframework .util .LinkedMultiValueMap ;
33
34
import org .springframework .util .MultiValueMap ;
34
35
@@ -240,7 +241,6 @@ private static boolean hasMetaAnnotationTypes(AnnotatedElement element, Class<?
240
241
241
242
return Boolean .TRUE .equals (
242
243
searchWithGetSemantics (element , annotationType , annotationName , new SimpleAnnotationProcessor <Boolean >() {
243
-
244
244
@ Override
245
245
public Boolean process (AnnotatedElement annotatedElement , Annotation annotation , int metaDepth ) {
246
246
return (metaDepth > 0 ? Boolean .TRUE : CONTINUE );
@@ -270,7 +270,6 @@ public static boolean isAnnotated(AnnotatedElement element, Class<? extends Anno
270
270
if (element .isAnnotationPresent (annotationType )) {
271
271
return true ;
272
272
}
273
-
274
273
return Boolean .TRUE .equals (searchWithGetSemantics (element , annotationType , null , alwaysTrueAnnotationProcessor ));
275
274
}
276
275
@@ -615,7 +614,6 @@ public static boolean hasAnnotation(AnnotatedElement element, Class<? extends An
615
614
if (element .isAnnotationPresent (annotationType )) {
616
615
return true ;
617
616
}
618
-
619
617
return Boolean .TRUE .equals (searchWithFindSemantics (element , annotationType , null , alwaysTrueAnnotationProcessor ));
620
618
}
621
619
@@ -873,8 +871,8 @@ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(Anno
873
871
* @param processor the processor to delegate to
874
872
* @return the result of the processor (potentially {@code null})
875
873
*/
876
- private static <T > T searchWithGetSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
877
- String annotationName , Processor <T > processor ) {
874
+ private static <T > T searchWithGetSemantics (AnnotatedElement element ,
875
+ Class <? extends Annotation > annotationType , String annotationName , Processor <T > processor ) {
878
876
879
877
return searchWithGetSemantics (element , annotationType , annotationName , null , processor );
880
878
}
@@ -893,12 +891,13 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
893
891
* @return the result of the processor (potentially {@code null})
894
892
* @since 4.3
895
893
*/
896
- private static <T > T searchWithGetSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
897
- String annotationName , Class <? extends Annotation > containerType , Processor <T > processor ) {
894
+ private static <T > T searchWithGetSemantics (AnnotatedElement element ,
895
+ Class <? extends Annotation > annotationType , String annotationName ,
896
+ Class <? extends Annotation > containerType , Processor <T > processor ) {
898
897
899
898
try {
900
- return searchWithGetSemantics (element , annotationType , annotationName , containerType , processor ,
901
- new HashSet <AnnotatedElement >(), 0 );
899
+ return searchWithGetSemantics (element , annotationType , annotationName ,
900
+ containerType , processor , new HashSet <AnnotatedElement >(), 0 );
902
901
}
903
902
catch (Throwable ex ) {
904
903
AnnotationUtils .rethrowAnnotationConfigurationException (ex );
@@ -923,8 +922,9 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
923
922
* @param metaDepth the meta-depth of the annotation
924
923
* @return the result of the processor (potentially {@code null})
925
924
*/
926
- private static <T > T searchWithGetSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
927
- String annotationName , Class <? extends Annotation > containerType , Processor <T > processor ,
925
+ private static <T > T searchWithGetSemantics (AnnotatedElement element ,
926
+ Class <? extends Annotation > annotationType , String annotationName ,
927
+ Class <? extends Annotation > containerType , Processor <T > processor ,
928
928
Set <AnnotatedElement > visited , int metaDepth ) {
929
929
930
930
Assert .notNull (element , "AnnotatedElement must not be null" );
@@ -939,7 +939,7 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
939
939
return result ;
940
940
}
941
941
942
- if (element instanceof Class ) { // otherwise getAnnotations doesn't return anything new
942
+ if (element instanceof Class ) { // otherwise getAnnotations does not return anything new
943
943
List <Annotation > inheritedAnnotations = new ArrayList <Annotation >();
944
944
for (Annotation annotation : element .getAnnotations ()) {
945
945
if (!declaredAnnotations .contains (annotation )) {
@@ -986,9 +986,9 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
986
986
* @since 4.2
987
987
*/
988
988
private static <T > T searchWithGetSemanticsInAnnotations (AnnotatedElement element ,
989
- List <Annotation > annotations , Class <? extends Annotation > annotationType , String annotationName ,
990
- Class <? extends Annotation > containerType , Processor < T > processor , Set < AnnotatedElement > visited ,
991
- int metaDepth ) {
989
+ List <Annotation > annotations , Class <? extends Annotation > annotationType ,
990
+ String annotationName , Class <? extends Annotation > containerType ,
991
+ Processor < T > processor , Set < AnnotatedElement > visited , int metaDepth ) {
992
992
993
993
// Search in annotations
994
994
for (Annotation annotation : annotations ) {
@@ -1054,7 +1054,8 @@ else if (currentAnnotationType == containerType) {
1054
1054
* @return the result of the processor (potentially {@code null})
1055
1055
* @since 4.2
1056
1056
*/
1057
- private static <T > T searchWithFindSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
1057
+ private static <T > T searchWithFindSemantics (AnnotatedElement element ,
1058
+ Class <? extends Annotation > annotationType ,
1058
1059
String annotationName , Processor <T > processor ) {
1059
1060
1060
1061
return searchWithFindSemantics (element , annotationType , annotationName , null , processor );
@@ -1074,17 +1075,18 @@ private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? e
1074
1075
* @return the result of the processor (potentially {@code null})
1075
1076
* @since 4.3
1076
1077
*/
1077
- private static <T > T searchWithFindSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
1078
- String annotationName , Class <? extends Annotation > containerType , Processor <T > processor ) {
1078
+ private static <T > T searchWithFindSemantics (AnnotatedElement element ,
1079
+ Class <? extends Annotation > annotationType , String annotationName ,
1080
+ Class <? extends Annotation > containerType , Processor <T > processor ) {
1079
1081
1080
1082
if (containerType != null && !processor .aggregates ()) {
1081
1083
throw new IllegalArgumentException (
1082
1084
"Searches for repeatable annotations must supply an aggregating Processor" );
1083
1085
}
1084
1086
1085
1087
try {
1086
- return searchWithFindSemantics (
1087
- element , annotationType , annotationName , containerType , processor , new HashSet <AnnotatedElement >(), 0 );
1088
+ return searchWithFindSemantics (element , annotationType , annotationName ,
1089
+ containerType , processor , new HashSet <AnnotatedElement >(), 0 );
1088
1090
}
1089
1091
catch (Throwable ex ) {
1090
1092
AnnotationUtils .rethrowAnnotationConfigurationException (ex );
@@ -1120,79 +1122,86 @@ private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? e
1120
1122
try {
1121
1123
// Locally declared annotations (ignoring @Inherited)
1122
1124
Annotation [] annotations = element .getDeclaredAnnotations ();
1123
- List <T > aggregatedResults = (processor .aggregates () ? new ArrayList <T >() : null );
1124
-
1125
- // Search in local annotations
1126
- for (Annotation annotation : annotations ) {
1127
- Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1128
- if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1129
- if (currentAnnotationType == annotationType ||
1130
- currentAnnotationType .getName ().equals (annotationName ) ||
1131
- processor .alwaysProcesses ()) {
1132
- T result = processor .process (element , annotation , metaDepth );
1133
- if (result != null ) {
1134
- if (processor .aggregates () && metaDepth == 0 ) {
1135
- aggregatedResults .add (result );
1136
- }
1137
- else {
1138
- return result ;
1125
+ if (annotations .length > 0 ) {
1126
+ List <T > aggregatedResults = (processor .aggregates () ? new ArrayList <T >() : null );
1127
+
1128
+ // Search in local annotations
1129
+ for (Annotation annotation : annotations ) {
1130
+ Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1131
+ if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1132
+ if (currentAnnotationType == annotationType ||
1133
+ currentAnnotationType .getName ().equals (annotationName ) ||
1134
+ processor .alwaysProcesses ()) {
1135
+ T result = processor .process (element , annotation , metaDepth );
1136
+ if (result != null ) {
1137
+ if (aggregatedResults != null && metaDepth == 0 ) {
1138
+ aggregatedResults .add (result );
1139
+ }
1140
+ else {
1141
+ return result ;
1142
+ }
1139
1143
}
1140
1144
}
1141
- }
1142
- // Repeatable annotations in container?
1143
- else if ( currentAnnotationType == containerType ) {
1144
- for ( Annotation contained : getRawAnnotationsFromContainer (element , annotation )) {
1145
- T result = processor . process ( element , contained , metaDepth );
1146
- if ( result != null ) {
1147
- // No need to post-process since repeatable annotations within a
1148
- // container cannot be composed annotations.
1149
- aggregatedResults . add ( result );
1145
+ // Repeatable annotations in container?
1146
+ else if ( currentAnnotationType == containerType ) {
1147
+ for ( Annotation contained : getRawAnnotationsFromContainer ( element , annotation ) ) {
1148
+ T result = processor . process (element , contained , metaDepth );
1149
+ if ( aggregatedResults != null && result != null ) {
1150
+ // No need to post-process since repeatable annotations within a
1151
+ // container cannot be composed annotations.
1152
+ aggregatedResults . add ( result );
1153
+ }
1150
1154
}
1151
1155
}
1152
1156
}
1153
1157
}
1154
- }
1155
1158
1156
- // Search in meta annotations on local annotations
1157
- for (Annotation annotation : annotations ) {
1158
- Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1159
- if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1160
- T result = searchWithFindSemantics (currentAnnotationType , annotationType , annotationName ,
1161
- containerType , processor , visited , metaDepth + 1 );
1162
- if (result != null ) {
1163
- processor .postProcess (currentAnnotationType , annotation , result );
1164
- if (processor .aggregates () && metaDepth == 0 ) {
1165
- aggregatedResults .add (result );
1166
- }
1167
- else {
1168
- return result ;
1159
+ // Recursively search in meta-annotations
1160
+ for (Annotation annotation : annotations ) {
1161
+ Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1162
+ if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1163
+ T result = searchWithFindSemantics (currentAnnotationType , annotationType , annotationName ,
1164
+ containerType , processor , visited , metaDepth + 1 );
1165
+ if (result != null ) {
1166
+ processor .postProcess (currentAnnotationType , annotation , result );
1167
+ if (aggregatedResults != null && metaDepth == 0 ) {
1168
+ aggregatedResults .add (result );
1169
+ }
1170
+ else {
1171
+ return result ;
1172
+ }
1169
1173
}
1170
1174
}
1171
1175
}
1172
- }
1173
1176
1174
- if (processor .aggregates ()) {
1175
- // Prepend to support top-down ordering within class hierarchies
1176
- processor .getAggregatedResults ().addAll (0 , aggregatedResults );
1177
+ if (!CollectionUtils .isEmpty (aggregatedResults )) {
1178
+ // Prepend to support top-down ordering within class hierarchies
1179
+ processor .getAggregatedResults ().addAll (0 , aggregatedResults );
1180
+ }
1177
1181
}
1178
1182
1179
1183
if (element instanceof Method ) {
1180
1184
Method method = (Method ) element ;
1185
+ T result ;
1181
1186
1182
1187
// Search on possibly bridged method
1183
1188
Method resolvedMethod = BridgeMethodResolver .findBridgedMethod (method );
1184
- T result = searchWithFindSemantics (resolvedMethod , annotationType , annotationName , containerType ,
1185
- processor , visited , metaDepth );
1186
- if (result != null ) {
1187
- return result ;
1189
+ if (resolvedMethod != method ) {
1190
+ result = searchWithFindSemantics (resolvedMethod , annotationType , annotationName ,
1191
+ containerType , processor , visited , metaDepth );
1192
+ if (result != null ) {
1193
+ return result ;
1194
+ }
1188
1195
}
1189
1196
1190
1197
// Search on methods in interfaces declared locally
1191
1198
Class <?>[] ifcs = method .getDeclaringClass ().getInterfaces ();
1192
- result = searchOnInterfaces (method , annotationType , annotationName , containerType , processor ,
1193
- visited , metaDepth , ifcs );
1194
- if (result != null ) {
1195
- return result ;
1199
+ if (ifcs .length > 0 ) {
1200
+ result = searchOnInterfaces (method , annotationType , annotationName ,
1201
+ containerType , processor , visited , metaDepth , ifcs );
1202
+ if (result != null ) {
1203
+ return result ;
1204
+ }
1196
1205
}
1197
1206
1198
1207
// Search on methods in class hierarchy and interface hierarchy
@@ -1202,7 +1211,6 @@ else if (currentAnnotationType == containerType) {
1202
1211
if (clazz == null || Object .class == clazz ) {
1203
1212
break ;
1204
1213
}
1205
-
1206
1214
try {
1207
1215
Method equivalentMethod = clazz .getDeclaredMethod (method .getName (), method .getParameterTypes ());
1208
1216
Method resolvedEquivalentMethod = BridgeMethodResolver .findBridgedMethod (equivalentMethod );
@@ -1215,10 +1223,9 @@ else if (currentAnnotationType == containerType) {
1215
1223
catch (NoSuchMethodException ex ) {
1216
1224
// No equivalent method found
1217
1225
}
1218
-
1219
1226
// Search on interfaces declared on superclass
1220
- result = searchOnInterfaces (method , annotationType , annotationName , containerType , processor ,
1221
- visited , metaDepth , clazz .getInterfaces ());
1227
+ result = searchOnInterfaces (method , annotationType , annotationName ,
1228
+ containerType , processor , visited , metaDepth , clazz .getInterfaces ());
1222
1229
if (result != null ) {
1223
1230
return result ;
1224
1231
}
@@ -1229,8 +1236,8 @@ else if (element instanceof Class) {
1229
1236
1230
1237
// Search on interfaces
1231
1238
for (Class <?> ifc : clazz .getInterfaces ()) {
1232
- T result = searchWithFindSemantics (ifc , annotationType , annotationName , containerType ,
1233
- processor , visited , metaDepth );
1239
+ T result = searchWithFindSemantics (ifc , annotationType , annotationName ,
1240
+ containerType , processor , visited , metaDepth );
1234
1241
if (result != null ) {
1235
1242
return result ;
1236
1243
}
@@ -1239,8 +1246,8 @@ else if (element instanceof Class) {
1239
1246
// Search on superclass
1240
1247
Class <?> superclass = clazz .getSuperclass ();
1241
1248
if (superclass != null && Object .class != superclass ) {
1242
- T result = searchWithFindSemantics (superclass , annotationType , annotationName , containerType ,
1243
- processor , visited , metaDepth );
1249
+ T result = searchWithFindSemantics (superclass , annotationType , annotationName ,
1250
+ containerType , processor , visited , metaDepth );
1244
1251
if (result != null ) {
1245
1252
return result ;
1246
1253
}
0 commit comments