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