001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020: package com.sun.codemodel;
021:
022: import java.lang.annotation.Annotation;
023: import java.util.LinkedHashMap;
024: import java.util.Map;
025:
026: /**
027: * Represents an annotation on a program element.
028: *
029: * TODO
030: * How to add enums to the annotations
031: * @author
032: * Bhakti Mehta (bhakti.mehta@sun.com)
033: */
034: public final class JAnnotationUse extends JAnnotationValue {
035:
036: /**
037: * The {@link Annotation} class
038: */
039: private final JClass clazz;
040:
041: /**
042: * Map of member values.
043: */
044: private Map<String, JAnnotationValue> memberValues;
045:
046: JAnnotationUse(JClass clazz) {
047: this .clazz = clazz;
048: }
049:
050: private JCodeModel owner() {
051: return clazz.owner();
052: }
053:
054: private void addValue(String name, JAnnotationValue annotationValue) {
055: // Use ordered map to keep the code generation the same on any JVM.
056: // Lazily created.
057: if (memberValues == null)
058: memberValues = new LinkedHashMap<String, JAnnotationValue>();
059: memberValues.put(name, annotationValue);
060: }
061:
062: /**
063: * Adds a member value pair to this annotation
064: *
065: * @param name
066: * The simple name for this annotation
067: *
068: * @param value
069: * The boolean value for this annotation
070: * @return
071: * The JAnnotationUse. More member value pairs can
072: * be added to it using the same or the overloaded methods.
073: *
074: */
075: public JAnnotationUse param(String name, boolean value) {
076: addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
077: return this ;
078: }
079:
080: /**
081: * Adds a member value pair to this annotation
082: * @param name
083: * The simple name for this annotation
084: *
085: * @param value
086: * The int member value for this annotation
087: * @return
088: * The JAnnotationUse. More member value pairs can
089: * be added to it using the same or the overloaded methods.
090: *
091: */
092: public JAnnotationUse param(String name, int value) {
093: addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
094: return this ;
095: }
096:
097: /**
098: * Adds a member value pair to this annotation
099: * @param name
100: * The simple name for this annotation
101: *
102: * @param value
103: * The String member value for this annotation
104: * @return
105: * The JAnnotationUse. More member value pairs can
106: * be added to it using the same or the overloaded methods.
107: *
108: */
109: public JAnnotationUse param(String name, String value) {
110: //Escape string values with quotes so that they can
111: //be generated accordingly
112: addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
113: return this ;
114: }
115:
116: /**
117: * Adds a member value pair to this annotation
118: * For adding class values as param
119: * @see #param(String, Class)
120: * @param name
121: * The simple name for this annotation
122: *
123: * @param value
124: * The annotation class which is member value for this annotation
125: * @return
126: * The JAnnotationUse. More member value pairs can
127: * be added to it using the same or the overloaded methods.
128: *
129: */
130: public JAnnotationUse annotationParam(String name,
131: Class<? extends Annotation> value) {
132: JAnnotationUse annotationUse = new JAnnotationUse(owner().ref(
133: value));
134: addValue(name, annotationUse);
135: return annotationUse;
136: }
137:
138: /**
139: * Adds a member value pair to this annotation
140: * @param name
141: * The simple name for this annotation
142: *
143: * @param value
144: * The enum class which is member value for this annotation
145: * @return
146: * The JAnnotationUse. More member value pairs can
147: * be added to it using the same or the overloaded methods.
148: *
149: */
150: public JAnnotationUse param(String name, final Enum value) {
151: addValue(name, new JAnnotationValue() {
152: public void generate(JFormatter f) {
153: f.t(owner().ref(value.getDeclaringClass())).p('.').p(
154: value.name());
155: }
156: });
157: return this ;
158: }
159:
160: /**
161: * Adds a member value pair to this annotation
162: * @param name
163: * The simple name for this annotation
164: *
165: * @param value
166: * The JEnumConstant which is member value for this annotation
167: * @return
168: * The JAnnotationUse. More member value pairs can
169: * be added to it using the same or the overloaded methods.
170: *
171: */
172: public JAnnotationUse param(String name, JEnumConstant value) {
173: addValue(name, new JAnnotationStringValue(value));
174: return this ;
175: }
176:
177: /**
178: * Adds a member value pair to this annotation
179: * This can be used for e.g to specify
180: * <pre>
181: * @XmlCollectionItem(type=Integer.class);
182: * <pre>
183: * For adding a value of Class<? extends Annotation>
184: * @link
185: * #annotationParam(java.lang.String, java.lang.Class<? extends java.lang.annotation.Annotation>)
186: * @param name
187: * The simple name for this annotation param
188: *
189: * @param value
190: * The class type of the param
191: * @return
192: * The JAnnotationUse. More member value pairs can
193: * be added to it using the same or the overloaded methods.
194: *
195: *
196: *
197: */
198: public JAnnotationUse param(String name, Class value) {
199: return param(name, clazz.owner().ref(value));
200: }
201:
202: /**
203: * Adds a member value pair to this annotation based on the
204: * type represented by the given JType
205: *
206: * @param name The simple name for this annotation param
207: * @param type the JType representing the actual type
208: * @return The JAnnotationUse. More member value pairs can
209: * be added to it using the same or the overloaded methods.
210: */
211: public JAnnotationUse param(String name, JType type) {
212: JClass clazz = type.boxify();
213: addValue(name, new JAnnotationStringValue(clazz.dotclass()));
214: return this ;
215: }
216:
217: /**
218: * Adds a member value pair which is of type array to this annotation
219: * @param name
220: * The simple name for this annotation
221: *
222: * @return
223: * The JAnnotationArrayMember. For adding array values
224: * @see JAnnotationArrayMember
225: *
226: */
227: public JAnnotationArrayMember paramArray(String name) {
228: JAnnotationArrayMember arrayMember = new JAnnotationArrayMember(
229: owner());
230: addValue(name, arrayMember);
231: return arrayMember;
232: }
233:
234: // /**
235: // * This can be used to add annotations inside annotations
236: // * for e.g @XmlCollection(values= @XmlCollectionItem(type=Foo.class))
237: // * @param className
238: // * The classname of the annotation to be included
239: // * @return
240: // * The JAnnotationUse that can be used as a member within this JAnnotationUse
241: // * @deprecated
242: // * use {@link JAnnotationArrayMember#annotate}
243: // */
244: // public JAnnotationUse annotate(String className) {
245: // JAnnotationUse annotationUse = new JAnnotationUse(owner().ref(className));
246: // return annotationUse;
247: // }
248:
249: /**
250: * This can be used to add annotations inside annotations
251: * for e.g @XmlCollection(values= @XmlCollectionItem(type=Foo.class))
252: * @param clazz
253: * The annotation class to be included
254: * @return
255: * The JAnnotationUse that can be used as a member within this JAnnotationUse
256: * @deprecated
257: * use {@link JAnnotationArrayMember#annotate}
258: */
259: public JAnnotationUse annotate(Class<? extends Annotation> clazz) {
260: JAnnotationUse annotationUse = new JAnnotationUse(owner().ref(
261: clazz));
262: return annotationUse;
263: }
264:
265: public void generate(JFormatter f) {
266: f.p('@').g(clazz);
267: if (memberValues != null) {
268: f.p('(');
269: boolean first = true;
270:
271: if (isOptimizable()) {
272: // short form
273: f.g(memberValues.get("value"));
274: } else {
275: for (Map.Entry<String, JAnnotationValue> mapEntry : memberValues
276: .entrySet()) {
277: if (!first)
278: f.p(',');
279: f.p(mapEntry.getKey()).p('=')
280: .g(mapEntry.getValue());
281: first = false;
282: }
283: }
284: f.p(')');
285: }
286: }
287:
288: private boolean isOptimizable() {
289: return memberValues.size() == 1
290: && memberValues.containsKey("value");
291: }
292: }
|