View Javadoc
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 }