View Javadoc
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 (C) Intalio, Inc. All Rights Reserved.
42   */
43  package org.exolab.javasource;
44  
45  import java.util.LinkedHashMap;
46  import java.util.Map;
47  import java.util.Vector;
48  
49  /**
50   * A class for handling source code for a constructor of a JClass.
51   *
52   * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a>
53   * @version $Revision$ $Date: 2005-05-08 05:24:54 -0600 (Sun, 08 May 2005) $
54   */
55  public final class JConstructor extends JAnnotatedElementHelper {
56  
57      /** The set of modifiers for this JConstructor. */
58      private JModifiers _modifiers;
59      
60      /** List of parameters for this JConstructor. */
61      private Map<String, JParameter> _params = new LinkedHashMap<String, JParameter>();
62      
63      /** The Class in this JConstructor has been declared. */
64      private AbstractJClass _declaringClass;
65      
66      /** The source code for this constructor. */
67      private JSourceCode _sourceCode;
68      
69      /** The exceptions that this JConstructor throws. */
70      private Vector<JClass> _exceptions;
71  
72      /**
73       * Creates a new JConstructor for the provided declaring class.
74       * 
75       * @param declaringClass The class this constructor creates.
76       */
77      protected JConstructor(final AbstractJClass declaringClass) {
78          _declaringClass = declaringClass;
79          _modifiers = new JModifiers();
80          _sourceCode = new JSourceCode();
81          _exceptions = new Vector<JClass>(1);
82      }
83  
84      /**
85       * Returns the exceptions that this JConstructor lists in its throws clause.
86       *
87       * @return The exceptions that this JConstructor lists in its throws clause.
88       */
89      public JClass[] getExceptions() {
90          JClass[] jclasses = new JClass[_exceptions.size()];
91          _exceptions.copyInto(jclasses);
92          return jclasses;
93      }
94  
95      /**
96       * Adds the given Exception to this JConstructor's throws clause.
97       *
98       * @param exp The JClass representing the Exception.
99       */
100     public void addException(final JClass exp) {
101         if (exp == null) { return; }
102 
103         //-- make sure exception is not already added
104         String expClassName = exp.getName();
105         for (int i = 0; i < _exceptions.size(); i++) {
106             JClass jClass = _exceptions.elementAt(i);
107             if (expClassName.equals(jClass.getName())) { return; }
108         }
109         //-- add exception
110         _exceptions.addElement(exp);
111     }
112 
113     /**
114      * Returns an array of JParameters consisting of the parameters of this
115      * JConstructor in declared order.
116      *
117      * @return A JParameter array consisting of the parameters of this
118      *         JConstructor in declared order.
119      */
120     public JParameter[] getParameters() {
121         return _params.values().toArray(new JParameter[_params.size()]);
122     }
123     
124     /**
125      * Returns the amount of parameters.
126      * @return The amount of parameters.
127      */
128     public int getParameterCount() {
129         return _params.size();
130     }
131 
132     /**
133      * Adds the given parameter to this JConstructor's list of parameters.
134      *
135      * @param parameter The parameter to add to the this JConstructor's list of
136      *        parameters.
137      */
138     public void addParameter(final JParameter parameter) {
139         if (parameter == null) { return; }
140 
141         //-- check current params
142         if (_params.get(parameter.getName()) != null) {
143             StringBuilder err = new StringBuilder(64);
144             err.append("A parameter already exists for the constructor, ");
145             err.append(this._declaringClass.getName());
146             err.append(", with the name: ");
147             err.append(parameter.getName());
148             throw new IllegalArgumentException(err.toString());
149         }
150 
151         _params.put(parameter.getName(), parameter);
152 
153         //-- be considerate and add the class name to the
154         //-- declaring class's list of imports
155         if (_declaringClass != null) {
156             JType jType = parameter.getType();
157             if (!jType.isPrimitive()) {
158                 _declaringClass.addImport(jType.getName());
159             }
160         }
161     }
162 
163     /**
164      * Returns the class in which this JConstructor has been declared.
165      *
166      * @return The class in which this JConstructor has been declared.
167      */
168     public AbstractJClass getDeclaringClass() {
169         return _declaringClass;
170     }
171 
172     /**
173      * Returns the modifiers for this JConstructor.
174      *
175      * @return The modifiers for this JConstructor.
176      */
177     public JModifiers getModifiers() {
178         return _modifiers;
179     }
180 
181     /**
182      * Sets the modifiers on this JConstructor.
183      *
184      * @param modifiers Modifiers to set on this constructor.
185      */
186     public void setModifiers(final JModifiers modifiers) {
187         _modifiers = modifiers.copy();
188         _modifiers.setFinal(false);
189     }
190 
191     /**
192      * Returns the source code for this JConstructor.
193      * 
194      * @return The source code.
195      */
196     public JSourceCode getSourceCode() {
197         return _sourceCode;
198     }
199 
200     /**
201      * Sets the source code for this constructor.
202      *
203      * @param sourceCode Source code to apply to this constructor.
204      */
205     public void setSourceCode(final String sourceCode) {
206         _sourceCode = new JSourceCode(sourceCode);
207     }
208 
209     /**
210      * Sets the source code for this constructor.
211      *
212      * @param sourceCode Source code to apply to this constructor.
213      */
214     public void setSourceCode(final JSourceCode sourceCode) {
215         _sourceCode = sourceCode;
216     }
217 
218     /**
219      * Prints this JConstructor to the provided JSourceWriter.
220      * 
221      * @param jsw The JSourceWriter to print the constructor to.
222      */
223     public void print(final JSourceWriter jsw) {
224         // -- print annotations
225         printAnnotations(jsw);
226 
227         if (_modifiers.isPrivate()) {
228             jsw.write("private");
229         } else if (_modifiers.isProtected()) {
230             jsw.write("protected");
231         } else {
232             jsw.write("public");
233         }
234         jsw.write(' ');
235         jsw.write(_declaringClass.getLocalName());
236         jsw.write('(');
237 
238         //-- any parameter annotations?
239         boolean parameterAnnotations = false;
240         for (JParameter jParameter : _params.values()) {
241             if (jParameter.hasAnnotations()) {
242                 parameterAnnotations = true;
243                 break;
244             }
245         }
246 
247         //-- print parameters
248         if (parameterAnnotations) {
249             jsw.indent();
250         }
251         int parameterCount = 0;
252         for (JParameter jParameter : _params.values()) {
253             if (parameterCount > 0) { 
254                 jsw.write(", ");
255             }
256             if (parameterAnnotations) { 
257                 jsw.writeln();
258             }
259             jParameter.printAnnotations(jsw);
260             String typeAndName = jParameter.toString();
261             jsw.write(typeAndName);
262             parameterCount++;
263         }
264         if (parameterAnnotations) { 
265             jsw.unindent(); 
266         }
267 
268         jsw.write(")");
269         if (_exceptions.size() > 0) {
270             jsw.writeln();
271             jsw.write("throws ");
272             for (int i = 0; i < _exceptions.size(); i++) {
273                 if (i > 0) { jsw.write(", "); }
274                 JClass jClass = _exceptions.elementAt(i);
275                 jsw.write(jClass.getName());
276             }
277         }
278         jsw.writeln(" {");
279 
280         _sourceCode.print(jsw);
281 
282         if (!jsw.isNewline()) { jsw.writeln(); }
283         jsw.writeln("}");
284     }
285 
286     /**
287      * {@inheritDoc}
288      */
289     public String toString() {
290         StringBuilder sb = new StringBuilder(32);
291         sb.append(_declaringClass.getName());
292         sb.append('(');
293 
294         //-- print parameters
295         for (int i = 0; i < _params.size(); i++) {
296             JParameter jp = _params.get(i);
297             if (i > 0) { sb.append(", "); }
298             sb.append(jp.getType().getName());
299         }
300         sb.append(')');
301         return sb.toString();
302     }
303 
304 }