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-2002 (C) Intalio, Inc. All Rights Reserved.
42 */
43 package org.exolab.javasource;
44
45 import java.util.ArrayList;
46 import java.util.LinkedHashMap;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Vector;
50
51 /**
52 * A class which holds information about the signature of a JMethod. The code in
53 * this package was modeled after the Java Reflection API as much as possible
54 * to reduce the learning curve.
55 *
56 * @author <a href="mailto:keith At kvisco DOT com">Keith Visco</a>
57 * @version $Revision$ $Date: 2004-12-03 11:57:33 -0700 (Fri, 03 Dec 2004) $
58 */
59 public final class JMethodSignature extends JAnnotatedElementHelper {
60
61 /** The set of modifiers for this JMethodSignature. */
62 private JModifiers _modifiers = null;
63
64 /** The return type of this method. */
65 private JType _returnType = null;
66
67 /** The name of this JMethodSignature. */
68 private String _name = null;
69
70 /** The list of parameters of this method in order declared. */
71 private final Map<String, JParameter> _params = new LinkedHashMap<String, JParameter>();
72
73 /** The JavaDoc comment for this method's signature. */
74 private final JDocComment _jdc;
75
76 /** The exceptions that this method throws. */
77 private final Vector<JClass> _exceptions;
78
79 /**
80 * Creates a new method with the given name and "void" return type.
81 *
82 * @param name The method name. Must not be null.
83 */
84 public JMethodSignature(final String name) {
85 if ((name == null) || (name.length() == 0)) {
86 String err = "The method name must not be null or zero-length";
87 throw new IllegalArgumentException(err);
88 }
89
90 _jdc = new JDocComment();
91 _returnType = null;
92 _name = name;
93 _modifiers = new JModifiers();
94 _exceptions = new Vector<JClass>(1);
95 }
96
97 /**
98 * Creates a new method with the given name and return type.
99 *
100 * @param name The method name. Must not be null.
101 * @param returnType The return type of the method. Must not be null.
102 */
103 public JMethodSignature(final String name, final JType returnType) {
104 this(name);
105
106 if (returnType == null) {
107 String err = "The return type must not be null or zero-length";
108 throw new IllegalArgumentException(err);
109 }
110 _returnType = returnType;
111 }
112
113 /**
114 * Adds the given Exception to this JMethodSignature's throws clause.
115 *
116 * @param exp The JClass representing the Exception.
117 */
118 public void addException(final JClass exp) {
119 if (exp == null) { return; }
120
121 //-- make sure exception is not already added
122 String expClassName = exp.getName();
123 for (int i = 0; i < _exceptions.size(); i++) {
124 JClass jClass = _exceptions.elementAt(i);
125 if (expClassName.equals(jClass.getName())) { return; }
126 }
127 //-- add exception
128 _exceptions.addElement(exp);
129 }
130
131 /**
132 * Adds the given parameter to this JMethodSignature's list of parameters.
133 *
134 * @param parameter The parameter to add to the this JMethodSignature's list
135 * of parameters.
136 */
137 public void addParameter(final JParameter parameter) {
138 if (parameter == null) {
139 return;
140 }
141
142 String pName = parameter.getName();
143 //-- check current params
144 if (_params.get(pName) != null) {
145 StringBuilder err = new StringBuilder(32);
146 err.append("A parameter already exists for this method, ");
147 err.append(_name);
148 err.append(", with the name: ");
149 err.append(pName);
150 throw new IllegalArgumentException(err.toString());
151 }
152
153 _params.put(pName, parameter);
154
155 //-- create comment
156 _jdc.addDescriptor(JDocDescriptor.createParamDesc(pName, null));
157 }
158
159 /**
160 * Returns the exceptions that this JMethodSignature lists in its throws
161 * clause.
162 *
163 * @return The exceptions that this JMethodSignature lists in its throws
164 * clause.
165 */
166 public JClass[] getExceptions() {
167 JClass[] jclasses = new JClass[_exceptions.size()];
168 _exceptions.copyInto(jclasses);
169 return jclasses;
170 }
171
172 /**
173 * Returns the JavaDoc comment describing this JMethodSignature.
174 *
175 * @return The JavaDoc comment describing this JMethodSignature.
176 */
177 public JDocComment getJDocComment() {
178 return _jdc;
179 }
180
181 /**
182 * Returns the modifiers for this JMethodSignature.
183 *
184 * @return The modifiers for this JMethodSignature.
185 */
186 public JModifiers getModifiers() {
187 return _modifiers;
188 }
189
190 /**
191 * Returns the name of the method.
192 *
193 * @return The name of the method.
194 */
195 public String getName() {
196 return _name;
197 }
198
199 /**
200 * Returns the JParameter at the given index.
201 *
202 * @param index The index of the JParameter to return.
203 * @return The JParameter at the given index.
204 */
205 public JParameter getParameter(final int index) {
206 return _params.get(index);
207 }
208
209 /**
210 * Returns the set of JParameters in this JMethodSignature.
211 * <br/>
212 * <B>Note:</B> the array is a copy, the parameters in the array are the
213 * actual references.
214 *
215 * @return The set of JParameters in this JMethodSignature.
216 */
217 public synchronized JParameter[] getParameters() {
218 return _params.values().toArray(new JParameter[_params.size()]);
219 }
220
221 /**
222 * Returns the JType that represents the return type for the method
223 * signature.
224 *
225 * @return The JType that represents the return type for the method
226 * signature.
227 */
228 public JType getReturnType() {
229 return _returnType;
230 }
231
232 /**
233 * Sets the name of the method.
234 *
235 * @param name The name of the method.
236 */
237 public void setName(final String name) {
238 _name = name;
239 }
240
241 /**
242 * Sets the JavaDoc comment describing this JMethodSignature.
243 *
244 * @param comment The JavaDoc comment for this member.
245 */
246 public void setComment(final String comment) {
247 _jdc.setComment(comment);
248 }
249
250 /**
251 * Sets the JModifiers for this method signature.
252 *
253 * @param modifiers The JModifiers for this method signature.
254 */
255 public void setModifiers(final JModifiers modifiers) {
256 _modifiers = modifiers.copy();
257 _modifiers.setFinal(false);
258 }
259
260 /**
261 * Returns an array containing the names of the classes of the parameters in
262 * this JMethodSignature. For Arrays, the class name of the object type
263 * stored in the Array is what is returned. Parameters that are primitive
264 * types (and Arrays of primitive types) are not represented in the array of
265 * names returned.
266 *
267 * @return An array containing the names of the classes of the parameters in
268 * this JMethodSignature.
269 */
270 protected String[] getParameterClassNames() {
271 List<String> names = new ArrayList<String>(_params.size());
272
273 for (JParameter parameter : _params.values()) {
274 JType jType = parameter.getType();
275 while (jType.isArray()) {
276 jType = ((JArrayType) jType).getComponentType();
277 }
278 if (!jType.isPrimitive()) {
279 JClass jclass = (JClass) jType;
280 names.add(jclass.getName());
281 }
282 }
283
284 return names.toArray(new String[names.size()]);
285 }
286
287 /**
288 * Prints the method signature. A semi-colon (end-of-statement terminator ';')
289 * will <em>not</em> be printed.
290 *
291 * @param jsw The JSourceWriter to print to.
292 */
293 public void print(final JSourceWriter jsw) {
294 print(jsw, true);
295 }
296
297 /**
298 * Prints the method signature. A semi-colon (end-of-statement terminator ';')
299 * will <em>not</em> be printed.
300 *
301 * @param jsw The JSourceWriter to print to.
302 * @param printJavaDoc If true, print the JDocComment associated with this
303 * method signature before we print the method signature.
304 */
305 public void print(final JSourceWriter jsw, final boolean printJavaDoc) {
306 //------------/
307 //- Java Doc -/
308 //------------/
309
310 if (printJavaDoc) { _jdc.print(jsw); }
311
312 //---------------/
313 //- Annotations -/
314 //---------------/
315
316 printAnnotations(jsw);
317
318 //-----------------/
319 //- Method Source -/
320 //-----------------/
321
322 jsw.write(_modifiers.toString());
323 if (_modifiers.toString().length() > 0) {
324 jsw.write(' ');
325 }
326 if (_returnType != null) {
327 jsw.write(_returnType);
328 } else {
329 jsw.write("void");
330 }
331 jsw.write(' ');
332 jsw.write(_name);
333 jsw.write('(');
334
335 //-- print parameters
336 int parameterCount = 0;
337 for (JParameter jParameter : _params.values()) {
338 if (parameterCount > 0) {
339 jsw.write(",");
340 }
341 jParameter.printAnnotations(jsw);
342 String typeAndName = jParameter.toString();
343 jsw.write(typeAndName);
344 parameterCount++;
345 }
346
347 jsw.write(")");
348
349 if (_exceptions.size() > 0) {
350 jsw.write(" throws ");
351 for (int i = 0; i < _exceptions.size(); i++) {
352 if (i > 0) { jsw.write(", "); }
353 JClass jClass = _exceptions.elementAt(i);
354 jsw.write(jClass.getName());
355 }
356 }
357 }
358
359 /**
360 * {@inheritDoc}
361 */
362 public String toString() {
363 StringBuilder sb = new StringBuilder(32);
364 if (_returnType != null) {
365 sb.append(_returnType);
366 } else {
367 sb.append("void");
368 }
369 sb.append(' ');
370 sb.append(_name);
371 sb.append('(');
372
373 //-- print parameters
374 int i = 0;
375 for (JParameter jParam : _params.values()) {
376 if (i > 0) {
377 sb.append(", ");
378 }
379 sb.append(jParam.getType().getName());
380 }
381
382 sb.append(") ");
383
384 return sb.toString();
385 }
386
387 }