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 }