1 /**
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Intalio, Inc. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Intalio, Inc. Exolab is a registered
23 * trademark of Intalio, Inc.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 1999-2002 (C) Intalio, Inc. All Rights Reserved.
42 */
43 package org.exolab.javasource;
44
45 import java.util.LinkedHashMap;
46 import java.util.Map;
47
48 import org.exolab.castor.builder.SourceGenerator;
49
50 /**
51 * Describes the definition of a annotation type class.
52 *
53 * <pre>
54 * JAnnotationType type = new JAnnotationType("RequestForEnhancement");
55 * type.addElement(new JAnnotationTypeElement("id", JType.Int));
56 * type.addElement(new JAnnotationTypeElement("synopsis", new JType("String")));
57 * JAnnotationTypeElement engineer;
58 * engineer = new JAnnotationTypeElement("engineer", new JType("String"));
59 * engineer.setDefaultString("\"[unassigned]\"");
60 * type.addElement(engineer);
61 * JAnnotationTypeElement date;
62 * date = new JAnnotationTypeElement("date", new JType("String"));
63 * date.setDefaultString("\"[unimplemented]\"");
64 * type.addElement(date);
65 * </pre>
66 *
67 * outputs
68 *
69 * <pre>
70 * public @interface RequestForEnhancement {
71 * int id();
72 * String synopsis();
73 * String engineer() default "[unassigned]";
74 * String date() default "[unimplemented]";
75 * }
76 * </pre>
77 *
78 * @author <a href="mailto:andrew DOT fawcett AT coda DOT com">Andrew Fawcett</a>
79 * @version $Revision$ $Date: 2006-04-25 16:09:10 -0600 (Tue, 25 Apr 2006) $
80 */
81 public final class JAnnotationType extends JStructure {
82
83 /** The list of elements of this JAnnotationType. */
84 private Map<String, JAnnotationTypeElement> _elements =
85 new LinkedHashMap<String, JAnnotationTypeElement>();
86
87 /**
88 * Creates a JAnnotationType of the given name.
89 *
90 * @param name Annotation name.
91 */
92 public JAnnotationType(final String name) {
93 super(name);
94
95 //-- initialize default Java doc
96 getJDocComment().appendComment("Annotation " + getLocalName() + ".");
97 }
98
99 /**
100 * {@inheritDoc}
101 */
102 public void addImport(final String className) {
103 if (className == null || className.length() == 0) { return; }
104 addImportInternal(className);
105 }
106
107 /**
108 * Adds the given JMember to this JAnnotationType.
109 *
110 * @param jMember The JMember to add.
111 */
112 public void addMember(final JMember jMember) {
113 if (!(jMember instanceof JAnnotationTypeElement)) {
114 throw new IllegalArgumentException("Must be a JAnnotationTypeElement.");
115 }
116 addElement((JAnnotationTypeElement) jMember);
117 }
118
119 /**
120 * Returns an Array containing all our JAnnotationTypeElements.
121 *
122 * @return An Array containing all our JAnnotationTypeElements.
123 */
124 public JAnnotationTypeElement[] getElements() {
125 return _elements.values().toArray(new JAnnotationTypeElement[_elements.size()]);
126 }
127
128 /**
129 * Returns the member with the given name, or null if no member was found
130 * with the given name.
131 *
132 * @param name The name of the member to return.
133 * @return The member with the given name, or null if no member was found
134 * with the given name.
135 */
136 public JAnnotationTypeElement getElement(final String name) {
137 return _elements.get(name);
138 }
139
140 /**
141 * Adds the given JAnnotationTypeElement to this JAnnotationType.
142 *
143 * @param jElement The element to add.
144 */
145 public void addElement(final JAnnotationTypeElement jElement) {
146 if (jElement == null) {
147 throw new IllegalArgumentException("Class members cannot be null");
148 }
149
150 String name = jElement.getName();
151 if (_elements.get(name) != null) {
152 String err = "duplicate name found: " + name;
153 throw new IllegalArgumentException(err);
154 }
155 _elements.put(name, jElement);
156
157 // if member is of a type not imported by this class
158 // then add import
159 JType type = jElement.getType();
160 while (type.isArray()) {
161 type = ((JArrayType) type).getComponentType();
162 }
163 if (!type.isPrimitive()) {
164 addImport(type.getName());
165 }
166 }
167
168 /**
169 * Not implemented. Always throws a RuntimeException.
170 * <br/>
171 * {@inheritDoc}
172 */
173 public JField[] getFields() {
174 throw new RuntimeException("Not implemented.");
175 }
176
177 /**
178 * Not implemented. Always throws a RuntimeException.
179 * <br/>
180 * {@inheritDoc}
181 */
182 public JField getField(final String name) {
183 throw new RuntimeException("Not implemented.");
184 }
185
186 /**
187 * Not implemented. Always throws a RuntimeException.
188 * <br/>
189 * {@inheritDoc}
190 */
191 public void addField(final JField jField) {
192 throw new RuntimeException("Not implemented.");
193 }
194
195 /**
196 * {@inheritDoc}
197 *
198 * @deprecated Please use the Velocity-template based approach instead.
199 * @see SourceGenerator#setJClassPrinterType(String)
200 */
201 public void print(final JSourceWriter jsw) {
202 if (jsw == null) {
203 throw new IllegalArgumentException("argument 'jsw' should not be null.");
204 }
205
206 StringBuilder buffer = new StringBuilder(100);
207
208 printHeader(jsw);
209 printPackageDeclaration(jsw);
210 printImportDeclarations(jsw);
211
212 //------------/
213 //- Java Doc -/
214 //------------/
215
216 getJDocComment().print(jsw);
217
218 //-- print class information
219 //-- we need to add some JavaDoc API adding comments
220
221 buffer.setLength(0);
222 JModifiers modifiers = getModifiers();
223 if (modifiers.isPrivate()) {
224 buffer.append("private ");
225 } else if (modifiers.isPublic()) {
226 buffer.append("public ");
227 }
228 buffer.append("@interface ");
229 buffer.append(getLocalName());
230 buffer.append(' ');
231 buffer.append('{');
232 jsw.writeln(buffer.toString());
233
234 //-- declare members
235
236 buffer.setLength(0);
237 jsw.writeln();
238 jsw.indent();
239 for (JAnnotationTypeElement jElement :_elements.values()) {
240 jElement.print(jsw);
241 jsw.writeln();
242 }
243 jsw.unindent();
244
245 // -- close class
246
247 jsw.writeln('}');
248 jsw.flush();
249 }
250
251 }