1717package org .springframework .core .type .classreading ;
1818
1919import java .lang .annotation .Annotation ;
20- import java .lang .reflect .Array ;
21- import java .lang .reflect .Field ;
22- import java .lang .reflect .Method ;
2320import java .lang .reflect .Modifier ;
24- import java .util .ArrayList ;
2521import java .util .LinkedHashSet ;
2622import java .util .List ;
2723import java .util .Map ;
2824import java .util .Set ;
2925
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 ;
3626import org .springframework .core .annotation .AnnotationAttributes ;
3727import org .springframework .core .annotation .AnnotationUtils ;
3828import 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-
22529
22630/**
22731 * ASM visitor which looks for the annotations defined on a class or method, including
@@ -245,6 +49,7 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib
24549
24650 private final Map <String , Set <String >> metaAnnotationMap ;
24751
52+
24853 public AnnotationAttributesReadingVisitor (String annotationType ,
24954 MultiValueMap <String , AnnotationAttributes > attributesMap , Map <String , Set <String >> metaAnnotationMap ,
25055 ClassLoader classLoader ) {
@@ -255,6 +60,7 @@ public AnnotationAttributesReadingVisitor(String annotationType,
25560 this .metaAnnotationMap = metaAnnotationMap ;
25661 }
25762
63+
25864 @ Override
25965 public void doVisitEnd (Class <?> annotationClass ) {
26066 super .doVisitEnd (annotationClass );
@@ -266,7 +72,7 @@ public void doVisitEnd(Class<?> annotationClass) {
26672 attributes .add (0 , this .attributes );
26773 }
26874 Set <String > metaAnnotationTypeNames = new LinkedHashSet <String >();
269- for (Annotation metaAnnotation : annotationClass .getAnnotations ()) {
75+ for (Annotation metaAnnotation : AnnotationUtils .getAnnotations (annotationClass )) {
27076 if (!AnnotationUtils .isInJavaLangAnnotationPackage (metaAnnotation )) {
27177 recursivelyCollectMetaAnnotations (metaAnnotationTypeNames , metaAnnotation );
27278 }
0 commit comments