1/*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.codemodel.internal;
27
28
29import java.lang.annotation.Annotation;
30import java.util.ArrayList;
31import java.util.List;
32import java.util.Collection;
33import java.util.Collections;
34
35/**
36 * Represents an arrays as annotation members
37 *
38 * <p>
39 * This class implements {@link JAnnotatable} to allow
40 * new annotations to be added as a member of the array.
41 *
42 * @author
43 *     Bhakti Mehta (bhakti.mehta@sun.com)
44 */
45public final class JAnnotationArrayMember extends JAnnotationValue implements JAnnotatable {
46    private final List<JAnnotationValue> values = new ArrayList<JAnnotationValue>();
47    private final JCodeModel owner;
48
49    JAnnotationArrayMember(JCodeModel owner) {
50        this.owner = owner;
51    }
52
53    /**
54     * Adds an array member to this annotation
55     *
56     * @param value Adds a string value to the array member
57     * @return The JAnnotationArrayMember. More elements can be added by calling
58     *         the same method multiple times
59     */
60    public JAnnotationArrayMember param(String value) {
61        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
62        values.add(annotationValue);
63        return this;
64    }
65
66    /**
67     * Adds an array member to this annotation
68     *
69     * @param value Adds a boolean value to the array member
70     * @return The JAnnotationArrayMember. More elements can be added by calling
71     *         the same method multiple times
72     */
73    public JAnnotationArrayMember param(boolean value) {
74        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
75        values.add(annotationValue);
76        return this;
77    }
78
79    /**
80     * Adds an array member to this annotation
81     *
82     * @param value Adds a byte value to the array member
83     * @return The JAnnotationArrayMember. More elements can be added by calling
84     *         the same method multiple times
85     */
86    public JAnnotationArrayMember param(byte value) {
87        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
88        values.add(annotationValue);
89        return this;
90    }
91
92    /**
93     * Adds an array member to this annotation
94     *
95     * @param value Adds a char value to the array member
96     * @return The JAnnotationArrayMember. More elements can be added by calling
97     *         the same method multiple times
98     */
99    public JAnnotationArrayMember param(char value) {
100        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
101        values.add(annotationValue);
102        return this;
103    }
104
105    /**
106     * Adds an array member to this annotation
107     *
108     * @param value Adds a double value to the array member
109     * @return The JAnnotationArrayMember. More elements can be added by calling
110     *         the same method multiple times
111     */
112    public JAnnotationArrayMember param(double value) {
113        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
114        values.add(annotationValue);
115        return this;
116    }
117
118    /**
119     * Adds an array member to this annotation
120     *
121     * @param value Adds a long value to the array member
122     * @return The JAnnotationArrayMember. More elements can be added by calling
123     *         the same method multiple times
124     */
125    public JAnnotationArrayMember param(long value) {
126        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
127        values.add(annotationValue);
128        return this;
129    }
130
131    /**
132     * Adds an array member to this annotation
133     *
134     * @param value Adds a short value to the array member
135     * @return The JAnnotationArrayMember. More elements can be added by calling
136     *         the same method multiple times
137     */
138    public JAnnotationArrayMember param(short value) {
139        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
140        values.add(annotationValue);
141        return this;
142    }
143
144    /**
145     * Adds an array member to this annotation
146     *
147     * @param value Adds an int value to the array member
148     * @return The JAnnotationArrayMember. More elements can be added by calling
149     *         the same method multiple times
150     */
151    public JAnnotationArrayMember param(int value) {
152        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
153        values.add(annotationValue);
154        return this;
155    }
156
157    /**
158     * Adds an array member to this annotation
159     *
160     * @param value Adds a float value to the array member
161     * @return The JAnnotationArrayMember. More elements can be added by calling
162     *         the same method multiple times
163     */
164    public JAnnotationArrayMember param(float value) {
165        JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
166        values.add(annotationValue);
167        return this;
168    }
169
170    /**
171     * Adds a enum array member to this annotation
172     *
173     * @param value Adds a enum value to the array member
174     * @return The JAnnotationArrayMember. More elements can be added by calling
175     *         the same method multiple times
176     */
177    public JAnnotationArrayMember param(final Enum<?> value) {
178        JAnnotationValue annotationValue = new JAnnotationValue() {
179            public void generate(JFormatter f) {
180                f.t(owner.ref(value.getDeclaringClass())).p('.').p(value.name());
181            }
182        };
183        values.add(annotationValue);
184        return this;
185    }
186
187    /**
188     * Adds a enum array member to this annotation
189     *
190     * @param value Adds a enum value to the array member
191     * @return The JAnnotationArrayMember. More elements can be added by calling
192     *         the same method multiple times
193     */
194    public JAnnotationArrayMember param(final JEnumConstant value) {
195        JAnnotationValue annotationValue = new JAnnotationStringValue(value);
196        values.add(annotationValue);
197        return this;
198    }
199
200    /**
201     * Adds an expression array member to this annotation
202     *
203     * @param value Adds an expression value to the array member
204     * @return The JAnnotationArrayMember. More elements can be added by calling
205     *         the same method multiple times
206     */
207    public JAnnotationArrayMember param(final JExpression value) {
208        JAnnotationValue annotationValue = new JAnnotationStringValue(value);
209        values.add(annotationValue);
210        return this;
211    }
212
213    /**
214     * Adds a class array member to this annotation
215     *
216     * @param value Adds a class value to the array member
217     * @return The JAnnotationArrayMember. More elements can be added by calling
218     *         the same method multiple times
219     */
220    public JAnnotationArrayMember param(final Class<?> value){
221       JAnnotationValue annotationValue = new JAnnotationStringValue(
222                   new JExpressionImpl() {
223                         public void generate(JFormatter f) {
224                                 f.p(value.getName().replace('$', '.'));
225                                 f.p(".class");
226                        }
227                 });
228       values.add(annotationValue);
229       return this;
230   }
231
232    public JAnnotationArrayMember param(JType type){
233        JClass clazz = type.boxify();
234        JAnnotationValue annotationValue = new JAnnotationStringValue ( clazz.dotclass() );
235        values.add(annotationValue);
236        return this;
237    }
238
239    /**
240     * Adds a new annotation to the array.
241     */
242    public JAnnotationUse annotate(Class<? extends Annotation> clazz){
243        return annotate(owner.ref(clazz));
244    }
245
246    /**
247     * Adds a new annotation to the array.
248     */
249    public JAnnotationUse annotate(JClass clazz){
250        JAnnotationUse a = new JAnnotationUse(clazz);
251        values.add(a);
252        return a;
253    }
254
255
256    public boolean removeAnnotation(JAnnotationUse annotation) {
257        return this.values.remove(annotation);
258    }
259
260    public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
261        return TypedAnnotationWriter.create(clazz,this);
262    }
263
264    /**
265     * {@link JAnnotatable#annotations()}
266     */
267    @SuppressWarnings("unchecked")
268        public Collection<JAnnotationUse> annotations() {
269        // this invocation is invalid if the caller isn't adding annotations into an array
270        // so this potentially type-unsafe conversion would be justified.
271        return Collections.<JAnnotationUse>unmodifiableList((List)values);
272    }
273
274    /**
275     * Adds an annotation member to this annotation  array
276     * This can be used for e.g &#64;XmlCollection(values= &#64;XmlCollectionItem(type=Foo.class))
277     * @param value
278     *        Adds a annotation  to the array member
279     * @return
280     *        The JAnnotationArrayMember. More elements can be added by calling
281     *        the same method multiple times
282     *
283     * @deprecated
284     *      use {@link #annotate}
285     */
286    public JAnnotationArrayMember param (JAnnotationUse value ){
287        values.add(value);
288        return this;
289    }
290
291    public void generate(JFormatter f) {
292        f.p('{').nl().i();
293
294        boolean first = true;
295        for (JAnnotationValue aValue : values) {
296            if (!first)
297                f.p(',').nl();
298            f.g(aValue);
299            first = false;
300        }
301        f.nl().o().p('}');
302    }
303}
304