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