View Javadoc
1   /*
2    *  Copyright 2012 Chris Pheby
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.jadira.scanner.core.helper;
17  
18  import java.lang.annotation.Annotation;
19  import java.util.Collections;
20  import java.util.HashSet;
21  import java.util.Set;
22  
23  import javassist.ClassPool;
24  import javassist.bytecode.AnnotationsAttribute;
25  import javassist.bytecode.ClassFile;
26  import javassist.bytecode.FieldInfo;
27  import javassist.bytecode.MethodInfo;
28  import javassist.bytecode.ParameterAnnotationsAttribute;
29  
30  import org.jadira.scanner.core.exception.ClasspathAccessException;
31  
32  public final class JavassistAnnotationsHelper {
33  
34      private static final ClassPool CLASS_POOL = ClassPool.getDefault();
35  	
36  	private JavassistAnnotationsHelper() {
37  	}
38  
39  	public static Annotation[] getAnnotationsForClass(ClassFile classFile) {
40  
41  		AnnotationsAttribute visible = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag);
42  		AnnotationsAttribute invisible = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.invisibleTag);
43  
44  		Set<Annotation> retVal = new HashSet<Annotation>();
45  
46  		retVal.addAll(findAnnotationsForAnnotationsAttribute(visible));
47  		retVal.addAll(findAnnotationsForAnnotationsAttribute(invisible));
48  
49  		return retVal.toArray(new Annotation[retVal.size()]);
50  	}
51  	
52  	public static Annotation[] getAnnotationsForMethod(MethodInfo methodInfo) {
53  
54  		AnnotationsAttribute visible = (AnnotationsAttribute) methodInfo.getAttribute(AnnotationsAttribute.visibleTag);
55  		AnnotationsAttribute invisible = (AnnotationsAttribute) methodInfo.getAttribute(AnnotationsAttribute.invisibleTag);
56  
57  		Set<Annotation> retVal = new HashSet<Annotation>();
58  
59  		retVal.addAll(findAnnotationsForAnnotationsAttribute(visible));
60  		retVal.addAll(findAnnotationsForAnnotationsAttribute(invisible));
61  
62  		return retVal.toArray(new Annotation[retVal.size()]);
63  	}
64  
65  	public static Annotation[] getAnnotationsForMethodParameter(MethodInfo methodInfo, int index) {
66  
67  		ParameterAnnotationsAttribute visible = (ParameterAnnotationsAttribute) methodInfo.getAttribute(ParameterAnnotationsAttribute.visibleTag);
68  		ParameterAnnotationsAttribute invisible = (ParameterAnnotationsAttribute) methodInfo.getAttribute(ParameterAnnotationsAttribute.invisibleTag);
69  
70  		Set<Annotation> retVal = new HashSet<Annotation>();
71  
72  		retVal.addAll(findAnnotationsForAnnotationsArray(visible.getAnnotations()[index]));
73  		retVal.addAll(findAnnotationsForAnnotationsArray(invisible.getAnnotations()[index]));
74  
75  		return retVal.toArray(new Annotation[retVal.size()]);
76  	}
77  
78  	public static Annotation[] getAnnotationsForFieldInfo(FieldInfo fieldInfo) {
79  
80  		AnnotationsAttribute visible = (AnnotationsAttribute) fieldInfo.getAttribute(AnnotationsAttribute.visibleTag);
81  		AnnotationsAttribute invisible = (AnnotationsAttribute) fieldInfo.getAttribute(AnnotationsAttribute.invisibleTag);
82  
83  		Set<Annotation> retVal = new HashSet<Annotation>();
84  
85  		retVal.addAll(findAnnotationsForAnnotationsAttribute(visible));
86  		retVal.addAll(findAnnotationsForAnnotationsAttribute(invisible));
87  
88  		return retVal.toArray(new Annotation[retVal.size()]);
89  	}
90  
91  	private static Set<Annotation> findAnnotationsForAnnotationsAttribute(AnnotationsAttribute attr) {
92  
93  		if (attr != null) {
94  			javassist.bytecode.annotation.Annotation[] anns = attr.getAnnotations();
95  			return findAnnotationsForAnnotationsArray(anns);
96  		}
97  		return Collections.emptySet();
98  	}
99  
100 	private static Set<Annotation> findAnnotationsForAnnotationsArray(javassist.bytecode.annotation.Annotation[] anns) {
101 
102 		final Set<Annotation> retVal = new HashSet<Annotation>();
103 		for (javassist.bytecode.annotation.Annotation next : anns) {
104 
105 			try {
106 				final Annotation toAdd = (Annotation) (next.toAnnotationType(JavassistAnnotationsHelper.class.getClassLoader(), CLASS_POOL));
107 				retVal.add(toAdd);
108 			} catch (ClassNotFoundException e) {
109 				throw new ClasspathAccessException("Problem finding class for annotation: " + e.getMessage(), e);
110 			}
111 		}
112 		return retVal;
113 	}
114 }