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