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 }