001package Torello.JavaDoc; 002 003import Torello.HTML.HTMLNode; 004import Torello.HTML.TagNode; 005import Torello.HTML.Replaceable; 006import Torello.HTML.Util; 007import Torello.HTML.Balance; 008import Torello.HTML.Replacement; 009 010import Torello.Java.StrCmpr; 011import Torello.Java.StrIndent; 012import Torello.Java.StrReplace; 013import Torello.Java.FileRW; 014 015import Torello.Java.Additional.Ret2; 016 017import Torello.Java.ReadOnly.ReadOnlyList; 018 019import static Torello.Java.C.*; 020 021import Torello.JDUInternal.Messager.Where.JDUUserAPI; 022import Torello.JDUInternal.Messager.Messager; 023import Torello.JDUInternal.Messager.Where.Where_Am_I; 024 025import java.util.*; 026import java.util.regex.*; 027import java.util.stream.*; 028 029import java.io.File; 030import java.util.function.Predicate; 031import java.util.function.Function; 032 033/** 034 * Retains all information parsed from a <CODE>'.html'</CODE> Java-Doc web-page, and borrows 035 * any missing information that was found in the <CODE>'.java'</CODE> source-code file; note 036 * that an instance-reference of this class may be rerieved, and used, to further change a Java 037 * Doc page by registering a visitor-handler with the configuration class {@link Upgrade} by 038 * calling <B>{@link Upgrade#setExtraTasks(Consumer)}</B>. 039 * 040 * <EMBED CLASS='external-html' DATA-FILE-ID=PROG_MOD_HTML> 041 * <EMBED CLASS='external-html' DATA-FILE-ID=JD_HTML_F> 042 */ 043@JDHeaderBackgroundImg(EmbedTagFileID="REFLECTION_HTML_CLASS") 044public final class JavaDocHTMLFile extends ParsedFile implements java.io.Serializable 045{ 046 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 047 public static final long serialVersionUID = 1; 048 049 // When the Messager Reports its errors, this class passes this reference to the Messager 050 // to facilitate the printing of that information (What class encountered an error or warning 051 // that needs to be printed by the Messager). 052 // 053 // This is officially Package-Private (rather than private, which it normally is), because 054 // this Class is large enough to have justified breaking it up into smaller, private/hidden 055 // "Helper-Chunks". I like that expression. 056 // 057 // The "Helper-Chunks" are in the same package, and they need access to this field 058 059 static final Where_Am_I WHERE_AM_I = JDUUserAPI.JavaDocHTMLFile; 060 061 062 // ******************************************************************************************** 063 // ******************************************************************************************** 064 // Constructor 065 // ******************************************************************************************** 066 // ******************************************************************************************** 067 068 069 // This Constructor does very little work. It is not a completely empty body, but the vast 070 // majority of the field computations for this class are done in the package: 071 // 072 // Torello.JDUInternal.Parse.HTML.JDHF 073 // 074 // This Constructor mostly copies its Field-Values from Data-Records that have been computed 075 // in the classes in that package. There is a brief amount of computation done here, below. 076 // 077 // Keeping HTML-Parsing code in a separate, internal, package allows me to "localize" the 078 // complicated parsing code into a single location - far away from the end user. This code 079 // is dependent upon which of the Java-Doc Versions is being used. 080 // 081 // Since October of 2024, HTML-Parsing Code has been moved to a single, JDUInternal, 082 // suite of directories that are much easier to manage. This constructor, for instance, just 083 // block copies nearly all of the fields from one of those JDUInternal Data-Record Classes. 084 085 public JavaDocHTMLFile( 086 final Torello.JDUInternal.MainJDU.ClassUpgradeData.UpgradePredicates predicates, 087 final Torello.JDUInternal.MainJDU.ClassUpgradeData.PathsAndTypes pathsTypes, 088 089 // Full-Path of this JavaDoc HTML-File 090 final String jdHTMLFileName, 091 092 // Same as above, but only the Directory-Name is included - File-Name has been removed 093 final String javaDocPackageDirName, 094 095 // Java-Doc Package-Directory Name where Hi-Lited Source-Files are stored for this pkg 096 final String javaDocPkgHiLitedSrcCodeDirName, 097 098 final Torello.JDUInternal.Parse.Java.JSCF.JavaSourceCodeFile jscf, 099 100 final RelativePathStr dotDots, 101 102 // August 2024: Stopped passing JDHFHeaderFacts, rip it apart, pass these instead 103 final String simpleNameWithContainersAndGenerics, 104 final String packageName, 105 final CIET ciet, 106 final ReadOnlyList<String> genericParameters, 107 final String cietFullNameNoGenerics, 108 final Vector<HTMLNode> fileVec, 109 110 // The Members-Entites of this CIET/Type (Methods, Fields, Constructors, EC's & AE's) 111 final Torello.JDUInternal.Parse.HTML.JDHF.MemberDetails.D1_JDHFMembers jdhfMembers, 112 113 114 // This was moved out of this constructor body, and into the S2_LoopFiles... 115 // This is needed to build the JDHFMembers instance. Now, therefore, it has to be 116 // passed into this constructor 117 118 final String srcAsHTMLFileURL, 119 120 // New class which handles any / all User-Requested Details removal 121 final Torello.JDUInternal.Parse.HTML.JDHF.D2_RemovedDetails removedDetails, 122 123 124 // The Package-Summary HTML-File 125 // The User may obtain access to this file, via the reference stored inside of this 126 // Class. 127 // 128 // March 28th, 2025 129 130 final PackageSummaryHTML pkgSummaryHTML 131 ) 132 { 133 super( 134 jdHTMLFileName, 135 136 // java.util.Map.Entry<K, V> ==> Map.Entry<K, V> 137 simpleNameWithContainersAndGenerics, 138 139 // java.util.Map.Entry<K, V> ==> java.util 140 packageName, 141 142 // java.util.Map.Entry<K, V> ==> CIET.CLASS 143 ciet, 144 145 // java.util.Map.Entry<K, V> ==> "K", and "V" 146 genericParameters, 147 148 // java.util.Map.Entry<K, V> ==> java.util.Map.Entry 149 cietFullNameNoGenerics, 150 151 // java.util.Map.Entry<K, V> ==? Entry 152 jscf.typeNameJOW, 153 154 jscf.startLineNumber, 155 jscf.endLineNumber, 156 jscf.jdStartLineNumber, 157 jscf.jdEndLineNumber, 158 jscf.typeLineCount, 159 jscf.typeSizeChars, 160 jscf.javaSrcFileAsStr, 161 162 jdhfMembers.methods, 163 jdhfMembers.fields, 164 jdhfMembers.constructors, 165 jdhfMembers.enumConstants, 166 jdhfMembers.annotationElements, 167 168 169 // I think this is the right way to do things... This might change one day to ensure 170 // that only Nested-Types that are visible on the Java-Doc Page are actually included 171 // in this list 172 // 173 // For now, any Inner-Type that is identified by the Source-Code Parser will be visible 174 // in an instance of JDHF - EVEN IF JAVADOC DID NOT CREATE ANY HTML FOR THAT NESTED-TYPE 175 176 jscf.nestedTypes 177 ); 178 179 180 // **************************************************************************************** 181 // **************************************************************************************** 182 // BEGINNING INITIALIZATIONS 183 // **************************************************************************************** 184 // **************************************************************************************** 185 186 187 this.fileVec = fileVec; 188 189 // The directory name of the 'javadoc/' sub-directory that contained this '.html' File 190 this.javaDocPackageDirName = javaDocPackageDirName; 191 192 193 // The directory name of the 'javadoc/' sub-directory that contains any / all Hi-Lited 194 // HTML-Files for this particular package. 195 196 this.javaDocPkgHiLitedSrcCodeDirName = javaDocPkgHiLitedSrcCodeDirName; 197 198 // The relative-path string to the root javadoc directory (comprised of "../../..") 199 this.dotDots = dotDots; 200 201 // The mirros for @StaticFunctional **AND** JDHeaderBackgroundImg 202 this.typeAnnotationMirrors = jscf.typeAnnotationMirrors; 203 204 205 // This used to be computed inside this constructor body. Now it is computed inside the 206 // Main Processing Loop for JDHF Files 207 208 this.srcAsHTMLFileURL = srcAsHTMLFileURL; 209 210 211 // March, 2025: The User has access to the parsed 'package-summary.html' File 212 // This has been parsed for many years, but a way to actually access this file (other than 213 // internally), was not provided until recently. 214 215 this.pkgSummaryHTML = pkgSummaryHTML; 216 217 218 // **************************************************************************************** 219 // **************************************************************************************** 220 // DETAILS ENTRIES - Computed in Class JDHFMembers Constructor (October 2024) 221 // **************************************************************************************** 222 // **************************************************************************************** 223 224 225 // These are all ReadOnlyList's of Torello.JavaDoc.ReflHTML<? extends Declaration> 226 this.allMethodDetails = jdhfMembers.methodsREFL; 227 this.allFieldDetails = jdhfMembers.fieldsREFL; 228 this.allConstructorDetails = jdhfMembers.ctorsREFL; 229 this.allECDetails = jdhfMembers.ecREFL; 230 this.allAEDetails = jdhfMembers.aeREFL; 231 232 233 // **************************************************************************************** 234 // **************************************************************************************** 235 // User-Requested Details-Removal: Done in separate; class, just copy over the booleans 236 // **************************************************************************************** 237 // **************************************************************************************** 238 239 240 // These are all booleans. These are only TRUE if (and only if) the User has requested 241 // that all Details for a particular section have, indeed, been removed. 242 243 this.methodDetailsRemoved = removedDetails.methodDetailsRemoved; 244 this.fieldDetailsRemoved = removedDetails.fieldDetailsRemoved; 245 this.constructorDetailsRemoved = removedDetails.constructorDetailsRemoved; 246 this.ecDetailsRemoved = removedDetails.ecDetailsRemoved; 247 this.aeDetailsRemoved = removedDetails.aeDetailsRemoved; 248 249 250 // **************************************************************************************** 251 // **************************************************************************************** 252 // Compute the Hilited Source File URL. 253 // **************************************************************************************** 254 // **************************************************************************************** 255 256 257 // The class "NavButtons" will use this FileURL. The class HiLiteSrcCodeFile will actually 258 // do that hiliting. 259 // 260 // This should be null if the file isn't being hilited. 261 262 if (! predicates.hiLiteSourceCodeFileFilter.test(this.fullNameNoGenerics)) 263 this.hiLitedSrcFileURL = null; 264 265 else this.hiLitedSrcFileURL = 266 267 "hilite-files/" + 268 269 // The Top-Level Parent-Container HiLited '.html' File is the one to use. This code is 270 // making sure to "re-use" the already hilited parent container class! 271 272 (this.isInner 273 ? this.simpleNameWithPossibleContainers.substring 274 (0, this.simpleNameWithPossibleContainers.indexOf('.')) 275 : this.simpleNameWithPossibleContainers) + 276 ".java.html"; 277 278 279 // **************************************************************************************** 280 // **************************************************************************************** 281 // Header & Footer 282 // **************************************************************************************** 283 // **************************************************************************************** 284 285 286 // All this does is facilitating moving the constructor body to package: 287 // Torello.JDUInternal.Parse.HTML.Other 288 // 289 // The User's API is all contained in: 290 // Torello.JavaDoc.HeaderFooterHTML 291 // 292 // This makes it easier for the user to read & understand the stuff he needs, and much more 293 // importantly, the complicated Parse-HTML is essentially completely contained in package: 294 // 295 // Torello.JDUInternal.Parse 296 297 this.headerFooter = new HeaderFooterHTML 298 (new Torello.JDUInternal.Parse.HTML.HeaderFooter.D1_HeaderFooterRec 299 (fileVec, this.ciet /*, jscf Passed to make debugging this record easier */)); 300 301 // Now add the CSS-Tags to the header & footer, do this here... 302 if (predicates.cssTagsFilter.test(this.fullNameNoGenerics)) 303 Torello.JDUInternal.Features.INSERT_CSS_TAGS.API_CSSTagsTopAndSumm 304 .addTagsToDetailBanners(fileVec); 305 306 307 // **************************************************************************************** 308 // **************************************************************************************** 309 // SUMMARIES ENTRIES 310 // **************************************************************************************** 311 // **************************************************************************************** 312 313 314 // if (! Q.YN(C.BGREEN + "Should this continue?" + C.RESET)) System.exit(1); 315 316 Torello.JDUInternal.Parse.HTML.SummaryTable.D1_AllSummaryTables allSummTables = 317 318 Torello.JDUInternal.Parse.HTML.SummaryTable.API_GetSummaryTables.build( 319 fileVec, jscf, this, 320 321 322 // NOTE: There is a "bang" / "not" / "exclamation point" because the name of this 323 // filter is parameter is "retainRemoveDescriptions" 324 // 325 // But the name of this filter is "SummaryRemoveFilter" 326 // I have tested this thing. 327 328 ! predicates.summaryRemoveFilter.test(this.fullNameNoGenerics) 329 ); 330 331 332 this.methodSummaryTable = allSummTables.methodSummaryTable; 333 this.fieldSummaryTable = allSummTables.fieldSummaryTable; 334 this.constructorSummaryTable = allSummTables.constructorSummaryTable; 335 this.ecSummaryTable = allSummTables.ecSummaryTable; 336 this.raeSummaryTable = allSummTables.raeSummaryTable; 337 this.oaeSummaryTable = allSummTables.oaeSummaryTable; 338 this.ntSummaryTable = allSummTables.ntSummaryTable; 339 340 this.allNonNullSummaryTables = allSummTables.allNonNullSummaryTables; 341 } 342 343 344 // ******************************************************************************************** 345 // ******************************************************************************************** 346 // END CONSTRUCTOR !!! 347 // ******************************************************************************************** 348 // ******************************************************************************************** 349 350 351 // ******************************************************************************************** 352 // ******************************************************************************************** 353 // Primary (Final) Fields 354 // ******************************************************************************************** 355 // ******************************************************************************************** 356 357 358 /** 359 * This provides the relative path-{@code String} from {@code 'this'} Java Doc generated 360 * {@code '.html'} File to the root Java Doc Directory. 361 */ 362 public final RelativePathStr dotDots; 363 364 /** 365 * Directory-Name of the Java-Doc Sub-Directory that contains this Java-Doc 366 * {@code '.html'}-File. This sub-directory should just be the name of the Root Java-Doc 367 * Directory, with this class' Full Package-Name appended to it. 368 * 369 * <BR /><BR />If the JPMS (Java Platform Module System) has been used by a User-Project 370 * that contains multiple Java-Modules, then this directory shall also be pre-fixed with the 371 * relevant module containing this directory. 372 */ 373 public final String javaDocPackageDirName; 374 375 /** 376 * Directory-Name of the Java-Doc Sub-Directory that contains the Hi-Lited Source-Code 377 * {@code '.html'}-Files for the Java-Classes which are included in the Java-Package to which 378 * this particular Java-Class belongs. 379 * 380 * <BR /><BR />Unless instructed otherwise, the JDU spends effort to provide Syntax-HiLited 381 * {@code '.html'}-Files for each and every one of the Classes in a User's Java-Project. These 382 * files are each saved in the Hi-Lite Directory that is germaine / relevant for the given 383 * Java-Package to which the given Java-Class belongs. 384 */ 385 public final String javaDocPkgHiLitedSrcCodeDirName; 386 387 /** 388 * Directory-Name of the Java-Doc Sub-Directory that 389 */ 390 391 // The HTML Vector for a Java Doc web-page 392 private final Vector<HTMLNode> fileVec; 393 394 // This is where the 'updated-vector' is saved after the changes have been recommitted. 395 private Vector<HTMLNode> updatedFileVec = null; 396 397 /** 398 * The HTML that occurs directly above the Summary-Tables is the header. The HTML that is 399 * located below the Detail-Entries is the footer. 400 */ 401 public final HeaderFooterHTML headerFooter; 402 403 /** 404 * This is the File-{@code URL} to use if a need to link to the corresponding 405 * {@code "/src-html/"} file is necessary. 406 * 407 * <BR /><BR />This is a <B STYLE='color: red;'>relative</B>-URL that contains the requisite 408 * number of 'dot-dots' to reach the file from the location where this Java Doc HTML File is 409 * located. 410 */ 411 public final String srcAsHTMLFileURL; 412 413 /** 414 * This is the File-{@code URL} to use if a need to link to the corresponding 415 * {@code "/hilite-files/"} file is necessary. 416 * 417 * <BR /><BR />This is a <B STYLE='color: red;'>relative</B>-URL that is relative to the file 418 * from the location where this Java Doc HTML File is located. Specifically, this 419 * {@code String} begins with the text {@code "/hilite-files/"}, followed by the type-name, 420 * and ending with the extension {@code ".java.html"} 421 */ 422 public final String hiLitedSrcFileURL; 423 424 /** 425 * This is a reference to the parsed, {@code 'package-summary.html'} File for the Project's 426 * 'Java-Package' to which this class belongs. 427 */ 428 public final PackageSummaryHTML pkgSummaryHTML; 429 430 431 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 432 // The HTML Details as Vector<ReflHTML<?>> 433 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 434 435 /** 436 * This is the list of all constructors in the "Constructor Details", stored as 437 * Reflection-HTML instances 438 */ 439 public final ReadOnlyList<ReflHTML<Constructor>> allConstructorDetails; 440 441 /** 442 * This is the list of all fields in the "Field Details", stored as Reflection-HTML 443 * instances 444 */ 445 public final ReadOnlyList<ReflHTML<Field>> allFieldDetails; 446 447 /** 448 * This is the list of all methods in the "Method Details", stored as Reflection-HTML 449 * instances 450 */ 451 public final ReadOnlyList<ReflHTML<Method>> allMethodDetails; 452 453 /** 454 * This is the list of all constants in the "Enumerated Constant Details", stored as 455 * Reflection-HTML instances 456 */ 457 public final ReadOnlyList<ReflHTML<EnumConstant>> allECDetails; 458 459 /** 460 * This is the list of all elements in the "Annotation Element Details", stored as 461 * Reflection-HTML instances 462 */ 463 public final ReadOnlyList<ReflHTML<AnnotationElem>> allAEDetails; 464 465 466 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 467 // The HTML Summaries as SummaryTableHTML 468 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 469 470 /** The HTML for a Method Summary */ 471 public final SummaryTableHTML<Method> methodSummaryTable; 472 473 /** The HTML for a Field Summary Table */ 474 public final SummaryTableHTML<Field> fieldSummaryTable; 475 476 /** The HTML for a Constructor Summary Table */ 477 public final SummaryTableHTML<Constructor> constructorSummaryTable; 478 479 /** The HTML for an Enum-Constant Summary Table */ 480 public final SummaryTableHTML<EnumConstant> ecSummaryTable; 481 482 /** The HTML for an Optional Annotation Element Summary Table */ 483 public final SummaryTableHTML<AnnotationElem> oaeSummaryTable; 484 485 /** The HTML for a Required Annotation Element Summary Table */ 486 public final SummaryTableHTML<AnnotationElem> raeSummaryTable; 487 488 /** The HTML for a Nested-Class (Inner-Class) Summary Table */ 489 public final SummaryTableHTML<NestedType> ntSummaryTable; 490 491 /** all non-null {@link SummaryTableHTML} instances */ 492 @SuppressWarnings("rawtypes") 493 public final ReadOnlyList<SummaryTableHTML> allNonNullSummaryTables; 494 495 496 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 497 // Booleans for remembering whether a Details Section was removed completely 498 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 499 500 /** Identifies if this Java Doc HTML Page has had it's Method Details Removed */ 501 public final boolean methodDetailsRemoved; 502 503 /** Identifies if this Java Doc HTML Page has had it's Constructor Details Removed */ 504 public final boolean constructorDetailsRemoved; 505 506 /** Identifies if this Java Doc HTML Page has had it's Field Details Removed */ 507 public final boolean fieldDetailsRemoved; 508 509 /** Identifies if this Java Doc HTML Page has had it's Enumeration Constant Details Removed */ 510 public final boolean ecDetailsRemoved; 511 512 /** Identifies if this Java Doc HTML Page has had it's Annotation-Element Details Removed */ 513 public final boolean aeDetailsRemoved; 514 515 516 // ******************************************************************************************** 517 // ******************************************************************************************** 518 // Find Methods: Methods that accept a String / int 519 // ******************************************************************************************** 520 // ******************************************************************************************** 521 522 523 /** 524 * Returns a list as a {@code java.util.stream.Stream} of all Reflected-HTML-{@link Method} 525 * instances that have a name equal to {@code 'methodName'}. 526 * 527 * @param methodName The name of the method being searched for. 528 * 529 * @return A Java Stream containing all {@link Method}-{@link ReflHTML} instances that match 530 * the provided {@code 'methodName'} criteria. 531 */ 532 public Stream<ReflHTML<Method>> findMethodHTML(String methodName) 533 { 534 return allMethodDetails 535 .stream() 536 .filter((ReflHTML<Method> refl) -> refl.entity.name.equals(methodName)); 537 } 538 539 /** 540 * Returns a list as a {@code java.util.stream.Stream} of all Reflected-HTML-{@link Method} 541 * instances that have the specified number of parameters. 542 * 543 * @param numParameters The number of parameters contained by the {@link Method} being searched 544 * for. 545 * 546 * @return A Java Stream containing all {@link Method}-{@link ReflHTML} instances that match 547 * the provided {@code 'numParameters'} criteria. 548 */ 549 public Stream<ReflHTML<Method>> findMethodHTML(int numParameters) 550 { 551 return allMethodDetails 552 .stream() 553 .filter((ReflHTML<Method> refl) -> refl.entity.numParameters() == numParameters); 554 } 555 556 /** 557 * Returns a list as a {@code java.util.stream.Stream} of all 558 * Reflected-HTML-{@link Constructor} instances that have the specified number of parameters. 559 * 560 * @param numParameters The number of parameters contained by the {@link Constructor} being 561 * searched for. 562 * 563 * @return A Java Stream containing all {@link Constructor}-{@link ReflHTML} instances that 564 * match the provided {@code 'numParameters'} specifier. 565 */ 566 public Stream<ReflHTML<Constructor>> findConstructorHTML(int numParameters) 567 { 568 return allConstructorDetails 569 .stream() 570 .filter((ReflHTML<Constructor> refl) -> refl.entity.numParameters() == numParameters); 571 } 572 573 /** 574 * The Reflected-HTML Field having the specified name, or null if no such field exists 575 * 576 * @param fieldName The name of the field being searched 577 * 578 * @return The {@code ReflHTML<Field>} instance, from {@code 'this'} Java Doc Page, whose name 579 * matches {@code fieldName}, or null it wasn't found. 580 */ 581 public ReflHTML<Field> findFieldHTML(String fieldName) 582 { 583 for (ReflHTML<Field> f : allFieldDetails) if (f.entity.name.equals(fieldName)) return f; 584 return null; 585 } 586 587 /** 588 * The Reflected-HTML Enum-Constant having the specified name, or null if no such constant 589 * exists 590 * 591 * @param enumConstantName The name of the constant being searched 592 * 593 * @return The {@code ReflHTML<EnumConstant>} instance, from {@code 'this'} Java Doc Page, 594 * whose name matches {@code enumConstantName}, or null it wasn't found. 595 * 596 * @throws UpgradeException Only a Java {@link CIET}/Type {@code 'enum'} is allowed to declare 597 * Enum-Constants, and therefore this exception throws <I>when this method is invoked on a 598 * Java Doc HTML File that doesn't represent an {@code enum}.</I> 599 */ 600 public ReflHTML<EnumConstant> findECHTML(String enumConstantName) 601 { 602 if (this.ciet != CIET.ENUM) throw new UpgradeException( 603 "Finding Enumeration-Constants is only possible with HTML Files for Java 'enum' " + 604 "Type's. This file is of type [" + this.ciet.toString() + "]" 605 ); 606 607 for (ReflHTML<EnumConstant> ec : allECDetails) 608 if (ec.entity.name.equals(enumConstantName)) 609 return ec; 610 611 return null; 612 } 613 614 /** 615 * The Reflected-HTML Annotation-Element having the specified name, or null if no such element 616 * exists 617 * 618 * @param annotationElemName The name of the constant being searched 619 * 620 * @return The {@code ReflHTML<EnumConstant>} instance, from {@code 'this'} Java Doc Page, 621 * whose name matches {@code annotationElemName}, or null it wasn't found. 622 * 623 * @throws UpgradeException Only a Java {@link CIET}/Type {@code '@interface'} is allowed to 624 * declare Annotation-Elements, and therefore this exception throws <I>when this method is 625 * invoked on a Java Doc HTML File that doesn't represent an annotation.</I> 626 */ 627 public ReflHTML<AnnotationElem> findAEHTML(String annotationElemName) 628 { 629 if (this.ciet != CIET.ANNOTATION) throw new UpgradeException( 630 "Finding Annotation-Elements is only possible with HTML Files for Java '@interface' " + 631 "(Annotation) Type's. This file is of type [" + this.ciet.toString() + "]" 632 ); 633 634 for (ReflHTML<AnnotationElem> ae : allAEDetails) 635 if (ae.entity.name.equals(annotationElemName)) 636 return ae; 637 638 return null; 639 } 640 641 642 // ******************************************************************************************** 643 // ******************************************************************************************** 644 // Find Refl<HTML> Entities 645 // ******************************************************************************************** 646 // ******************************************************************************************** 647 648 649 /** 650 * Finds a matching {@link ReflHTML} instance whose internal {@code 'entity'} field has an 651 * ID number that matches input-parameter {@code 'declarationID'}. 652 * 653 * @param declarationID Whenever any instance of a sub-class of {@link Declaration} is created, 654 * it is given a unique id that uniquely identifies it across the entire life-cycle of the JVM 655 * that is currently running. 656 * 657 * @param c This must be a Java {@code java.lang.Class} from one of the following: 658 * {@link Constructor}, {@link Method}, {@link Field}, {@link EnumConstant} or 659 * {@link AnnotationElem}. 660 * 661 * <BR /><BR /><B>NOTE:</B> This class is very easily obtained by simple using the 662 * {@code 'enum'} field {@link Entity#upgraderReflectionClass}. To pass the appropriate class 663 * for a method, simply pass {@code Entity.METHOD.upgraderReflectionClass} to this parameter. 664 * 665 * <BR /><BR /><B>ALSO:</B> Even more easy (if you know the member/entity type), you can 666 * hard-code / hand-type the class yourself - for instance {@code Method.class}. If you were 667 * searching for a {@code ReflHTML<Field>}, you would pass {@code Field.class} to this 668 * parameter. 669 * 670 * @return The {@link ReflHTML} instance whose HTML describes the Method, Field, or Constructor 671 * etc... whose actual Reflected-class has an ID that matches {@code 'declarationID'}. Note 672 * that the second parameter {@code 'c'} is primarily used to "speed up" the search process. 673 * 674 * <DIV CLASS=EXAMPLE>{@code 675 * // Note the 'Method' being passed is Torello.JavaDoc.Method (not java.lang.reflect.Method) 676 * ReflHTML<Method> refl = jdhf.findEntity(someEntityID, Method.class); 677 * }</DIV> 678 * 679 * @throws IllegalArgumentException If the value passed to {@code 'declarationID'} is negative. 680 */ 681 @SuppressWarnings("unchecked") // Seems like the Java-Compiler is failing on this one. 682 public <ENTITY extends Declaration> ReflHTML<ENTITY> findReflHTML 683 (int declarationID, Class<ENTITY> c) 684 { 685 if (declarationID < 0) throw new IllegalArgumentException 686 ("You have passed a negative declarationID: " + declarationID); 687 688 if (Constructor.class.equals(c)) // This is **CLEARLY** not an unchecked cast! 689 for (ReflHTML<Constructor> r : allConstructorDetails) 690 { if (r.entity.id == declarationID) return (ReflHTML<ENTITY>) r; } 691 692 else if (Method.class.equals(c)) 693 for (ReflHTML<Method> r : allMethodDetails) 694 { if (r.entity.id == declarationID) return (ReflHTML<ENTITY>) r; } 695 696 else if (Field.class.equals(c)) 697 for (ReflHTML<Field> r : allFieldDetails) 698 { if (r.entity.id == declarationID) return (ReflHTML<ENTITY>) r; } 699 700 else if (EnumConstant.class.equals(c)) 701 for (ReflHTML<EnumConstant> r : allECDetails) 702 { if (r.entity.id == declarationID) return (ReflHTML<ENTITY>) r; } 703 704 else if (AnnotationElem.class.equals(c)) 705 for (ReflHTML<AnnotationElem> r : allAEDetails) 706 { if (r.entity.id == declarationID) return (ReflHTML<ENTITY>) r; } 707 708 return null; 709 } 710 711 712 // ******************************************************************************************** 713 // ******************************************************************************************** 714 // Links-Checker Access-Method 715 // ******************************************************************************************** 716 // ******************************************************************************************** 717 718 719 // StrReplace Helper String[]-Arrays 720 private static final String[] MATCH_STRS = { "%3C", "%3E", "%5B", "%5D" }; 721 private static final String[] REPLACE_STRS = { "<" , ">", "[", "]" }; 722 723 724 // This Retrieves all CSS-ID's and all <A HREF=...> (the HREF part) from every HTMLNode in 725 // this set, and checks returns them as two TreeSet's. 726 // 727 // Ret2.a: All CSS-ID's found on the page - *NOTE*, this is the *POST-PROCESSED* page 728 // Ret2.b: All HREF Attributes inside of every <A>/Anchor on this page 729 // 730 // This is called by the LinksChecker class 731 732 public Ret2<TreeSet<String>, TreeSet<String>> allIDsAndHREFs() 733 { 734 TreeSet<String> allIDs = new TreeSet<>(); 735 TreeSet<String> allHREFs = new TreeSet<>(); 736 TagNode tn = null; 737 738 for (HTMLNode n : updatedFileVec) 739 740 if ((tn = n.openTagPWA()) != null) 741 { 742 String id = tn.AV("id"); 743 String href = tn.AV("href"); 744 745 if (id != null) allIDs.add(id); 746 747 if (href != null) 748 { 749 if (href.equals("#top")) continue; 750 751 if (StrCmpr.startsWithXOR( 752 href, "http://", "https://", "/", 753 "javascript:" 754 )) 755 continue; 756 757 allHREFs.add(StrReplace.r(href, MATCH_STRS, REPLACE_STRS)); 758 } 759 } 760 761 return new Ret2<>(allIDs, allHREFs); 762 } 763 764 765 // ******************************************************************************************** 766 // ******************************************************************************************** 767 // Internal Utility Methods 768 // ******************************************************************************************** 769 // ******************************************************************************************** 770 771 772 // Checks the validity of the HTML on a Java Doc Web-page 773 // @return The Balance Report, generated by class {@link Balance}. The ;identifies any 774 // potential unmatched HTML tags. 775 // 776 // EXPORT_PORTAL METHOD 777 // This method is used by Package HTMLProcessors, and doesn't need to be exported to the user. 778 779 Hashtable<String, Integer> checkValidity() 780 { 781 if (updatedFileVec == null) Messager.assertFailGeneralPurpose( 782 "For some odd reason, the updatedFileVec has not been set", 783 null, 784 WHERE_AM_I 785 ); 786 787 return Balance.checkNonZero(Balance.check(updatedFileVec)); 788 } 789 790 // Saves the Vectorized-HTML back to the file on disk from whence it was loaded. 791 // @throws IOException This propogates any / all exceptions which might be thrown when 792 // trying to write the file to the file-system. 793 // 794 // EXPORT_PORTAL METHOD 795 // This method is used by Package HTMLProcessors, and doesn't need to be exported to the user. 796 797 void commitFileToDisk() throws java.io.IOException 798 { 799 if (updatedFileVec == null) Messager.assertFailGeneralPurpose( 800 "For some odd reason, the updatedFileVec has not been set", 801 null, 802 WHERE_AM_I 803 ); 804 805 FileRW.writeFile(Util.pageToString(this.updatedFileVec), this.fileName); 806 } 807 808 809 // Collates and inserts any changes made to the Sub-Sections back into the main page 810 // 811 // NO MESSAGER, NO THROWS, THE DATA IS ALL PRIVATE 812 // 813 // EXPORT_PORTAL METHOD 814 // This method is used by Package HTMLProcessors, and doesn't need to be exported to the user. 815 816 @SuppressWarnings("unchecked") // The Vector<Replaceable> cast 817 void commitChanges() 818 { 819 final TreeSet<Replaceable> replaceables = new TreeSet<>(); 820 821 allNonNullSummaryTables.forEach( 822 (@SuppressWarnings("rawtypes") SummaryTableHTML sTable) -> 823 replaceables.addAll((Vector<Replaceable>) sTable.allReplaceables()) 824 ); 825 826 for (ReflHTML<Method> r : allMethodDetails) 827 replaceables.addAll(r.allReplaceables()); 828 829 for (ReflHTML<Field> r : allFieldDetails) 830 replaceables.addAll(r.allReplaceables()); 831 832 for (ReflHTML<Constructor> r : allConstructorDetails) 833 replaceables.addAll(r.allReplaceables()); 834 835 for (ReflHTML<AnnotationElem> r : allAEDetails) 836 replaceables.addAll(r.allReplaceables()); 837 838 for (ReflHTML<EnumConstant> r : allECDetails) 839 replaceables.addAll(r.allReplaceables()); 840 841 replaceables.addAll(headerFooter.allReplaceables()); 842 843 844 // This is one of those "assert" moments. This exception is not EVER supposed to throw, 845 // however, if it does, it is likely because of some grave error that was made inside of 846 // this class Constructor. When this happens, it is better to print the file name that has 847 // caused this exception throw, quickly. 848 // 849 // Generally UNHANDLED EXCEPTIONS are supposed to signify a more serious design flaw, so 850 // it is better (IMHO) to just let them bubble up to the top, and FIX THE BUG ASAP. 851 // 852 // If this throws, make sure the print the file-name, and hope it is easy to figure out 853 // what just happened. 854 855 try 856 { this.updatedFileVec = Replacement.run(fileVec, replaceables, false).a; } 857 858 catch (Torello.HTML.ReplaceablesOverlappingException e) 859 { 860 System.out.println( 861 '\n' + 862 "Currently Processing - this.fileName:\n" + 863 " [" + BYELLOW + this.fileName + RESET + "]\n" + 864 "ParsedFile.quickSummary():\n" + 865 StrIndent.indent(this.quickSummary(), 4) 866 ); 867 868 throw e; 869 } 870 } 871 872 873 // ******************************************************************************************** 874 // ******************************************************************************************** 875 // THE NEW-THING: Garbage-Collector Helper? 876 // ******************************************************************************************** 877 // ******************************************************************************************** 878 // 879 // Does this help? Is this "good" for the Garbage-Collect? Is this going to speed it up, 880 // or slow it down? This is just a "C-Styled" FREE or DESTORY method... 881 // It isn't publicly visible anyway... 882 883 void clear() 884 { 885 headerFooter.clear(); 886 887 // private final Vector<SummaryTableHTML> allNonNullSummaryTables; 888 for (@SuppressWarnings("rawtypes") SummaryTableHTML st : allNonNullSummaryTables) 889 st.clear(); 890 } 891 892 893}