1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package com.salesforce.aptspring.processor;
28
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Map.Entry;
32
33 import javax.lang.model.element.AnnotationMirror;
34 import javax.lang.model.element.AnnotationValue;
35 import javax.lang.model.element.Element;
36 import javax.lang.model.element.ExecutableElement;
37 import javax.lang.model.element.TypeElement;
38 import javax.lang.model.element.VariableElement;
39 import javax.lang.model.util.SimpleAnnotationValueVisitor8;
40
41 public class AnnotationValueExtractor {
42
43 private static final String ALIAS_TYPE = "org.springframework.core.annotation.AliasFor";
44
45 private static final String ALIAS_TARGET_TYPE = "annotation";
46
47 private static final String ALIAS_TARGET_FIELD = "attribute";
48
49 private static final String DEFAULT_ANNOTATION_VALUE = "value";
50
51
52 private static class AliasData {
53 private String targetAnnotation = null;
54 private String targetField = null;
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68 public static String[] getAnnotationValue(Element e, String annotationTypeName, String methodName) {
69 if (e instanceof TypeElement) {
70
71 ((TypeElement) e).getSuperclass();
72 ((TypeElement) e).getInterfaces();
73 }
74 for (AnnotationMirror a : e.getAnnotationMirrors()) {
75 String[] returned = getAnnotationValue(a, annotationTypeName, methodName);
76 if (returned != null) {
77 return returned;
78 }
79 }
80 return null;
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94 private static String[] getAnnotationValue(AnnotationMirror am, String annotationTypeName, String methodName) {
95 String currentType = am.getAnnotationType().toString();
96 for (Entry<? extends ExecutableElement, ? extends AnnotationValue> ev : am.getElementValues().entrySet()) {
97 boolean aliasMatch = aliasMatch(getAlias(ev.getKey()), annotationTypeName, methodName, currentType);
98 boolean foundField = ev.getKey().getSimpleName().toString().equals(methodName);
99 if (aliasMatch || (foundField && currentType.equals(annotationTypeName))) {
100 AnnotationValueExtractorVisitor ex = new AnnotationValueExtractorVisitor();
101 List<String> values = new ArrayList<>();
102 ex.visit(ev.getValue(), values);
103 return values.toArray(new String[values.size()]);
104 }
105 }
106 if (currentType.equals(annotationTypeName)) {
107
108 return new String[]{};
109 }
110
111 for (AnnotationMirror a : am.getAnnotationType().getAnnotationMirrors()) {
112
113 if (!a.getAnnotationType().asElement().toString().startsWith("java.lang.annotation")) {
114 String[] output = getAnnotationValue(a, annotationTypeName, methodName);
115 if (output != null) {
116 return output;
117 }
118 }
119 }
120 return null;
121 }
122
123
124
125
126
127
128
129
130 private static AliasData getAlias(ExecutableElement annotationParameter) {
131 AliasData output = null;
132 for (AnnotationMirror am : annotationParameter.getAnnotationMirrors()) {
133 if (ALIAS_TYPE.equals(am.getAnnotationType().asElement().toString())) {
134 output = new AliasData();
135 for (Entry<? extends ExecutableElement, ? extends AnnotationValue> ev : am.getElementValues().entrySet()) {
136 String fieldName = ev.getKey().getSimpleName().toString();
137 if (ALIAS_TARGET_TYPE.equals(fieldName)) {
138 if (ev.getValue() != null && ev.getValue().getValue() != null) {
139 output.targetAnnotation = ev.getValue().getValue().toString();
140 } else {
141 return null;
142 }
143 }
144 if (ALIAS_TARGET_FIELD.equals(fieldName)
145 && ev.getValue() != null && ev.getValue().getValue() != null) {
146 output.targetField = ev.getValue().getValue().toString();
147 }
148 if (DEFAULT_ANNOTATION_VALUE.equals(fieldName)
149 && (ev.getValue() != null && ev.getValue().getValue() != null)) {
150 output.targetField = ev.getValue().getValue().toString();
151 }
152 }
153 }
154 }
155 return output;
156 }
157
158
159
160
161
162
163 private static boolean aliasMatch(AliasData aliasData, String targetType, String targetField, String currentAnnotation) {
164 if (aliasData == null) {
165 return false;
166 }
167 return (
168 (targetType.equals(aliasData.targetAnnotation)
169 || (aliasData.targetAnnotation == null && targetType.equals(currentAnnotation)))
170 &&
171 targetField.equals(aliasData.targetField));
172 }
173
174 private static class AnnotationValueExtractorVisitor extends SimpleAnnotationValueVisitor8<Void, List<String>> {
175
176 @Override
177 protected Void defaultAction(Object o, List<String> values) {
178 values.add(o.toString());
179 return null;
180 }
181
182 public Void visitEnumConstant(VariableElement c, List<String> values) {
183 values.add(c.getSimpleName().toString());
184 return null;
185 }
186
187 public Void visitAnnotation(AnnotationMirror a, List<String> values) {
188
189 return defaultAction(a, values);
190 }
191
192 public Void visitArray(List<? extends AnnotationValue> vals, List<String> values) {
193 for (AnnotationValue val : vals) {
194 visit(val, values);
195 }
196 return null;
197 }
198 }
199 }