1 package net.sourceforge.jenesis4java.impl;
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
28
29
30
31
32
33
34
35
36
37
38
39
40 import net.sourceforge.jenesis4java.*;
41 import net.sourceforge.jenesis4java.impl.MVM.MCodeable;
42 import net.sourceforge.jenesis4java.impl.util.ListTypeSelector;
43 import net.sourceforge.jenesis4java.impl.util.VisitorUtils;
44
45 import java.util.ArrayList;
46 import java.util.Iterator;
47 import java.util.List;
48
49 class MAnnotation extends MCodeable implements Annotation {
50
51 static class MAnnotationAttribute extends MCodeable implements AnnotationAttribute {
52
53 private String name;
54
55 private final List<Expression> values = new ArrayList<>(2);
56
57 private boolean isArray;
58
59 private Annotation[] valueAnnotations;
60
61 MAnnotationAttribute(MVM vm) {
62 super(vm);
63 }
64
65 @Override
66 public MAnnotationAttribute addValue(Expression value) {
67 values.add(value);
68 return this;
69 }
70
71 @Override
72 public AnnotationAttribute addValues(Iterable<Expression> values) {
73 for (Expression value : values) {
74 addValue(value);
75 }
76
77 return null;
78 }
79
80 @Override
81 public MAnnotationAttribute addValueAnnotation(Annotation valueAnnotation) {
82 Annotation[] oldValue = valueAnnotations;
83 if (oldValue == null) {
84 oldValue = new Annotation[0];
85 }
86 valueAnnotations = new Annotation[oldValue.length + 1];
87 System.arraycopy(oldValue, 0, valueAnnotations, 0, oldValue.length);
88 valueAnnotations[oldValue.length] = valueAnnotation;
89 return this;
90 }
91
92 @Override
93 public List<Expression> getValuesCopy() {
94 return new ArrayList<>(values);
95 }
96
97 @Override
98 public String getName() {
99 return name;
100 }
101
102 @Override
103 public Expression getValue() {
104 if (!values.isEmpty()) {
105 return values.get(0);
106 } else {
107 return null;
108 }
109 }
110
111 @Override
112 public boolean isDefaultValueAttribute() {
113 return name.isEmpty();
114 }
115
116 @Override
117 public Annotation getValueAnnotation() {
118 if (valueAnnotations != null && valueAnnotations.length > 0) {
119 return valueAnnotations[0];
120 } else {
121 return null;
122 }
123 }
124
125 @Override
126 public Annotation[] getValueAnnotations() {
127 return valueAnnotations;
128 }
129
130 @Override
131 public boolean isArray() {
132 return isArray || values != null && values.size() > 1 || valueAnnotations != null && valueAnnotations.length > 1;
133 }
134
135 @Override
136 @Deprecated
137 public MAnnotationAttribute setArray(boolean isArray) {
138 this.isArray = isArray;
139 return this;
140 }
141
142 private static String nullToEmpty(String string) {
143 if (string == null) {
144 return "";
145 } else {
146 return string;
147 }
148 }
149
150 @Override
151 public MAnnotationAttribute setName(String name) {
152 this.name = nullToEmpty(name);
153 return this;
154 }
155
156 @Override
157 public MAnnotationAttribute setValue(Expression value) {
158 values.clear();
159 values.add(value);
160 return this;
161 }
162
163 @Override
164 public MAnnotationAttribute setValueAnnotation(Annotation valueAnnotation) {
165 valueAnnotations = new Annotation[]{
166 valueAnnotation
167 };
168 return this;
169 }
170
171 @Override
172 public MAnnotationAttribute setValueAnnotations(Annotation[] valueAnnotations) {
173 this.valueAnnotations = valueAnnotations;
174 return this;
175 }
176
177 @Override
178 public CodeWriter toCode(CodeWriter out) {
179 if (!isArray() && valueAnnotations != null && valueAnnotations.length == 1) {
180 out.indentLine();
181 }
182 if (name != null && !name.trim().isEmpty()) {
183 out.write(name);
184 out.write(" = ");
185 }
186 if (isArray()) {
187 out.write('{');
188 out.indentLine();
189 }
190 if (!values.isEmpty()) {
191 for (int index = 0; index < values.size(); index++) {
192 if (index > 0) {
193 out.write(", ");
194 }
195 out.write(values.get(index));
196 }
197 } else if (valueAnnotations != null) {
198 for (int index = 0; index < valueAnnotations.length; index++) {
199 if (index > 0) {
200 out.write(", ");
201 out.newLine();
202 }
203 out.write(valueAnnotations[index]);
204 }
205 }
206 if (isArray()) {
207 out.dedentLine();
208 out.write('}');
209 } else if (valueAnnotations != null && valueAnnotations.length == 1) {
210 out.dedentLine();
211 }
212 return out;
213 }
214
215 @Override
216 public void visit(ReplacingVisitor visitor) {
217 super.visit(visitor);
218 VisitorUtils.visit(values, this, visitor);
219 VisitorUtils.visit(valueAnnotations, this, visitor);
220 }
221 }
222
223 private String name;
224
225 private String text;
226
227 private List<AnnotationAttribute> annotationAttributes = new ArrayList<>();
228
229 MAnnotation(MVM vm, String text) {
230 super(vm);
231 checkArgument(!text.startsWith("@"), "name must not start with @");
232 this.text = text;
233 }
234
235 private static void checkArgument(boolean condition, String message) {
236 if (!condition) {
237 throw new IllegalArgumentException(message);
238 }
239 }
240
241 @Override
242 public MAnnotation addAnnotationAttribute(AnnotationAttribute annotation) {
243 annotationAttributes.add(annotation);
244 return this;
245 }
246
247 @Override
248 public AnnotationAttribute addAnnotationAttribute(String attributeName) {
249 MAnnotationAttribute attribute = new MAnnotationAttribute(vm);
250 attribute.setName(attributeName);
251 addAnnotationAttribute(attribute);
252 return attribute;
253 }
254
255 @Override
256 public AnnotationAttribute addAnnotationAttribute(String name, Expression value) {
257 AnnotationAttribute attribute = addAnnotationAttribute(name);
258 attribute.setValue(value);
259 return attribute;
260 }
261
262 @Override
263 public AnnotationAttribute getAnnotationAttribute(String name) {
264 for (Object element : annotationAttributes) {
265 AnnotationAttribute annotationAttribute = (AnnotationAttribute) element;
266 if (annotationAttribute.getName().equals(name)) {
267 return annotationAttribute;
268 }
269 }
270 return null;
271 }
272
273 @Override
274 public List<AnnotationAttribute> getAnnotationAttributes() {
275 return ListTypeSelector.select(annotationAttributes, AnnotationAttribute.class);
276 }
277
278 @Override
279 public String getEffectiveName() {
280 return name != null ? name : text;
281 }
282
283 @Override
284 @Deprecated
285 public String getName() {
286 return name;
287 }
288
289 @Override
290 @Deprecated
291 public String getText() {
292 return text;
293 }
294
295 @Override
296 @Deprecated
297 public MAnnotation setName(String name) {
298 this.name = name;
299 return this;
300 }
301
302 @Override
303 @Deprecated
304 public MAnnotation setText(String text) {
305 this.text = text;
306 return this;
307 }
308
309 @Override
310 public AnnotationAttribute addDefaultValueAttribute(Expression... values) {
311 MAnnotationAttribute defaultValueAttribute = new MAnnotationAttribute(vm);
312 defaultValueAttribute.setName("");
313 for (Expression value : values) {
314 defaultValueAttribute.addValue(value);
315 }
316 this.addAnnotationAttribute(defaultValueAttribute);
317 return defaultValueAttribute;
318 }
319
320 @Override
321 public CodeWriter toCode(CodeWriter out) {
322 super.toCode(out);
323
324 List<AnnotationAttribute> annotationAttributes = attributesWithValue(this.annotationAttributes);
325
326 if (annotationAttributes.isEmpty() && (name == null || "".equals(name))) {
327 out.write("@" + text);
328 } else if (annotationAttributes.isEmpty()) {
329 out.write("@" + name + "(" + text + ")");
330 } else {
331 out.write("@");
332 if (name != null && !name.trim().isEmpty()) {
333 out.write(name);
334 } else if (text != null && !text.trim().isEmpty()) {
335 out.write(text);
336 }
337 out.write("(");
338 for (Iterator<AnnotationAttribute> iterator = annotationAttributes.iterator(); iterator.hasNext();) {
339 out.write(iterator.next());
340 if (iterator.hasNext()) {
341 out.write(", ");
342 }
343 }
344 out.write(")");
345 }
346 return out;
347 }
348
349 private List<AnnotationAttribute> attributesWithValue(List<AnnotationAttribute> allAnnotationAttributes) {
350 List<AnnotationAttribute> attributesWithNonNullValue = new ArrayList<>(allAnnotationAttributes.size());
351 for (AnnotationAttribute attribute : allAnnotationAttributes) {
352 if (attribute.getValue() != null || attribute.getValueAnnotations() != null) {
353 attributesWithNonNullValue.add(attribute);
354 }
355 }
356 return attributesWithNonNullValue;
357 }
358
359 @Override
360 public void visit(ReplacingVisitor visitor) {
361 super.visit(visitor);
362 VisitorUtils.visit(annotationAttributes, this, visitor);
363 }
364 }