001package Torello.JavaDoc; 002 003 004// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 005// Standard-Java Imports 006// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 007 008import java.io.IOException; 009import java.util.List; 010import java.util.function.Consumer; 011import java.util.Optional; 012 013 014// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 015// Java-HTML Imports 016// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 017 018import Torello.Java.*; 019 020import static Torello.JavaDoc.PF.*; 021import static Torello.Java.C.*; 022 023import Torello.Java.Additional.Ret4; 024import Torello.Java.Function.IntTFunction; 025import Torello.Java.ReadOnly.ROArrayListBuilder; 026import Torello.Java.ReadOnly.ReadOnlyArrayList; 027import Torello.Java.ReadOnly.ReadOnlyList; 028 029import Torello.JDUInternal.DataClasses.MainLoopData.AnnotationsMirror; 030import Torello.JDUInternal.DataClasses.MainLoopData.CallableSignature; 031 032 033// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 034// The new Source-Code Parser: com.sun.source.* 035// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 036 037import com.sun.source.tree.*; 038 039 040/** 041 * <B STYLE='color:darkred;'>Reflection Class:</B> 042 * 043 * Common-Root Ancestor Class of both {@link Method} and {@link Constructor}. 044 * 045 * <BR /><BR /> 046 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_CALLBL> 047 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_DIAGRAM> 048 */ 049@JDHeaderBackgroundImg 050public abstract class Callable extends Declaration implements java.io.Serializable 051{ 052 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 053 public static final long serialVersionUID = 1; 054 055 // COMPLETELY UN-USED RIGHT NOW, EXPERIMENTAL-ONLY 056 public final String autoFindID; 057 058 @Override 059 String codeHiLiteString() 060 { return (this.body == null) ? null : StrIndent.chompCallableBraces(this.body); } 061 062 063 // ******************************************************************************************** 064 // ******************************************************************************************** 065 // protected final String[] parameterNames; 066 // ******************************************************************************************** 067 // ******************************************************************************************** 068 069 070 /** 071 * The names of all parameters to this {@code Method} or {@code Constructor}. 072 * 073 * <BR /><BR /><B CLASS=JDDescLabel>Parallel List:</B> 074 * 075 * <BR />This list must be considered a parallel list to the other parameter-related list: 076 * {@link #parameterTypes}, {@link #parameterTypesJOW} and {@link #parameterAnnotations} 077 */ 078 public final ReadOnlyList<String> parameterNames; 079 080 /** 081 * This contains the types of the parameters, stored as {@code String's}. The contents of 082 * these {@code String's} do include: <I>package-name, containing classes (if 083 * inner-classes), and generic-parameter expressions (if generic-types).</I> These names are 084 * as fully-qualified as the AST Parser allows. 085 * 086 * <BR /><BR /><B CLASS=JDDescLabel>JOW Alternative:</B> 087 * 088 * <BR />The {@code ReadOnlyList} {@link #parameterTypesJOW} reduces these types (as 089 * {@code String's}) to a single-word. If a {@link Method} or a {@link Constructor} that 090 * accepts a paremeter such as {@code java.util.Iterable<Integer>}, and it seems 091 * <I>'difficult to work with'</I> - the entry in {@link #parameterTypesJOW} at the 092 * same array-location would contain, simply, the Java {@code String 'Iterable'}. 093 * 094 * <BR /><BR /><B CLASS=JDDescLabel>Parallel List:</B> 095 * 096 * <BR />This list must be considered a parallel list to the other parameter-related list: 097 * {@link #parameterNames}, {@link #parameterTypesJOW} and {@link #parameterAnnotations} 098 */ 099 public final ReadOnlyList<String> parameterTypes; 100 101 /** 102 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_JOW_TITLE> 103 * 104 * <BR /><BR /><B CLASS=JDDescLabel>Parallel List:</B> 105 * 106 * <BR />This list must be considered a parallel list to the other parameter-related list: 107 * {@link #parameterNames}, {@link #parameterTypes} and {@link #parameterAnnotations} 108 */ 109 public final ReadOnlyList<String> parameterTypesJOW; 110 111 /** 112 * Any parameters that are annotated will have the <I>exact text-{@code String} of the 113 * annotations that were used in the source-code for that parameter</I> stored in this 114 * two-dimensional {@code String[][]} array. 115 * 116 * <BR /><BR />This list will retrieve and contain the actual character data that may be found 117 * in the source-code file for an element in a {@code com.sun.source} 'AST' (Abstract Syntax 118 * Tree). The list of annotations on a parameter (if any) will each be saved as a 119 * {@code java.lang.String}. 120 * 121 * <BR /><BR /><B CLASS=JDDescLabel>Null Warning:</B> 122 * 123 * <BR />Unlike the other lists in class {@code Callable}, when there are no parameters for 124 * a {@code Callabe}, or when there are parameters, but none of them have been annotated, 125 * <I>for the purposes of efficiency and better memory management, this field will simply be 126 * assigned null</I>. 127 * 128 * <BR /><BR />In almost all cases (particularly in the Java HTML Library), this 129 * two-dimensional list, itself, really will be null - <I>since parameter annotations are 130 * quite uncommon</I>. Perhaps, some users make use of them from time to time. 131 * 132 * <BR /><BR /><B CLASS=JDDescLabel>Parallel List:</B> 133 * 134 * <BR />This list must be considered a parallel list to the other parameter-related list: 135 * {@link #parameterNames}, {@link #parameterTypes} and {@link #parameterTypesJOW} 136 */ 137 public final ReadOnlyList<ReadOnlyList<String>> parameterAnnotations; 138 139 /** 140 * The names of all {@code Exception, Error} and {@code Throwable} that may be thrown by this 141 * {@code Constructor} or {@code Method}. 142 * 143 * <BR /><BR /><B STYLE='color: red;'>NOTE:</B> Only exceptions which are included in the 144 * actual {@link Declaration#signature}, inside the original {@code '.java'} source-file for 145 * this {@code Callable} will be listed in this array. 146 */ 147 public final ReadOnlyList<String> exceptions; 148 149 150 // ******************************************************************************************** 151 // ******************************************************************************************** 152 // Quick Parameter Helper Methods 153 // ******************************************************************************************** 154 // ******************************************************************************************** 155 156 157 /** 158 * Retrieves the number of parameters utilized by the {@link Method} or {@link Constructor} 159 * ({@code Callable}) 160 * 161 * @return The size of all three of the parameter {@link ReadOnlyList}'s' 162 */ 163 public int numParameters() 164 { return parameterNames.size(); } 165 166 /** 167 * This will retrieve the type of the parameter (as a {@code String}) that has the name 168 * {@code 'parameterName'}. This method will simply return null, gracefully, if this 169 * {@link Method} or {@link Constructor} does not have a parameter with that name. This method 170 * will not throw an exception in such cases. 171 * 172 * @param parameterName The name of the parameter whose type you are requesting. 173 * 174 * @return The fully-qualified type of the parameter, as a {@code String} having the name 175 * {@code 'parameterName'}, or null if no such type exists. 176 * 177 * @see #parameterTypes 178 * @see #parameterNames 179 */ 180 public String getParameterType(String parameterName) 181 { 182 for (int i=0; i < parameterNames.size(); i++) 183 if (parameterNames.get(i).equals(parameterName)) 184 return parameterTypes.get(i); 185 186 return null; 187 } 188 189 /** 190 * This will retrieve the type of the parameter (as a {@code String}) that has the name 191 * {@code 'parameterName'}. This method will simply return null, gracefully, if this 192 * {@link Method} or {@link Constructor} does not have a parameter with that name. This 193 * method will not throw an exception in such cases. 194 * 195 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_C_JOW_NOTE> 196 * 197 * @param parameterName The name of the parameter whose type you are requesting. 198 * 199 * @return The type of the parameter, as a <B>one-word {@code String}</B> having the name 200 * {@code 'parameterName'}. 201 * 202 * @see #parameterTypesJOW 203 * @see #parameterTypes 204 * @see #parameterNames 205 */ 206 public String getParameterTypeJOW(String parameterName) 207 { 208 if (parameterNames != null) 209 for (int i=0; i < parameterNames.size(); i++) 210 if (parameterNames.get(i).equals(parameterName)) 211 return parameterTypesJOW.get(i); 212 213 return null; 214 } 215 216 /** 217 * This will retrieve the annotations-list that may (or may not) adorn the parameter which uses 218 * the name {@code 'parameterName'}. 219 * 220 * <BR /><BR />This method will simply return null, gracefully, if this {@link Method} or 221 * {@link Constructor} does not have a parameter with that name. This method will not throw 222 * an exception in such cases. 223 * 224 * <BR /><BR /><B>NOTE:</B>This method will also return null even if a parameter having the 225 * provided name is found, but that parameter wasn't annotated with anything. If a null is 226 * returned, distinguishing between the case where {@code 'parameterName'} just wasn't found, 227 * and the case where that parameter wasn't annotated - isn't possible here. 228 * 229 * @param parameterName The name of the parameter whose annotation-list you are requesting. 230 * 231 * @return The type of the parameter having the name {@code 'parameterName'}. 232 * 233 * @see #parameterAnnotations 234 * @see #parameterNames 235 */ 236 public ReadOnlyList<String> getParameterAnnotations(String parameterName) 237 { 238 if (parameterAnnotations == null) return null; 239 240 for (int i=0; i < parameterNames.size(); i++) 241 242 if (parameterNames.get(i).equals(parameterName)) 243 return parameterAnnotations.get(i); 244 // In the line above, if a parameter isnt annotated, that location in the 245 // array will have a 'null' 246 247 return null; 248 } 249 250 /** 251 * This will look at each parmeter's annotation array to see if there are any parameters in 252 * this {@code Callable's} invocation parameter-list that were annotated with anything. 253 * 254 * @return {@code TRUE} if there are any parameters that were annotated with something, and 255 * false if <B><I>every parameter</I></B> in the parameter-list had a 'null' {@code String} 256 * array of parameter-annotations. 257 * 258 * <BR /><BR />If this instance of {@code Callable} is one which does not accept any 259 * parameters, this methhod will return {@code FALSE} immediately. 260 * 261 * <BR /><BR /><B STYLE='color:red;'>NOTE:</B> The internal {@code 'parameterAnnotations'} 262 * field for class {@code Callable} is implemented as a two-dimensional {@code String}-array. 263 * There may be any number of parameters that are passed to a {@link Method} or 264 * {@code Constructor}, and each of those parameters may have any number of annotations that 265 * were attached to them. 266 * 267 * <BR /><BR /><B>SANITY-CHECK</B> Likely {@code 99.99%} of the parameters in the Java HTML 268 * library do not have any parameter's that are annotated. 269 * 270 * @see #parameterAnnotations 271 */ 272 public boolean hasAnnotatedParameters() 273 { return parameterAnnotations != null; } 274 275 /** 276 * Reports how many of the parameters in the internal list of parameters that had annotations 277 * attached to them. 278 * 279 * <BR /><BR /><B>SANITY-CHECK</B> Likely {@code 99.99%} of the parameters in the Java HTML 280 * library do not have any parameter's that are annotated. 281 * 282 * @return This will count how many parameters which are used by this {@code Callable} 283 * (either {@link Method} or {@link Field}) that have annotations that were attached to 284 * the parameter. 285 * 286 * @see #parameterAnnotations 287 */ 288 public int numAnnotatedParameters() 289 { 290 int count = 0; 291 292 if (parameterAnnotations == null) return 0; 293 294 // NOTE: each parameter has an "Annotation List" stored in a 2-D array. This is why 295 // this for-loop is using 'String[]', rather than 'String' ... 296 // A parameter may be annotated with zero annotations, one, or many annotations. 297 298 for (ReadOnlyList<String> paList : parameterAnnotations) 299 if (paList.size() > 0) count++; 300 301 return count; 302 } 303 304 305 // ******************************************************************************************** 306 // ******************************************************************************************** 307 // Constructor - com.sun.source.tree 308 // ******************************************************************************************** 309 // ******************************************************************************************** 310 311 312 // package-private: Only used by subclasses. 313 Callable( 314 MethodTree methodOrConstructor, 315 String methodOrConstructorName, 316 Entity entity, 317 TreeUtils util 318 ) 319 { 320 super( 321 util, // Big Ret4 thing 322 methodOrConstructor, // com.sun.source.Tree.MethodTree instance 323 methodOrConstructor.getModifiers(), // Annotation **AND** public, static, final 324 methodOrConstructorName, // Method-Name or "<init>" 325 entity, // Entity.METHOD or Entity.CONSTRUCTOR 326 methodOrConstructor.getBody() 327 ); 328 329 330 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 331 // Callable Parameters 332 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 333 334 List<? extends VariableTree> pList = methodOrConstructor.getParameters(); 335 336 if ((pList == null) || (pList.size() == 0)) 337 { 338 this.parameterNames = EMPTY_READONLY_LIST; 339 this.parameterTypes = EMPTY_READONLY_LIST; 340 this.parameterTypesJOW = EMPTY_READONLY_LIST; 341 this.parameterAnnotations = null; 342 } 343 344 else 345 { 346 int SIZE = pList.size(); 347 boolean atLeastOneAnnotatedParameter = false; 348 349 // For efficiency, use the ROAL-Builder, because otherwise (using ReadOnlyArrayList 350 // constructor), the Iterator would have to be run 4 separate times. 351 352 ROArrayListBuilder<String> bParameterNames = new ROArrayListBuilder<>(SIZE); 353 ROArrayListBuilder<String> bParameterTypes = new ROArrayListBuilder<>(SIZE); 354 ROArrayListBuilder<String> bParameterTypesJOW = new ROArrayListBuilder<>(SIZE); 355 356 ROArrayListBuilder<ReadOnlyList<String>> bParameterAnnotations = 357 new ROArrayListBuilder<>(); 358 359 for (VariableTree vt : pList) 360 { 361 bParameterNames.add(vt.getName().toString()); 362 363 String type = vt.getType().toString(); 364 365 bParameterTypes.add(type); 366 bParameterTypesJOW.add(StrSource.typeToJavaIdentifier(type)); 367 368 // NOTE: You **WILL TRY** again... It cannot be done - a Var-Args Parameter is auto 369 // converted into an Array by com.sun.souce.tree. There isn't a way to know that it 370 // was a Var-Args. (Other than by parsing the JavaDocHTMLFile) 371 // 372 // System.out.println(" " + this.parameterTypes[i] + " ==> " + 373 // this.parameterTypesJOW[i]); 374 375 // List<? extends AnnotationTree> annotList = ... 376 @SuppressWarnings("unchecked") 377 List<AnnotationTree> annotList = 378 (List<AnnotationTree>) vt.getModifiers().getAnnotations(); 379 380 if ((annotList == null) || (annotList.size() == 0)) 381 bParameterAnnotations.add(null); 382 else 383 { 384 atLeastOneAnnotatedParameter = true; 385 386 bParameterAnnotations.add( 387 new ReadOnlyArrayList<String>( 388 annotList, 389 (AnnotationTree at) -> at.toString().trim(), 390 annotList.size() 391 )); 392 } 393 } 394 395 this.parameterNames = bParameterNames.build(); 396 this.parameterTypes = bParameterTypes.build(); 397 this.parameterTypesJOW = bParameterTypesJOW.build(); 398 399 this.parameterAnnotations = atLeastOneAnnotatedParameter 400 ? bParameterAnnotations.build() 401 : null; 402 } 403 404 405 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 406 // Throws Clauses Declared by this Callable 407 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 408 409 @SuppressWarnings("unchecked") 410 // List<? extends ExpressionTree> tl = ... 411 List<ExpressionTree> tl = (List<ExpressionTree>) methodOrConstructor.getThrows(); 412 413 if ((tl == null) || (tl.size() == 0)) 414 this.exceptions = EMPTY_READONLY_LIST; 415 416 else this.exceptions = new ReadOnlyArrayList<String> 417 (tl, (ExpressionTree et) -> et.toString().trim(), tl.size()); 418 419 420 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 421 // FINISHED 422 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 423 // 424 // Currently Unused / Experimental 425 // this.autoFindID = AnnotationsMirror.processAutoFindID(annotations, signature); 426 427 this.autoFindID = ""; 428 } 429 430 431 // ******************************************************************************************** 432 // ******************************************************************************************** 433 // Package-Private Constructor: Used Internally by 'JDUInternal.ParseHTML.SignatureParse' 434 // ******************************************************************************************** 435 // ******************************************************************************************** 436 437 438 // Ensures that the Version with longer type-information strings is used. 439 // Java Doc often uses longer type strings 440 // 441 // This cannot be public because this "Merge" expects that both of these constructors are 442 // identical - with the only noted difference being one was from JavaDoc and one was from the 443 // source-code. The array-lengths need to be equal or else IndexOutOfBoundsException will 444 // start throwing. Plus, this is not useful outside of the upgrade application. 445 // 446 // This "merging" of two instances of Callable is **ONLY NEEDED** for Methods and Constructors, 447 // **AND NOT** for Fields, Enum-Constants or Annotation-Elements. 448 449 Callable(CallableSignature cSig, Callable cFromSourceParser) 450 { 451 // Calls the super 'clone' constructor for Declaration 452 // Java Parser has much more information for everything, except the "Parameter Types" 453 // JP elects to leave off the "Package Information" for types - while Java Doc includes 454 // it (**unless** it can provide an <A HREF=...> for the type, then it leaves it off too!) 455 456 super(cFromSourceParser); 457 458 this.parameterNames = cFromSourceParser.parameterNames; 459 this.parameterTypesJOW = cFromSourceParser.parameterTypesJOW; 460 this.exceptions = cFromSourceParser.exceptions; 461 this.parameterAnnotations = cFromSourceParser.parameterAnnotations; 462 463 // Currently Unused / Experimental 464 this.autoFindID = cFromSourceParser.autoFindID; 465 466 if (cFromSourceParser.parameterTypes.size() == 0) 467 this.parameterTypes = EMPTY_READONLY_LIST; 468 469 else 470 { 471 ROArrayListBuilder<String> roalb = 472 new ROArrayListBuilder<>(cFromSourceParser.parameterTypes.size()); 473 474 // Java Doc always produces "java.lang.String", while JP just gives "String" 475 // REMEMBER: JP is lazy when it comes to "Package Information" for types. 476 // Java-Doc includes it often - BUT NOT ALWAYS. (See above comment) 477 // Remember, though, the rest of the JavaParser fields are filled out, Java Doc 478 // leaves out all the other information that JP retrieves. 479 480 for (int i=0; i < cFromSourceParser.parameterTypes.size(); i++) 481 482 roalb.add( 483 (cSig.parameterTypes.get(i).length() > 484 cFromSourceParser.parameterTypes.get(i).length()) 485 486 ? cSig.parameterTypes.get(i) 487 : cFromSourceParser.parameterTypes.get(i) 488 ); 489 490 this.parameterTypes = roalb.build(); 491 } 492 } 493 494 Callable(CallableSignature cSig, Entity entity) 495 { 496 super(cSig.name, entity, cSig.signature); 497 498 this.parameterNames = cSig.parameterNames; 499 this.parameterTypes = cSig.parameterTypes; 500 this.parameterTypesJOW = cSig.parameterTypesJOW; 501 this.exceptions = null; 502 this.autoFindID = null; 503 this.parameterAnnotations = null; 504 } 505 506 507 // ******************************************************************************************** 508 // ******************************************************************************************** 509 // NEW HELPER 510 // ******************************************************************************************** 511 // ******************************************************************************************** 512 513 514 boolean nearlyEqualsCallableSig(CallableSignature cSig) 515 { 516 // This works for Methods and Constructors. This method used to be in the actual 'Method' 517 // and 'Constructor' sub-class due to this one-line optimization. (This is an un-necessary 518 // check for Constructors, but not for methods). 519 520 if (this.numParameters() != cSig.parameterNames.size()) return false; 521 522 // If there are no parameters (for either of them), then return true immediately 523 if (this.numParameters() == 0) return true; 524 525 // If any of the parameter-names are different, break immediately and return false; 526 for (int i=0; i < this.parameterNames.size(); i++) 527 if (! this.parameterNames.get(i).equals(cSig.parameterNames.get(i))) 528 return false; 529 530 // If the parameter-types listed by the javadoc '.html' file differ from parameter-types 531 // listed in the original '.java' source-code file, then break immediately. 532 // 533 // NOTE: The "package-information" for the FULL CLASS OR INTERFACE NAME is not always 534 // available. 535 536 for (int i=0; i < this.parameterTypes.size(); i++) 537 if (! this.parameterTypesJOW.get(i).equals(cSig.parameterTypesJOW.get(i))) 538 return false; 539 540 // ALL TESTS PASSED 541 return true; 542 } 543 544 545 // ******************************************************************************************** 546 // ******************************************************************************************** 547 // HELPERS - toString(int flags) 548 // ******************************************************************************************** 549 // ******************************************************************************************** 550 551 552 String printedParamNames() 553 { 554 return 555 "Parameter Names: " + 556 "[" + 557 ((parameterNames != null) 558 ? StrCSV.toCSV(parameterNames, true, true, null) : "") + 559 "]\n"; 560 } 561 562 String printedParamTypes(Torello.Java.Additional.Ret2<Boolean, Boolean> jow) 563 { 564 boolean b = parameterTypesJOW == null; 565 566 if (jow.b /*onlyJOW*/) return 567 "Simple Param-Types: " + 568 "[" + 569 (b ? "" : StrCSV.toCSV(parameterTypesJOW, true, true, null)) + 570 "]\n"; 571 572 else if (jow.a /*addJOW*/) return 573 "Parameter Types: " + 574 "[" + 575 (b ? "" : StrCSV.toCSV(parameterTypes, true, true, null)) + 576 "]\n" + 577 "Simple Param-Types: " + 578 "[" + 579 (b ? "" : StrCSV.toCSV(parameterTypesJOW, true, true, null)) + 580 "]\n"; 581 582 else return 583 "Parameter Types: " + 584 "[" + 585 (b ? "" : StrCSV.toCSV(parameterTypes, true, true, null)) + 586 "]\n"; 587 } 588 589 String printedExceptions() 590 { 591 return 592 "Exceptions: " + 593 "[" + 594 ((exceptions == null) ? "" : StrCSV.toCSV(exceptions, true, true, null)) + 595 "]\n"; 596 } 597 598 String printedCallableBody(int flags) 599 { 600 boolean methodBody = (flags & BODY) > 0; 601 boolean shortMethodBody = (flags & BODY_SHORT) > 0; 602 603 // "shortMethodBody" has a higher FLAG-PRECEDENCE 604 if (methodBody && shortMethodBody) methodBody = false; 605 606 if ((! methodBody) && (! shortMethodBody)) return ""; 607 608 String bodyStr = (this.body != null) ? codeHiLiteString() : "Not Defined"; 609 610 // "Synthetic Methods" do not have a body. Interface Methods also do not have one, either 611 // If this was built from the JavaDoc Signature, it will *ALSO* have no body... 612 613 if (shortMethodBody) bodyStr = StrPrint.abbrevEndRDSF(bodyStr, MAX_STR_LEN, true); 614 615 if ( shortMethodBody 616 || ((bodyStr.indexOf('\n') == -1) && (bodyStr.length() <= MAX_STR_LEN)) 617 ) 618 return "\nCallable Body: [" + bodyStr + " ]"; 619 else if (methodBody) 620 return "\nCallable Body: [\n" + bodyStr + "\n]"; 621 else 622 return ""; 623 } 624 625 /** 626 * Dummy Method. Overriden by Concrete Sub-Classes. 627 * @see Method#toString() 628 * @see Constructor#toString() 629 */ 630 public String toString() 631 { return "Callable is Abstract, all Concrete Sub-Classes Override this method."; } 632 633 /** 634 * Dummy Method. Overriden by Concrete Sub-Classes. 635 * @see Method#toString(int) 636 * @see Constructor#toString(int) 637 */ 638 public String toString(int flags) 639 { return "Callable is Abstract, all Concrete Sub-Classes Override this method."; } 640 641 642 // ******************************************************************************************** 643 // ******************************************************************************************** 644 // HELPERS - toString() - NO FLAGS 645 // ******************************************************************************************** 646 // ******************************************************************************************** 647 648 649 String printedParameterNamesTS() 650 { 651 return 652 "Parameter Names: [" + 653 ((parameterNames == null) 654 ? "" 655 : StrCSV.toCSV(parameterNames, true, true, null) 656 ) + "]\n"; 657 } 658 659 String printedParameterTypesTS() 660 { 661 return 662 "Parameter Types: [" + 663 ((parameterTypesJOW == null) 664 ? "" 665 : StrCSV.toCSV(parameterTypesJOW, true, true, null) 666 ) + "]\n"; 667 } 668 669 String printedExceptionsTS() 670 { 671 return 672 "Exceptions: [" + 673 ((exceptions == null) 674 ? "" 675 : StrCSV.toCSV(exceptions, true, true, null) 676 ) + "]\n"; 677 } 678}