1 package com.atlassian.plugin.spring.scanner.core;
2
3 import com.google.common.base.Function;
4 import com.google.common.base.Joiner;
5 import com.google.common.collect.Lists;
6 import javassist.bytecode.AnnotationsAttribute;
7 import javassist.bytecode.ClassFile;
8 import javassist.bytecode.MethodInfo;
9 import javassist.bytecode.ParameterAnnotationsAttribute;
10 import javassist.bytecode.annotation.Annotation;
11 import javassist.bytecode.annotation.ArrayMemberValue;
12 import javassist.bytecode.annotation.ClassMemberValue;
13 import javassist.bytecode.annotation.MemberValue;
14 import javassist.bytecode.annotation.StringMemberValue;
15
16 import javax.annotation.Nullable;
17 import java.util.Collections;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21
22 import static com.google.common.collect.ImmutableList.copyOf;
23 import static com.google.common.collect.Iterables.transform;
24
25
26
27
28
29
30
31 public class JavassistHelper {
32 private static final Joiner ARRAY_MEMBER_VALUE_JOINER = Joiner.on(",");
33
34 public List<String> getClassAnnotationNames(final ClassFile aClass) {
35 return getAnnotationNames((AnnotationsAttribute) aClass.getAttribute(AnnotationsAttribute.visibleTag));
36 }
37
38 private List<String> getAnnotationNames(final AnnotationsAttribute... annotationsAttributes) {
39 final List<String> result = Lists.newArrayList();
40
41 if (annotationsAttributes != null) {
42 for (final AnnotationsAttribute annotationsAttribute : annotationsAttributes) {
43 if (annotationsAttribute != null) {
44 for (final Annotation annotation : annotationsAttribute.getAnnotations()) {
45 result.add(annotation.getTypeName());
46 }
47 }
48 }
49 }
50
51 return result;
52 }
53
54
55
56
57
58
59
60
61
62 Set<String> getAnnotationMemberSet(final ClassFile classFile, final String annotationType, final String memberName) {
63 final MemberValue value = getMemberValue(classFile, annotationType, memberName);
64 if (value != null && value instanceof ArrayMemberValue) {
65 final Set<String> values = new HashSet<String>();
66 final ArrayMemberValue arrayMemberValue = (ArrayMemberValue) value;
67 final MemberValue[] arrayMemberValueValues = arrayMemberValue.getValue();
68 for (final MemberValue memberValue : arrayMemberValueValues) {
69 if (memberValue != null) {
70 values.add(removeQuotes(memberValue.toString()));
71 }
72 }
73 return values;
74 }
75 return Collections.emptySet();
76 }
77
78 private MemberValue getMemberValue(final ClassFile classFile, final String annotationType, final String memberName) {
79 final AnnotationsAttribute annotations = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag);
80 final Annotation annotation = annotations.getAnnotation(annotationType);
81 return annotation == null ? null : annotation.getMemberValue(memberName);
82 }
83
84
85
86
87 private String removeQuotes(String s) {
88 if (s.startsWith("\"")) {
89 s = s.substring(1);
90 }
91 if (s.endsWith("\"")) {
92 s = s.substring(0, s.length() - 1);
93 }
94 return s;
95 }
96
97
98
99
100
101
102
103
104
105 String getAnnotationMember(final ClassFile classFile, final String annotationType, final String memberName) {
106 final MemberValue value = getMemberValue(classFile, annotationType, memberName);
107 return dataForMemberValue(value);
108 }
109
110
111
112
113
114
115
116
117 String getAnnotationMember(final Annotation annotation, final String memberName) {
118 final MemberValue value = annotation == null ? null : annotation.getMemberValue(memberName);
119 return dataForMemberValue(value);
120 }
121
122 private String dataForMemberValue(final MemberValue memberValue) {
123 if (memberValue instanceof StringMemberValue) {
124 return ((StringMemberValue) memberValue).getValue();
125 } else if (memberValue instanceof ClassMemberValue) {
126 return ((ClassMemberValue) memberValue).getValue();
127 } else if (memberValue instanceof ArrayMemberValue) {
128 final MemberValue[] entryValues = ((ArrayMemberValue) memberValue).getValue();
129 final Iterable<String> entryData = transform(copyOf(entryValues), new Function<MemberValue, String>() {
130 @Override
131 public String apply(@Nullable final MemberValue entryValue) {
132 return dataForMemberValue(entryValue);
133 }
134 });
135 return ARRAY_MEMBER_VALUE_JOINER.join(entryData);
136
137 } else {
138
139
140
141 return memberValue == null ? null : removeQuotes(memberValue.toString());
142 }
143 }
144
145
146
147
148
149
150
151
152 List<Annotation> getParameterAnnotations(final MethodInfo method, final int parameterIndex) {
153 final List<Annotation> result = Lists.newArrayList();
154
155 final ParameterAnnotationsAttribute parameterAnnotationsAttribute =
156 (ParameterAnnotationsAttribute) method.getAttribute(ParameterAnnotationsAttribute.visibleTag);
157 if (parameterAnnotationsAttribute != null) {
158 final Annotation[][] allAnnotations = parameterAnnotationsAttribute.getAnnotations();
159 if (parameterIndex < allAnnotations.length) {
160 final Annotation[] annotations = allAnnotations[parameterIndex];
161 if (annotations != null) {
162 Collections.addAll(result, annotations);
163 }
164 }
165 }
166 return result;
167 }
168
169
170 }