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