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