001: /**
002: * Redistribution and use of this software and associated documentation
003: * ("Software"), with or without modification, are permitted provided
004: * that the following conditions are met:
005: *
006: * 1. Redistributions of source code must retain copyright
007: * statements and notices. Redistributions must also contain a
008: * copy of this document.
009: *
010: * 2. Redistributions in binary form must reproduce the
011: * above copyright notice, this list of conditions and the
012: * following disclaimer in the documentation and/or other
013: * materials provided with the distribution.
014: *
015: * 3. The name "Exolab" must not be used to endorse or promote
016: * products derived from this Software without prior written
017: * permission of Intalio, Inc. For written permission,
018: * please contact info@exolab.org.
019: *
020: * 4. Products derived from this Software may not be called "Exolab"
021: * nor may "Exolab" appear in their names without prior written
022: * permission of Intalio, Inc. Exolab is a registered
023: * trademark of Intalio, Inc.
024: *
025: * 5. Due credit should be given to the Exolab Project
026: * (http://www.exolab.org/).
027: *
028: * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
029: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
030: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
031: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
032: * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
033: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
035: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
036: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
037: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
038: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
039: * OF THE POSSIBILITY OF SUCH DAMAGE.
040: *
041: * Copyright 1999-2002 (C) Intalio, Inc. All Rights Reserved.
042: */package org.exolab.javasource;
043:
044: import java.util.Vector;
045:
046: /**
047: * A class which holds information about the signtaure of a JMethod. The code in
048: * this package was modelled after the Java Reflection API as much as possible
049: * to reduce the learning curve.
050: *
051: * @author <a href="mailto:keith At kvisco DOT com">Keith Visco</a>
052: * @version $Revision: 6677 $ $Date: 2004-12-03 11:57:33 -0700 (Fri, 03 Dec 2004) $
053: */
054: public final class JMethodSignature extends JAnnotatedElementHelper {
055: //--------------------------------------------------------------------------
056:
057: /** Default size of the map for method parameters. */
058: private static final int DEFAULT_PARAM_MAP_SIZE = 3;
059:
060: //--------------------------------------------------------------------------
061:
062: /** The set of modifiers for this JMethodSignature. */
063: private JModifiers _modifiers = null;
064:
065: /** The return type of this method. */
066: private JType _returnType = null;
067:
068: /** The name of this JMethodSignature. */
069: private String _name = null;
070:
071: /** The list of parameters of this method in order declared. */
072: private final JNamedMap _params;
073:
074: /** The JavaDoc comment for this method's signature. */
075: private final JDocComment _jdc;
076:
077: /** The exceptions that this method throws. */
078: private final Vector _exceptions;
079:
080: //--------------------------------------------------------------------------
081:
082: /**
083: * Creates a new method with the given name and "void" return type.
084: *
085: * @param name The method name. Must not be null.
086: */
087: public JMethodSignature(final String name) {
088: if ((name == null) || (name.length() == 0)) {
089: String err = "The method name must not be null or zero-length";
090: throw new IllegalArgumentException(err);
091: }
092:
093: _jdc = new JDocComment();
094: _returnType = null;
095: _name = name;
096: _modifiers = new JModifiers();
097: _params = new JNamedMap(DEFAULT_PARAM_MAP_SIZE);
098: _exceptions = new Vector(1);
099: }
100:
101: /**
102: * Creates a new method with the given name and return type.
103: *
104: * @param name The method name. Must not be null.
105: * @param returnType The return type of the method. Must not be null.
106: */
107: public JMethodSignature(final String name, final JType returnType) {
108: this (name);
109:
110: if (returnType == null) {
111: String err = "The return type must not be null or zero-length";
112: throw new IllegalArgumentException(err);
113: }
114: _returnType = returnType;
115: }
116:
117: //--------------------------------------------------------------------------
118:
119: /**
120: * Adds the given Exception to this JMethodSignature's throws clause.
121: *
122: * @param exp The JClass representing the Exception.
123: */
124: public void addException(final JClass exp) {
125: if (exp == null) {
126: return;
127: }
128:
129: //-- make sure exception is not already added
130: String expClassName = exp.getName();
131: for (int i = 0; i < _exceptions.size(); i++) {
132: JClass jClass = (JClass) _exceptions.elementAt(i);
133: if (expClassName.equals(jClass.getName())) {
134: return;
135: }
136: }
137: //-- add exception
138: _exceptions.addElement(exp);
139: }
140:
141: /**
142: * Adds the given parameter to this JMethodSignature's list of parameters.
143: *
144: * @param parameter The parameter to add to the this JMethodSignature's list
145: * of parameters.
146: */
147: public void addParameter(final JParameter parameter) {
148: if (parameter == null) {
149: return;
150: }
151:
152: String pName = parameter.getName();
153: //-- check current params
154: if (_params.get(pName) != null) {
155: StringBuffer err = new StringBuffer();
156: err.append("A parameter already exists for this method, ");
157: err.append(_name);
158: err.append(", with the name: ");
159: err.append(pName);
160: throw new IllegalArgumentException(err.toString());
161: }
162:
163: _params.put(pName, parameter);
164:
165: //-- create comment
166: _jdc.addDescriptor(JDocDescriptor.createParamDesc(pName, null));
167: }
168:
169: /**
170: * Returns the exceptions that this JMethodSignature lists in its throws
171: * clause.
172: *
173: * @return The exceptions that this JMethodSignature lists in its throws
174: * clause.
175: */
176: public JClass[] getExceptions() {
177: JClass[] jclasses = new JClass[_exceptions.size()];
178: _exceptions.copyInto(jclasses);
179: return jclasses;
180: }
181:
182: /**
183: * Returns the JavaDoc comment describing this JMethodSignature.
184: *
185: * @return The JavaDoc comment describing this JMethodSignature.
186: */
187: public JDocComment getJDocComment() {
188: return _jdc;
189: }
190:
191: /**
192: * Returns the modifiers for this JMethodSignature.
193: *
194: * @return The modifiers for this JMethodSignature.
195: */
196: public JModifiers getModifiers() {
197: return _modifiers;
198: }
199:
200: /**
201: * Returns the name of the method.
202: *
203: * @return The name of the method.
204: */
205: public String getName() {
206: return _name;
207: }
208:
209: /**
210: * Returns the JParameter at the given index.
211: *
212: * @param index The index of the JParameter to return.
213: * @return The JParameter at the given index.
214: */
215: public JParameter getParameter(final int index) {
216: return (JParameter) _params.get(index);
217: }
218:
219: /**
220: * Returns the set of JParameters in this JMethodSignature.
221: * <br/>
222: * <B>Note:</B> the array is a copy, the parameters in the array are the
223: * actual references.
224: *
225: * @return The set of JParameters in this JMethodSignature.
226: */
227: public synchronized JParameter[] getParameters() {
228: JParameter[] pArray = new JParameter[_params.size()];
229: for (int i = 0; i < pArray.length; i++) {
230: pArray[i] = (JParameter) _params.get(i);
231: }
232: return pArray;
233: }
234:
235: /**
236: * Returns the JType that represents the return type for the method
237: * signature.
238: *
239: * @return The JType that represents the return type for the method
240: * signature.
241: */
242: public JType getReturnType() {
243: return _returnType;
244: }
245:
246: /**
247: * Sets the name of the method.
248: *
249: * @param name The name of the method.
250: */
251: public void setName(final String name) {
252: _name = name;
253: }
254:
255: /**
256: * Sets the JavaDoc comment describing this JMethodSignature.
257: *
258: * @param comment The JavaDoc comment for this member.
259: */
260: public void setComment(final String comment) {
261: _jdc.setComment(comment);
262: }
263:
264: /**
265: * Sets the JModifiers for this method signature.
266: *
267: * @param modifiers The JModifiers for this method signature.
268: */
269: public void setModifiers(final JModifiers modifiers) {
270: _modifiers = modifiers.copy();
271: _modifiers.setFinal(false);
272: }
273:
274: //--------------------------------------------------------------------------
275:
276: /**
277: * Returns an array containing the names of the classes of the parameters in
278: * this JMethodSignature. For Arrays, the class name of the object type
279: * stored in the Array is what is returned. Parameters that are primitive
280: * types (and Arrays of primitive types) are not represented in the array of
281: * names returned.
282: *
283: * @return An array containing the names of the classes of the parameters in
284: * this JMethodSignature.
285: */
286: protected String[] getParameterClassNames() {
287: Vector names = new Vector(_params.size());
288:
289: for (int i = 0; i < _params.size(); i++) {
290:
291: JType jType = ((JParameter) _params.get(i)).getType();
292: while (jType.isArray()) {
293: jType = ((JArrayType) jType).getComponentType();
294: }
295: if (!jType.isPrimitive()) {
296: JClass jclass = (JClass) jType;
297: names.addElement(jclass.getName());
298: }
299: }
300:
301: String[] array = new String[names.size()];
302: names.copyInto(array);
303: return array;
304: }
305:
306: //--------------------------------------------------------------------------
307:
308: /**
309: * Prints the method signature. A semi-colon (end-of-statement terminator ';')
310: * will <em>not</em> be printed.
311: *
312: * @param jsw The JSourceWriter to print to.
313: */
314: public void print(final JSourceWriter jsw) {
315: print(jsw, true);
316: }
317:
318: /**
319: * Prints the method signature. A semi-colon (end-of-statement terminator ';')
320: * will <em>not</em> be printed.
321: *
322: * @param jsw The JSourceWriter to print to.
323: * @param printJavaDoc If true, print the JDocComment associated with this
324: * method signature before we print the method signature.
325: */
326: public void print(final JSourceWriter jsw,
327: final boolean printJavaDoc) {
328: //------------/
329: //- Java Doc -/
330: //------------/
331:
332: if (printJavaDoc) {
333: _jdc.print(jsw);
334: }
335:
336: //---------------/
337: //- Annotations -/
338: //---------------/
339:
340: printAnnotations(jsw);
341:
342: //-----------------/
343: //- Method Source -/
344: //-----------------/
345:
346: jsw.write(_modifiers.toString());
347: if (_modifiers.toString().length() > 0) {
348: jsw.write(' ');
349: }
350: if (_returnType != null) {
351: jsw.write(_returnType);
352: } else {
353: jsw.write("void");
354: }
355: jsw.write(' ');
356: jsw.write(_name);
357: jsw.writeln('(');
358:
359: //-- print parameters
360: jsw.indent();
361: jsw.indent();
362: for (int i = 0; i < _params.size(); i++) {
363: if (i > 0) {
364: jsw.writeln(",");
365: }
366: JParameter jParameter = (JParameter) _params.get(i);
367: jParameter.printAnnotations(jsw);
368: String typeAndName = jParameter.toString();
369: jsw.write(typeAndName);
370: }
371: jsw.unindent();
372: jsw.unindent();
373:
374: jsw.write(")");
375:
376: if (_exceptions.size() > 0) {
377: jsw.writeln();
378: jsw.write("throws ");
379: for (int i = 0; i < _exceptions.size(); i++) {
380: if (i > 0) {
381: jsw.write(", ");
382: }
383: JClass jClass = (JClass) _exceptions.elementAt(i);
384: jsw.write(jClass.getName());
385: }
386: }
387: }
388:
389: /**
390: * {@inheritDoc}
391: */
392: public String toString() {
393: StringBuffer sb = new StringBuffer();
394: if (_returnType != null) {
395: sb.append(_returnType);
396: } else {
397: sb.append("void");
398: }
399: sb.append(' ');
400: sb.append(_name);
401: sb.append('(');
402:
403: //-- print parameters
404: for (int i = 0; i < _params.size(); i++) {
405: JParameter jParam = (JParameter) _params.get(i);
406: if (i > 0) {
407: sb.append(", ");
408: }
409: sb.append(jParam.getType().getName());
410: }
411: sb.append(") ");
412:
413: return sb.toString();
414: }
415:
416: //--------------------------------------------------------------------------
417: }
|