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