17
17
package org .springframework .core .type .classreading ;
18
18
19
19
import java .lang .annotation .Annotation ;
20
- import java .lang .reflect .Array ;
21
- import java .lang .reflect .Field ;
22
- import java .lang .reflect .Method ;
23
20
import java .lang .reflect .Modifier ;
24
- import java .util .ArrayList ;
25
21
import java .util .LinkedHashSet ;
26
22
import java .util .List ;
27
23
import java .util .Map ;
28
24
import java .util .Set ;
29
25
30
- import org .apache .commons .logging .Log ;
31
- import org .apache .commons .logging .LogFactory ;
32
-
33
- import org .springframework .asm .AnnotationVisitor ;
34
- import org .springframework .asm .SpringAsmInfo ;
35
- import org .springframework .asm .Type ;
36
26
import org .springframework .core .annotation .AnnotationAttributes ;
37
27
import org .springframework .core .annotation .AnnotationUtils ;
38
28
import org .springframework .util .MultiValueMap ;
39
- import org .springframework .util .ObjectUtils ;
40
- import org .springframework .util .ReflectionUtils ;
41
-
42
- /**
43
- * @author Chris Beams
44
- * @author Juergen Hoeller
45
- * @author Phillip Webb
46
- * @author Sam Brannen
47
- * @since 3.1.1
48
- */
49
- abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor {
50
-
51
- protected final Log logger = LogFactory .getLog (getClass ());
52
-
53
- protected final AnnotationAttributes attributes ;
54
-
55
- protected final ClassLoader classLoader ;
56
-
57
- public AbstractRecursiveAnnotationVisitor (ClassLoader classLoader , AnnotationAttributes attributes ) {
58
- super (SpringAsmInfo .ASM_VERSION );
59
- this .classLoader = classLoader ;
60
- this .attributes = attributes ;
61
- }
62
-
63
- @ Override
64
- public void visit (String attributeName , Object attributeValue ) {
65
- this .attributes .put (attributeName , attributeValue );
66
- }
67
-
68
- @ Override
69
- public AnnotationVisitor visitAnnotation (String attributeName , String asmTypeDescriptor ) {
70
- String annotationType = Type .getType (asmTypeDescriptor ).getClassName ();
71
- AnnotationAttributes nestedAttributes = new AnnotationAttributes ();
72
- this .attributes .put (attributeName , nestedAttributes );
73
- return new RecursiveAnnotationAttributesVisitor (annotationType , nestedAttributes , this .classLoader );
74
- }
75
-
76
- @ Override
77
- public AnnotationVisitor visitArray (String attributeName ) {
78
- return new RecursiveAnnotationArrayVisitor (attributeName , this .attributes , this .classLoader );
79
- }
80
-
81
- @ Override
82
- public void visitEnum (String attributeName , String asmTypeDescriptor , String attributeValue ) {
83
- Object newValue = getEnumValue (asmTypeDescriptor , attributeValue );
84
- visit (attributeName , newValue );
85
- }
86
-
87
- protected Object getEnumValue (String asmTypeDescriptor , String attributeValue ) {
88
- Object valueToUse = attributeValue ;
89
- try {
90
- Class <?> enumType = this .classLoader .loadClass (Type .getType (asmTypeDescriptor ).getClassName ());
91
- Field enumConstant = ReflectionUtils .findField (enumType , attributeValue );
92
- if (enumConstant != null ) {
93
- valueToUse = enumConstant .get (null );
94
- }
95
- }
96
- catch (ClassNotFoundException ex ) {
97
- logger .debug ("Failed to classload enum type while reading annotation metadata" , ex );
98
- }
99
- catch (IllegalAccessException ex ) {
100
- logger .warn ("Could not access enum value while reading annotation metadata" , ex );
101
- }
102
- return valueToUse ;
103
- }
104
- }
105
-
106
-
107
- /**
108
- * @author Chris Beams
109
- * @author Juergen Hoeller
110
- * @since 3.1.1
111
- */
112
- final class RecursiveAnnotationArrayVisitor extends AbstractRecursiveAnnotationVisitor {
113
-
114
- private final String attributeName ;
115
-
116
- private final List <AnnotationAttributes > allNestedAttributes = new ArrayList <AnnotationAttributes >();
117
-
118
- public RecursiveAnnotationArrayVisitor (
119
- String attributeName , AnnotationAttributes attributes , ClassLoader classLoader ) {
120
- super (classLoader , attributes );
121
- this .attributeName = attributeName ;
122
- }
123
-
124
- @ Override
125
- public void visit (String attributeName , Object attributeValue ) {
126
- Object newValue = attributeValue ;
127
- Object existingValue = this .attributes .get (this .attributeName );
128
- if (existingValue != null ) {
129
- newValue = ObjectUtils .addObjectToArray ((Object []) existingValue , newValue );
130
- }
131
- else {
132
- Class <?> arrayClass = newValue .getClass ();
133
- if (Enum .class .isAssignableFrom (arrayClass )) {
134
- while (arrayClass .getSuperclass () != null && !arrayClass .isEnum ()) {
135
- arrayClass = arrayClass .getSuperclass ();
136
- }
137
- }
138
- Object [] newArray = (Object []) Array .newInstance (arrayClass , 1 );
139
- newArray [0 ] = newValue ;
140
- newValue = newArray ;
141
- }
142
- this .attributes .put (this .attributeName , newValue );
143
- }
144
-
145
- @ Override
146
- public AnnotationVisitor visitAnnotation (String attributeName , String asmTypeDescriptor ) {
147
- String annotationType = Type .getType (asmTypeDescriptor ).getClassName ();
148
- AnnotationAttributes nestedAttributes = new AnnotationAttributes ();
149
- this .allNestedAttributes .add (nestedAttributes );
150
- return new RecursiveAnnotationAttributesVisitor (annotationType , nestedAttributes , this .classLoader );
151
- }
152
-
153
- @ Override
154
- public void visitEnd () {
155
- if (!this .allNestedAttributes .isEmpty ()) {
156
- this .attributes .put (this .attributeName ,
157
- this .allNestedAttributes .toArray (new AnnotationAttributes [this .allNestedAttributes .size ()]));
158
- }
159
- }
160
- }
161
-
162
-
163
- /**
164
- * @author Chris Beams
165
- * @author Juergen Hoeller
166
- * @since 3.1.1
167
- */
168
- class RecursiveAnnotationAttributesVisitor extends AbstractRecursiveAnnotationVisitor {
169
-
170
- private final String annotationType ;
171
-
172
- public RecursiveAnnotationAttributesVisitor (String annotationType , AnnotationAttributes attributes ,
173
- ClassLoader classLoader ) {
174
- super (classLoader , attributes );
175
- this .annotationType = annotationType ;
176
- }
177
-
178
- @ Override
179
- public final void visitEnd () {
180
- try {
181
- Class <?> annotationClass = this .classLoader .loadClass (this .annotationType );
182
- doVisitEnd (annotationClass );
183
- }
184
- catch (ClassNotFoundException ex ) {
185
- logger .debug ("Failed to class-load type while reading annotation metadata. " +
186
- "This is a non-fatal error, but certain annotation metadata may be unavailable." , ex );
187
- }
188
- }
189
-
190
- protected void doVisitEnd (Class <?> annotationClass ) {
191
- registerDefaultValues (annotationClass );
192
- }
193
-
194
- private void registerDefaultValues (Class <?> annotationClass ) {
195
- // Only do further scanning for public annotations; we'd run into
196
- // IllegalAccessExceptions otherwise, and we don't want to mess with
197
- // accessibility in a SecurityManager environment.
198
- if (Modifier .isPublic (annotationClass .getModifiers ())) {
199
- // Check declared default values of attributes in the annotation type.
200
- Method [] annotationAttributes = annotationClass .getMethods ();
201
- for (Method annotationAttribute : annotationAttributes ) {
202
- String attributeName = annotationAttribute .getName ();
203
- Object defaultValue = annotationAttribute .getDefaultValue ();
204
- if (defaultValue != null && !this .attributes .containsKey (attributeName )) {
205
- if (defaultValue instanceof Annotation ) {
206
- defaultValue = AnnotationAttributes .fromMap (AnnotationUtils .getAnnotationAttributes (
207
- (Annotation ) defaultValue , false , true ));
208
- }
209
- else if (defaultValue instanceof Annotation []) {
210
- Annotation [] realAnnotations = (Annotation []) defaultValue ;
211
- AnnotationAttributes [] mappedAnnotations = new AnnotationAttributes [realAnnotations .length ];
212
- for (int i = 0 ; i < realAnnotations .length ; i ++) {
213
- mappedAnnotations [i ] = AnnotationAttributes .fromMap (AnnotationUtils .getAnnotationAttributes (
214
- realAnnotations [i ], false , true ));
215
- }
216
- defaultValue = mappedAnnotations ;
217
- }
218
- this .attributes .put (attributeName , defaultValue );
219
- }
220
- }
221
- }
222
- }
223
- }
224
-
225
29
226
30
/**
227
31
* ASM visitor which looks for the annotations defined on a class or method, including
@@ -245,6 +49,7 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib
245
49
246
50
private final Map <String , Set <String >> metaAnnotationMap ;
247
51
52
+
248
53
public AnnotationAttributesReadingVisitor (String annotationType ,
249
54
MultiValueMap <String , AnnotationAttributes > attributesMap , Map <String , Set <String >> metaAnnotationMap ,
250
55
ClassLoader classLoader ) {
@@ -255,6 +60,7 @@ public AnnotationAttributesReadingVisitor(String annotationType,
255
60
this .metaAnnotationMap = metaAnnotationMap ;
256
61
}
257
62
63
+
258
64
@ Override
259
65
public void doVisitEnd (Class <?> annotationClass ) {
260
66
super .doVisitEnd (annotationClass );
@@ -266,7 +72,7 @@ public void doVisitEnd(Class<?> annotationClass) {
266
72
attributes .add (0 , this .attributes );
267
73
}
268
74
Set <String > metaAnnotationTypeNames = new LinkedHashSet <String >();
269
- for (Annotation metaAnnotation : annotationClass .getAnnotations ()) {
75
+ for (Annotation metaAnnotation : AnnotationUtils .getAnnotations (annotationClass )) {
270
76
if (!AnnotationUtils .isInJavaLangAnnotationPackage (metaAnnotation )) {
271
77
recursivelyCollectMetaAnnotations (metaAnnotationTypeNames , metaAnnotation );
272
78
}
0 commit comments