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.Vector;
46
47 /**
48 * A class which holds information about the methods of a JClass. Modelled
49 * closely after the Java Reflection API. This class is part of package which
50 * is used to create source code.
51 *
52 * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a>
53 * @version $Revision$ $Date: 2004-12-03 11:57:33 -0700 (Fri, 03 Dec 2004) $
54 */
55 public final class JMethod implements JMember, JAnnotatedElement {
56 //--------------------------------------------------------------------------
57
58 /** The set of classes that contain this JMethod. */
59 private final Vector _classes;
60
61 /** The JavaDoc comment for this JMethod. This will overwrite the JavaDoc for
62 * the JMethodSignature. */
63 private JDocComment _jdc = null;
64
65 /** The source code for this method. */
66 private JSourceCode _source = null;
67
68 /** The signature for this method. */
69 private JMethodSignature _signature = null;
70
71 //--------------------------------------------------------------------------
72
73 /**
74 * Creates a new JMethod with the given name and "void" return type.
75 *
76 * @param name The method name. Must not be null.
77 */
78 public JMethod(final String name) {
79 if (name == null || name.length() == 0) {
80 String err = "The method name must not be null or zero-length";
81 throw new IllegalArgumentException(err);
82 }
83 _classes = new Vector(1);
84 _source = new JSourceCode();
85 _signature = new JMethodSignature(name);
86 _jdc = _signature.getJDocComment();
87 }
88
89 /**
90 * Creates a new JMethod with the given name and returnType. The return type
91 * must not be empty or null. For "void" return types, use
92 * {@link #JMethod(String)} instead of this constructor.
93 *
94 *
95 * @param name The method name. Must not be null.
96 * @param returnType The return type of the method. Must not be null.
97 * @param returnDoc Javadoc comment for the @return annotation. If
98 * null, a default (and mostly useless) javadoc comment will be
99 * generated.
100 */
101 public JMethod(final String name, final JType returnType, final String returnDoc) {
102 this(name);
103
104 _signature = new JMethodSignature(name, returnType);
105 _jdc = _signature.getJDocComment();
106 _jdc.appendComment("Method " + name + ".");
107 if (returnDoc != null && returnDoc.length() > 0) {
108 _jdc.addDescriptor(JDocDescriptor.createReturnDesc(returnDoc));
109 } else {
110 _jdc.addDescriptor(JDocDescriptor.createReturnDesc(returnType.getLocalName()));
111 }
112 }
113
114 //--------------------------------------------------------------------------
115
116 /**
117 * Adds the given Exception to this JMethod's throws clause.
118 *
119 * @param exp The JClass representing the Exception.
120 * @param description JavaDoc comment explaining when this exception is thrown.
121 */
122 public void addException(final JClass exp, final String description) {
123 _signature.addException(exp);
124 _jdc.addDescriptor(JDocDescriptor.createExceptionDesc(exp.getName(), description));
125 }
126
127 /**
128 * Adds the given parameter to this JMethod's list of parameters.
129 *
130 * @param parameter The parameter to add to the this JMethod's list of
131 * parameters.
132 */
133 public void addParameter(final JParameter parameter) {
134 _signature.addParameter(parameter);
135
136 //-- be considerate and add the class name to the
137 //-- each declaring class' list of imports
138 JType jType = parameter.getType();
139 while (jType.isArray() || jType instanceof JCollectionType) {
140 if (jType.isArray()) {
141 jType = ((JArrayType) jType).getComponentType();
142 } else {
143 jType = ((JCollectionType) jType).getComponentType();
144 }
145 }
146 if (!jType.isPrimitive()) {
147 JClass jClass = (JClass) jType;
148 for (int i = 0; i < _classes.size(); i++) {
149 ((JClass) _classes.elementAt(i)).addImport(jClass.getName());
150 }
151 }
152 }
153
154 /**
155 * Returns the JavaDoc comment describing this JMethod.
156 *
157 * @return The JavaDoc comment describing this JMethod.
158 */
159 public JDocComment getJDocComment() {
160 return _jdc;
161 }
162
163 /**
164 * Returns the exceptions that this JMethod throws.
165 *
166 * @return The exceptions that this JMethod throws.
167 */
168 public JClass[] getExceptions() {
169 return _signature.getExceptions();
170 }
171
172 /**
173 * Returns the amount of exceptions thrown.
174 *
175 * @return The amount of exceptions thrown.
176 */
177 public int getExceptionCount() {
178 return _signature.getExceptions().length;
179 }
180
181 /**
182 * Returns the modifiers for this JMethod.
183 *
184 * @return The modifiers for this JMethod.
185 */
186 public JModifiers getModifiers() {
187 return _signature.getModifiers();
188 }
189
190 /**
191 * Returns the name of this JMethod.
192 *
193 * @return The name of this JMethod.
194 */
195 public String getName() {
196 return _signature.getName();
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 _signature.getParameter(index);
207 }
208
209 /**
210 * Returns the set of JParameters for this JMethod.
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 for this JMethod.
216 */
217 public JParameter[] getParameters() {
218 return _signature.getParameters();
219 }
220
221 /**
222 * Returns the amount of parameters.
223 *
224 * @return The amount of parameters.
225 */
226 public int getParameterCount() {
227 return _signature.getParameters().length;
228 }
229
230 /**
231 * Returns the JType that represents the return type of the JMethod.
232 *
233 * @return The JType that represents the return type of the JMethod.
234 */
235 public JType getReturnType() {
236 return _signature.getReturnType();
237 }
238
239 /**
240 * Returns the JMethodSignature for this JMethod.
241 *
242 * @return The JMethodSignature for this JMethod.
243 */
244 public JMethodSignature getSignature() {
245 return _signature;
246 }
247
248 /**
249 * Returns the JSourceCode for the method body.
250 *
251 * @return The JSourceCode for the method body.
252 */
253 public JSourceCode getSourceCode() {
254 return this._source;
255 }
256
257 /**
258 * Sets the name of this JMethod.
259 *
260 * @param name The name of this method.
261 */
262 public void setName(final String name) {
263 _signature.setName(name);
264 }
265
266 /**
267 * Sets the comment describing this JMethod. The comment will be printed
268 * when this JMethod is printed.
269 *
270 * @param comment The comment for this member.
271 */
272 public void setComment(final String comment) {
273 _jdc.setComment(comment);
274 }
275
276 /**
277 * Sets the JModifiers for this JMethod. This JMethod will use only a copy
278 * of the JModifiers.
279 * <br/>
280 * <B>Note:</B> The JModifiers will be set in the containing
281 * JMethodSignature. If the JMethodSignature is used by other methods, keep
282 * in mind that it will be changed.
283 *
284 * @param modifiers The JModifiers to set.
285 */
286 public void setModifiers(final JModifiers modifiers) {
287 _signature.setModifiers(modifiers);
288 }
289
290 /**
291 * Sets the given string as the source code (method body) for this JMethod.
292 *
293 * @param source The String that represents the method body.
294 */
295 public void setSourceCode(final String source) {
296 _source = new JSourceCode(source);
297 }
298
299 /**
300 * Sets the given JSourceCode as the source code (method body) for this
301 * JMethod.
302 *
303 * @param source The JSourceCode that represents the method body.
304 */
305 public void setSourceCode(final JSourceCode source) {
306 _source = source;
307 }
308
309 /**
310 * {@inheritDoc}
311 */
312 public String toString() {
313 return _signature.toString();
314 }
315
316 /**
317 * {@inheritDoc}
318 */
319 public JAnnotation getAnnotation(final JAnnotationType annotationType) {
320 return _signature.getAnnotation(annotationType);
321 }
322
323 /**
324 * {@inheritDoc}
325 */
326 public JAnnotation[] getAnnotations() {
327 return _signature.getAnnotations();
328 }
329
330 /**
331 * {@inheritDoc}
332 */
333 public boolean isAnnotationPresent(final JAnnotationType annotationType) {
334 return _signature.isAnnotationPresent(annotationType);
335 }
336
337 /**
338 * {@inheritDoc}
339 */
340 public void addAnnotation(final JAnnotation annotation) {
341 _signature.addAnnotation(annotation);
342 }
343
344 /**
345 * {@inheritDoc}
346 */
347 public JAnnotation removeAnnotation(final JAnnotationType annotationType) {
348 return _signature.removeAnnotation(annotationType);
349 }
350
351 /**
352 * {@inheritDoc}
353 */
354 public boolean hasAnnotations() {
355 return _signature.hasAnnotations();
356 }
357
358 //--------------------------------------------------------------------------
359
360 /**
361 * Prints this JMethod to the given JSourceWriter.
362 *
363 * @param jsw The JSourceWriter to print to.
364 */
365 public void print(final JSourceWriter jsw) {
366 //------------/
367 //- Java Doc -/
368 //------------/
369
370 _jdc.print(jsw);
371
372 //--------------------/
373 //- Method Signature -/
374 //--------------------/
375
376 _signature.print(jsw, false);
377
378 if (_signature.getModifiers().isAbstract()) {
379 jsw.writeln(";");
380 } else {
381 jsw.writeln(" {");
382 _source.print(jsw);
383 jsw.writeln("}");
384 }
385 }
386
387 //--------------------------------------------------------------------------
388 }