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 }