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 }