1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.scanner.classpath.types;
17
18 import java.util.HashSet;
19 import java.util.Set;
20
21 import javassist.bytecode.annotation.Annotation;
22
23 import org.apache.commons.lang3.builder.EqualsBuilder;
24 import org.apache.commons.lang3.builder.HashCodeBuilder;
25 import org.apache.commons.lang3.builder.ToStringBuilder;
26 import org.apache.commons.lang3.builder.ToStringStyle;
27 import org.jadira.scanner.classpath.ClasspathResolver;
28 import org.jadira.scanner.classpath.visitor.IntrospectionVisitor;
29 import org.jadira.scanner.core.exception.ClasspathAccessException;
30 import org.jadira.scanner.core.helper.JavassistAnnotationsHelper;
31
32 public class JAnnotation<A extends java.lang.annotation.Annotation> extends JType {
33
34 private JElement enclosingElement;
35
36 protected JAnnotation(Annotation annotation, JElement enclosingElement, ClasspathResolver resolver) {
37 super(findClassFile(annotation.getTypeName(), resolver), resolver);
38 this.enclosingElement = enclosingElement;
39 }
40
41 protected JAnnotation(java.lang.annotation.Annotation annotation, JElement enclosingElement, ClasspathResolver resolver) {
42 super(findClassFile(annotation.annotationType().getName(), resolver), resolver);
43 this.enclosingElement = enclosingElement;
44 }
45
46 public JClass getSuperType() throws ClasspathAccessException {
47
48 final String superClassFile = getClassFile().getSuperclass();
49 return JClass.getJClass(superClassFile, getResolver());
50 }
51
52 public Class<?> getActualSuperType() throws ClasspathAccessException {
53 return getSuperType().getActualClass();
54 }
55
56 public static JAnnotation<?> getJAnnotation(Annotation nextAnnotation, JElement enclosingElement, ClasspathResolver resolver) {
57 return new JAnnotation<java.lang.annotation.Annotation>(nextAnnotation, enclosingElement, resolver);
58 }
59
60 public static <A extends java.lang.annotation.Annotation> JAnnotation<A> getJAnnotation(A nextAnnotation, JElement enclosingElement, ClasspathResolver resolver) {
61 return new JAnnotation<A>(nextAnnotation, enclosingElement, resolver);
62 }
63
64 public A getActualAnnotation() throws ClasspathAccessException {
65
66 final java.lang.annotation.Annotation[] annotations;
67 if (enclosingElement instanceof JOperation) {
68 annotations = JavassistAnnotationsHelper.getAnnotationsForMethod(((JOperation)enclosingElement).getMethodInfo());
69 } else if (enclosingElement instanceof JField) {
70 annotations = JavassistAnnotationsHelper.getAnnotationsForFieldInfo(((JField)enclosingElement).getFieldInfo());
71 } else if (enclosingElement instanceof JParameter) {
72 annotations = JavassistAnnotationsHelper.getAnnotationsForMethodParameter(((JMethod)enclosingElement).getMethodInfo(), ((JParameter)enclosingElement).getIndex());
73 } else if (enclosingElement instanceof JPackage) {
74 annotations = ((JPackage)enclosingElement).getAnnotationsForPackage();
75 } else {
76 annotations = JavassistAnnotationsHelper.getAnnotationsForClass(((JType)enclosingElement).getClassFile());
77 }
78
79 String requiredName = getActualClass().getName();
80 for (java.lang.annotation.Annotation next : annotations) {
81 String nextName = next.annotationType().getName();
82 if (nextName.equals(requiredName)) {
83 @SuppressWarnings("unchecked") final A retVal = (A) next;
84 return retVal;
85 }
86 }
87 throw new ClasspathAccessException("Could not find annotation of type " + getActualClass() + " for " + enclosingElement);
88 }
89
90 @Override
91 public Set<JAnnotation<?>> getAnnotations() throws ClasspathAccessException {
92
93 Set<JAnnotation<?>> retVal = new HashSet<JAnnotation<?>>();
94 java.lang.annotation.Annotation[] anns = JavassistAnnotationsHelper.getAnnotationsForClass(getClassFile());
95 for(java.lang.annotation.Annotation next : anns) {
96 retVal.add(JAnnotation.getJAnnotation(next, this, getResolver()));
97 }
98 return retVal;
99 }
100
101 @Override
102 public JPackage getPackage() throws ClasspathAccessException {
103 return JPackage.getJPackage(getName().substring(0, getName().lastIndexOf(".")), getResolver());
104 }
105
106 @Override
107 public Class<A> getActualClass() throws ClasspathAccessException {
108
109 @SuppressWarnings("unchecked")
110 Class<A> retVal = (Class<A>) getResolver().loadClass(getClassFile().getName());
111 return retVal;
112 }
113
114 @Override
115 public void acceptVisitor(IntrospectionVisitor visitor) {
116 visitor.visit(this);
117 }
118
119 @Override
120 public JElement getEnclosingElement() {
121 return enclosingElement;
122 }
123
124 @Override
125 public String toString() {
126
127 ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
128 builder.append("name", getName());
129 builder.append("enclosingElement", getEnclosingElement());
130
131 return builder.toString();
132 }
133
134 @Override
135 public boolean equals(Object obj) {
136 if (obj == null) {
137 return false;
138 }
139 if (obj == this) {
140 return true;
141 }
142 if (obj.getClass() != getClass()) {
143 return false;
144 }
145 JAnnotation<?> rhs = (JAnnotation<?>) obj;
146 return new EqualsBuilder()
147 .appendSuper(super.equals(obj))
148 .append(enclosingElement, rhs.enclosingElement).isEquals();
149 }
150
151 @Override
152 public int hashCode() {
153 return new HashCodeBuilder(11, 47).append(super.hashCode())
154 .append(enclosingElement).toHashCode();
155 }
156 }