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@codehaus.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.codehaus.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   * $Id$
44   */
45  
46  package org.codehaus.modello.plugin.java.javasource;
47  
48  
49  /*
50   * Copyright (c) 2004, Codehaus.org
51   *
52   * Permission is hereby granted, free of charge, to any person obtaining a copy of
53   * this software and associated documentation files (the "Software"), to deal in
54   * the Software without restriction, including without limitation the rights to
55   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
56   * of the Software, and to permit persons to whom the Software is furnished to do
57   * so, subject to the following conditions:
58   *
59   * The above copyright notice and this permission notice shall be included in all
60   * copies or substantial portions of the Software.
61   *
62   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
68   * SOFTWARE.
69   */
70  
71  import java.util.Vector;
72  
73  /**
74   * A class which holds information about the signature
75   * of a JMethod.
76   *
77   * The code in this package was modelled after the Java Reflection API
78   * as much as possible to reduce the learning curve.
79   *
80   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
81   **/
82  public final class JMethodSignature
83  {
84  
85      /**
86       * The set of modifiers for this JMethod
87       **/
88      private JModifiers modifiers = null;
89  
90      /**
91       * The return type of this Method
92       **/
93      private JType returnType = null;
94  
95      /**
96       * The name of this method
97       **/
98      private String name = null;
99  
100 
101     /**
102      * The list of parameters of this JMethodSignature in declared
103      * order
104      **/
105     private JNamedMap params = null;
106 
107     /**
108      * The JavaDoc comment for this method signature.
109      **/
110     private JDocComment jdc = null;
111 
112     /**
113      * The exceptions that this method throws
114      **/
115     private Vector<JClass> exceptions = null;
116 
117     /**
118      * Creates a new method with the given name and return type.
119      * For "void" return types, simply pass in null as the returnType
120      *
121      * @param name, the method name. Must not be null.
122      * @param returnType the return type of the method. May be null.
123      **/
124     public JMethodSignature( String name, JType returnType )
125     {
126 
127         if ( ( name == null ) || ( name.length() == 0 ) )
128         {
129             String err = "The method name must not be null or zero-length";
130             throw new IllegalArgumentException( err );
131         }
132 
133         this.jdc = new JDocComment();
134         this.returnType = returnType;
135         this.name = name;
136         this.modifiers = new JModifiers();
137         this.params = new JNamedMap( 3 );
138         this.exceptions = new Vector<JClass>( 1 );
139     } //-- JMethodSignature
140 
141     /**
142      * Adds the given Exception to this JMethodSignature's throws clause.
143      *
144      * @param exp the JClass representing the Exception
145      **/
146     public void addException( JClass exp )
147     {
148 
149         if ( exp == null ) return;
150 
151         //-- make sure exception is not already added
152         String expClassName = exp.getName();
153         for ( int i = 0; i < exceptions.size(); i++ )
154         {
155             JClass jClass = (JClass) exceptions.elementAt( i );
156             if ( expClassName.equals( jClass.getName() ) ) return;
157         }
158         //-- add exception
159         exceptions.addElement( exp );
160 
161         //-- create comment
162         jdc.addDescriptor( JDocDescriptor.createExceptionDesc( expClassName, null ) );
163     } //-- addException
164 
165     /**
166      * Adds the given parameter to this JMethodSignature's list of
167      * parameters.
168      *
169      * @param parameter the parameter to add to the this Methods
170      * list of parameters.
171      * @throws java.lang.IllegalArgumentException when a parameter already
172      * exists for this Method with the same name as the new
173      * parameter.
174      **/
175     public void addParameter( JParameter parameter )
176         throws IllegalArgumentException
177     {
178 
179         if ( parameter == null ) return;
180 
181         String pName = parameter.getName();
182         //-- check current params
183         if ( params.get( pName ) != null )
184         {
185             StringBuffer err = new StringBuffer();
186             err.append( "A parameter already exists for this method, " );
187             err.append( name );
188             err.append( ", with the name: " );
189             err.append( pName );
190             throw new IllegalArgumentException( err.toString() );
191         }
192 
193 
194         params.put( pName, parameter );
195 
196         //-- create comment
197         jdc.addDescriptor( JDocDescriptor.createParamDesc( pName, null ) );
198 
199     } //-- addParameter
200 
201     /**
202      * Returns the exceptions that this JMethodSignature lists
203      * in it's throws clause.
204      *
205      * @return the exceptions that this JMethodSignature lists
206      * in it's throws clause.
207      **/
208     public JClass[] getExceptions()
209     {
210 
211         JClass[] jclasses = new JClass[exceptions.size()];
212         exceptions.copyInto( jclasses );
213         return jclasses;
214     } //-- getExceptions
215 
216     /**
217      * Returns the JDocComment describing this JMethodSignature
218      *
219      * @return the JDocComment describing this JMethodSignature
220      **/
221     public JDocComment getJDocComment()
222     {
223         return this.jdc;
224     } //-- getJDocComment
225 
226     /**
227      * Returns the modifiers for this JMethodSignature.
228      *
229      * @return the modifiers for this JMethodSignature.
230      **/
231     public JModifiers getModifiers()
232     {
233         return this.modifiers;
234     } //-- getModifiers
235 
236     /**
237      * Returns the name of the method.
238      *
239      * @return the name of the method.
240      **/
241     public String getName()
242     {
243         return this.name;
244     } //-- getName
245 
246     /**
247      * Returns the JParameter at the given index.
248      *
249      * @param index the index of the JParameter to return.
250      * @return the JParameter at the given index.
251      **/
252     public JParameter getParameter( int index )
253     {
254         return (JParameter) params.get( index );
255     } //-- getParameter
256 
257     /**
258      * Returns the set of JParameters for this JMethodSignature
259      * <BR>
260      * <B>Note:</B> the array is a copy, the params in the array
261      * are the actual references.
262      * @return the set of JParameters for this JMethod
263      **/
264     public synchronized JParameter[] getParameters()
265     {
266         JParameter[] pArray = new JParameter[params.size()];
267         for ( int i = 0; i < pArray.length; i++ )
268         {
269             pArray[i] = (JParameter) params.get( i );
270         }
271         return pArray;
272     } //-- getParameters
273 
274     /**
275      * Returns the JType that represents the return type for the
276      * method signature.
277      *
278      * @return the JType that represents the return type for the
279      * method signature.
280      **/
281     public JType getReturnType()
282     {
283         return returnType;
284     } //-- getReturnType
285 
286 
287     /**
288      * Sets the comment describing this JMethodSignature.
289      *
290      * @param comment the comment for this member
291      * @see #getJDocComment
292      **/
293     public void setComment( String comment )
294     {
295         jdc.setComment( comment );
296     } //-- setComment
297 
298 
299     /**
300      * Sets the JModifiers for this method signature.
301      *
302      * @param modifiers the JModifiers for this method signature.
303      **/
304     public void setModifiers( JModifiers modifiers )
305     {
306         this.modifiers = modifiers.copy();
307         this.modifiers.setFinal( false );
308     } //-- setModifiers
309 
310     /**
311      * Prints the method signature. A semi-colon (end-of-statement
312      * terminator ';') will Not be printed.
313      *
314      * @param jsw the JSourceWriter to print to.
315      **/
316     public void print( JSourceWriter jsw )
317     {
318         print( jsw, true );
319     } //-- print
320 
321     /**
322      * Prints the method signature. A semi-colon (end-of-statement
323      * terminator ';') will Not be printed.
324      *
325      * @param jsw the JSourceWriter to print to.
326      * @param printJavaDoc a boolean that when true prints the JDocComment
327      * associated with this method signature.
328      **/
329     public void print( JSourceWriter jsw, boolean printJavaDoc )
330     {
331 
332         //------------/
333         //- Java Doc -/
334         //------------/
335 
336         if ( printJavaDoc ) jdc.print( jsw );
337 
338         //-----------------/
339         //- Method Source -/
340         //-----------------/
341 
342         jsw.write( modifiers.toString() );
343         if ( modifiers.toString().length() > 0 )
344         {
345             jsw.write( ' ' );
346         }
347         if ( returnType != null )
348         {
349             jsw.write( returnType );
350         }
351         else
352             jsw.write( "void" );
353         jsw.write( ' ' );
354         jsw.write( name );
355         jsw.write( '(' );
356 
357         //-- print parameters
358         if ( params.size() > 0 )
359         {
360             jsw.write( ' ' );
361             for ( int i = 0; i < params.size(); i++ )
362             {
363                 if ( i > 0 ) jsw.write( ", " );
364                 jsw.write( params.get( i ) );
365             }
366             jsw.write( ' ' );
367         }
368 
369         jsw.write( ')' );
370 
371         if ( exceptions.size() > 0 )
372         {
373             jsw.writeln();
374             jsw.write( "    throws " );
375             for ( int i = 0; i < exceptions.size(); i++ )
376             {
377                 if ( i > 0 ) jsw.write( ", " );
378                 JClass jClass = (JClass) exceptions.elementAt( i );
379                 jsw.write( jClass.getName() );
380             }
381         }
382     } //-- print
383 
384 
385     /**
386      * Returns the String representation of this JMethod,
387      * which is the method prototype.
388      * @return the String representation of this JMethod, which
389      * is simply the method prototype
390      **/
391     public String toString()
392     {
393 
394         StringBuffer sb = new StringBuffer();
395         if ( returnType != null )
396         {
397             sb.append( returnType );
398         }
399         else
400             sb.append( "void" );
401         sb.append( ' ' );
402         sb.append( name );
403         sb.append( '(' );
404 
405         //-- print parameters
406         if ( params.size() > 0 )
407         {
408             sb.append( ' ' );
409             for ( int i = 0; i < params.size(); i++ )
410             {
411                 JParameter jParam = (JParameter) params.get( i );
412                 if ( i > 0 ) sb.append( ", " );
413                 sb.append( jParam.getType().getName() );
414             }
415             sb.append( ' ' );
416         }
417 
418         sb.append( ')' );
419 
420         return sb.toString();
421     } //-- toString
422 
423     protected String[] getParameterClassNames()
424     {
425         Vector<String> names = new Vector<String>( params.size() );
426 
427         for ( int i = 0; i < params.size(); i++ )
428         {
429 
430             JType jType = ( (JParameter) params.get( i ) ).getType();
431             while ( jType.isArray() ) jType = jType.getComponentType();
432             if ( !jType.isPrimitive() )
433             {
434                 JClass jclass = (JClass) jType;
435                 names.addElement( jclass.getName() );
436             }
437         }
438 
439         String[] names_array = new String[names.size()];
440         names.copyInto( names_array );
441         return names_array;
442     } //-- getParameterClassNames
443 
444 } //-- JMethodSignature