View Javadoc
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 &#064;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 }