001package Torello.JavaDoc; 002 003import Torello.HTML.*; 004import Torello.HTML.NodeSearch.*; 005import Torello.Java.*; 006 007import static Torello.Java.C.*; 008 009import java.util.*; 010 011import java.io.Serializable; 012 013import Torello.JDUInternal.MESSAGER.Messager; 014 015/** 016 * This class stores the HTML Detail-Descriptions retrieved from a Java Doc web-page 'Details 017 * Section', and simultaneously, holds the reflection-data extracted from the 018 * <CODE>'.java'</CODE> corresponding source-code files - facilitating all changes to a Java 019 * Doc Page deemed necessary. 020 * 021 * <EMBED CLASS='external-html' DATA-FILE-ID=PROG_MOD_HTML> 022 * <EMBED CLASS='external-html' DATA-FILE-ID=REFLHTML> 023 * 024 * @param <ENTITY> This will take one of five type's: {@link Method}, {@link Constructor}, 025 * {@link Field}, {@link EnumConstant}, or {@link AnnotationElem}. The HTML contained by an 026 * instance of this class corresponds directly to the HTML contained by a detail section of one of 027 * one of these five Members / Entities. 028 */ 029@JDHeaderBackgroundImg(EmbedTagFileID="REFLECTION_HTML_CLASS") 030@SuppressWarnings("rawtypes") 031public class ReflHTML<ENTITY extends Declaration> 032 implements java.io.Serializable, java.lang.Comparable<ReflHTML> 033{ 034 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 035 protected static final long serialVersionUID = 1; 036 037 038 // ******************************************************************************************** 039 // ******************************************************************************************** 040 // HTML Processor's Special Access Stuff 041 // ******************************************************************************************** 042 // ******************************************************************************************** 043 044 045 /** 046 * This points to the opening {@code <UL>} tag for the detail. It's contents may be modified 047 * to include CSS classes or id's. 048 */ 049 public final TagNodeIndex openingUL; 050 051 private static final TagNode OPEN_DL = HTMLTags.hasTag("dl", TC.OpeningTags); 052 private static final TagNode CLOSE_DL = HTMLTags.hasTag("dl", TC.ClosingTags); 053 054 private Replaceable hiLitedCode = null; 055 056 private final boolean needToAddOpenCloseDLsForHiLitedDetails; 057 058 public void insertHiLitedDetail(Vector<HTMLNode> hiLitedDetail) 059 { 060 if (needToAddOpenCloseDLsForHiLitedDetails) 061 { 062 hiLitedDetail.insertElementAt(OPEN_DL, 0); 063 hiLitedDetail.add(CLOSE_DL); 064 } 065 066 this.hiLitedCode = this.hiLitedCode.setHTML(hiLitedDetail); 067 } 068 069 070 // ******************************************************************************************** 071 // ******************************************************************************************** 072 // Main Fields 073 // ******************************************************************************************** 074 // ******************************************************************************************** 075 076 077 /** 078 * This is the actual type-reflection (type-mirror) of the {@code Entity} extracted from the 079 * Java Doc {@code '.html'} web-page file, <I><B>and</B> from the </I> {@code '.java'} Source 080 * Code File. 081 * 082 * <BR /><BR />Since the type-parameter {@code ENTITY} must extend {@link Declaration}, this 083 * field will hold all of the information that was parsed & extracted by Java Parser. 084 * Depending on what type of instance of {@code Declaration} this represents, this will field 085 * will contain all of the parameter-names, parameter-types, modifiers, and exceptions that 086 * are associated with the entity. 087 * 088 * <BR /><BR />This will take one of five type's: {@link Method}, {@link Constructor}, 089 * {@link Field}, {@link EnumConstant}, {@link AnnotationElem}. This allows you to retrieve 090 * all reflected information, quickly and easily, associated with the Java Doc HTML "Detail 091 * Section" for a particular method, field, constructor etc... 092 */ 093 public final ENTITY entity; 094 095 /** 096 * This is used as a 'faster-way' to retrieve what type of Entity this "Reference-HTML" 097 * detail-section is being represented here. This makes the code more readable than using 098 * Java's {@code 'getClass()'} reflection to identify whether this 'Detail Section HTML' holds 099 * the HTML for a Method, Field, Constructor, Enumeration, etc... 100 * 101 * <BR /><BR />The value in {@code 'entityAsEnum'} shall always be identical to the type of 102 * the {@link #entity}. So for instance, if {@link #entity} contained a {@link Field} instance, 103 * this field would be equal to {@link Entity#FIELD}. If this entity represented a 104 * {@link Method} HTML Detail-Section element, then this field would hold 105 * {@link Entity#METHOD}. 106 */ 107 public final Entity entityAsEnum; 108 109 // The location in the parsed Java Doc '.html' web-page from whence this HTML was retrieved. 110 // This field is declared final. The many sections, parts, and segments of a Java Doc 111 // generated page can have their contents added, abbreviated, and extended, but they cannot be 112 // moved to different places on the page. 113 114 private final DotPair location; 115 116 // This is used to insert two "wrapper dividers" - the HTML <DIV> Elements that "wrap" around 117 // the contents of a ReflHTML. These wrapper DIV's (of which there are two) are need for the 118 // maximize, minimize & partialize buttons. Both of the two DIV's have **BOTH** a CSS-ID 119 // **AND** a CSS-CLASS that are used by two-line Java-Script methods that set the CSS "display" 120 // property to "block" and "none" (for hiding and showing these Refl's at the click of a 121 // button) 122 123 private final int endingLI; 124 125 126 // ******************************************************************************************** 127 // ******************************************************************************************** 128 // EVERYTHING ELSE 129 // ******************************************************************************************** 130 // ******************************************************************************************** 131 132 133 /** 134 * Each Deteail Entity on a JavaDoc Page has a <I>small and empty</I> Anchor-Link, <I>with an 135 * ID Attribute</I> that allows the browser to redirect to the detail on a JavaDoc page using 136 * a relative URL to redirect to the details location on the web-page. If that detail element 137 * was found, it's will be stored in this field. (Otherwise, this field will contain null) 138 * 139 * <BR /><BR />Below is the <CODE><A ID=..></CODE> generated by Java Doc for a method 140 * that is named {@code 'length'}, and takes zero parameters as input. 141 * 142 * <DIV CLASS=HTML>{@code 143 * <a id="length()"> 144 * <!-- --> 145 * </a> 146 * }</DIV> 147 */ 148 public final String htmlID; 149 150 151 // Every Detail-Element (Method, Field, Constructor, Enum-Constant and Annotation-Element) 152 // **MUST** have a name. This should be a member field, instead of an entry in the 153 // TreeMap of 'possible' subsections 154 155 private final SubSection name; 156 private final SubSection signature; 157 158 // This Vector's contents are auto-inserted by the "NavButtons" class 159 private final Vector<HTMLNode> detailNavBar = new Vector<>(); 160 161 162 163 // This is a TreeMap that will hold all of the 'optional' Detail-Elements. Many of the 164 // entries in this TreeMap will be very common (at least as far as Java-HTML Type's goes), 165 // but *NONE* of them are 'mandatory' - Java Doc will not auto-create the detail-elements 166 // that are stored in this map. They must be explicitly added by the user with taglets 167 168 private final TreeMap<Character, SubSection> subSections = new TreeMap<>(); 169 170 // These are all of the keys that are used for the SubSections that will be stored inside 171 // this TreeMap 172 173 private static final Character DESCRIPTION_KEY = 'a'; 174 private static final Character ANNOTATION_DEFAULT_KEY = 'b'; 175 private static final Character RETURNS_KEY = 'c'; 176 private static final Character SEE_ALSO_KEY = 'd'; 177 private static final Character THROWS_KEY = 'e'; 178 private static final Character PARAMETERS_KEY = 'f'; 179 private static final Character TYPE_PARAMETERS_KEY = 'g'; 180 private static final Character OVERRIDES_KEY = 'h'; 181 private static final Character SPECIFIED_BY_KEY = 'i'; 182 private static final Character AUTHOR_KEY = 'j'; 183 private static final Character SINCE_KEY = 'k'; 184 185 // The other 'simpleTagLabels' just have their index and value saved, furthermore this 186 // array-list is only built if one is found/identified in the JavaDoc page. 99% of the 187 // types in JavaHTML do not have these... 188 189 private ArrayList<TagNodeIndex> miscSimpleTagLabels = null; 190 191 /** 192 * This boolean indicates that the HTML description provided by this JavaDoc Detail has 193 * been copied from an parent-class or from an interface. In cases where an abstract method 194 * is implemented, the programmer may "opt-out" of typing anything about what the method's 195 * purpose is. If so, JavaDoc automatically copies the abstract (or parent) method's 196 * description, and leaves a little note saying so. 197 * 198 * <BR /><BR />Note that when this occurs, there will by two HTML {@code <DIV CLASS="block">} 199 * elements on the page for that detail. 200 */ 201 public final boolean descFromTypeLabel; 202 203 204 // ******************************************************************************************** 205 // ******************************************************************************************** 206 // SubSection Accessor Methods 207 // ******************************************************************************************** 208 // ******************************************************************************************** 209 210 211 /** 212 * Returns an HTML-{@code Vector} of the HTML used to display the 213 * <B STYLE='color: red;'>name</B> of a detail element. 214 * 215 * <BR /><BR />This also contains the same information as in the field 216 * {@link Declaration#name}, which is reflected (using <B>{@code Java Parer}</B>) from the 217 * associated {@code 'java'} source-code file. The HTML for this segment is listed, here 218 * below: 219 * 220 * <DIV CLASS=HTML>{@code 221 * <h4> [Name] </h4> 222 * }</DIV> 223 * 224 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 225 * 226 * @return An HTML-{@code Vector} of the Java Doc <B STYLE='color: red;'>name</B> 227 * segment of this detail. This method will never return null, as all detail-elements have 228 * a name. 229 * 230 * @see Declaration#name 231 */ 232 public Vector<HTMLNode> name() { return name.html; } 233 234 /** 235 * Returns an HTML-{@code Vector} of the HTML used to display the 236 * <B STYLE='color: red;'>signature</B> of a detail element. 237 * 238 * <BR /><BR />This also contains the same information as in the field 239 * {@link Declaration#signature}, which is reflected (using <B>{@code Java Parer}</B>) from the 240 * associated {@code 'java'} source-code file. In the HTML below it is the text that appears 241 * between the <CODE><PRE></CODE> tags. Note that the HTML {@code 'class'} attribute 242 * (present, below) will not always be included in every detail element. 243 * 244 * <DIV CLASS=HTML>{@code 245 * <h4> [Name] </h4> 246 * <pre class="Signature"> ... </pre> 247 * }</DIV> 248 * 249 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 250 * 251 * @return An HTML-{@code Vector} of the Java Doc <B STYLE='color: red;'>signature</B> 252 * segment of this detail. This method will never return null, as all detail-elements have 253 * a signature. 254 * 255 * @see Declaration#signature 256 */ 257 public Vector<HTMLNode> signature() { return signature.html; } 258 259 /** 260 * Returns an HTML-{@code Vector} of the HTML used to display the 261 * <B STYLE='color: red;'>description</B> of a detail element. 262 * 263 * <BR /><BR />This HTML is generated by the Java Doc Tool using the text provided by a 264 * programmer in his Java Doc Comments directly above the code in a {@code '.java'} file. In 265 * a Java Doc {@code '.html'} file, the description is always surrounded by an HTML divider 266 * ({@code '<DIV>'}) element, as appears below: 267 * 268 * <DIV CLASS=HTML>{@code 269 * <div class="block"> ... [Text-Description of Method, Field, etc...] ... </div> 270 * }</DIV> 271 * 272 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 273 * 274 * @return An HTML-{@code Vector} of the Java Doc <B STYLE='color: red;'>description</B> 275 * segment of this detail. Since a description is not mandatory, and it is not an 276 * auto-generated segment of a detail element, <I>this method will return null if a programmer 277 * has not written or included a description for this particular detail element in his 278 * source-code for this detail element.</I> 279 * 280 */ 281 public final Vector<HTMLNode> description() 282 { 283 SubSection s = subSections.get(DESCRIPTION_KEY); 284 return (s!= null) ? s.html : null; 285 } 286 287 /** 288 * Returns an HTML-{@code Vector} of the HTML used to display the 289 * <B STYLE='color: red;'>Default Annotation Element Value</B> of an Annotation-Detail element. 290 * 291 * <BR /><BR />This also contains the same information as in the field 292 * {@link AnnotationElem#defaultValue}, which is reflected (using <B>{@code Java Parer}</B>) 293 * from the associated {@code 'java'} source-code file. The HTML for this segment is listed, 294 * here below: 295 * 296 * <DIV CLASS=HTML>{@code 297 * <dl> 298 * <dt>Default:</dt> 299 * <dd> [ some values possibly inserted here ]</dd> 300 * </dl> 301 * }</DIV> 302 * 303 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 304 * 305 * <BR /><BR />Unless this detail is an "Annotation Detail", calling this method will generate 306 * an exception-throw. 307 * 308 * @return An HTML-{@code Vector} of an annotation detail element's 309 * <B STYLE='color: red;'>Default Value</B>. If the annotation does not have a default value 310 * assigned, or it is not present on the Java Doc Page, this method will return null. 311 * 312 * @throws DetailsException If the {@code ReflHTML} instance on which this method is being 313 * invoked is not for an Annotation Detail, the invocation will generate a 314 * {@code DetailsException} 315 * 316 * @see AnnotationElem#defaultValue 317 */ 318 public Vector<HTMLNode> annotationDefault() 319 { 320 if (entityAsEnum != Entity.ANNOTATION_ELEM) 321 322 throw new DetailsException( 323 "This ReflHTML is a Reflection of a(n) " + entityAsEnum.toString() + " details, " + 324 "however only Annotations may have Annotation-Element Default Values." 325 ); 326 327 SubSection s = subSections.get(ANNOTATION_DEFAULT_KEY); 328 return (s!= null) ? s.html : null; 329 } 330 331 /** 332 * Returns an HTML-{@code Vector} of the HTML used to display the 333 * <B STYLE='color: red;'>Returns:</B> segment of a Method Detail element. 334 * 335 * <BR /><BR />This also contains some of the information present in the field 336 * {@link Method#returnType}, which is reflected (using <B>{@code Java Parer}</B>) from the 337 * associated {@code 'java'} source-code file. 338 * 339 * <BR /><BR />This HTML is auto-generated by Java Doc using the 340 * <B><CODE STYLE='color: blue;'>@return</CODE></B> taglet's, which may be provided 341 * by a programmer in his {@code '.java'} source-code file. The HTML output generated by Java 342 * Doc is as below: 343 * 344 * <DIV CLASS=HTML>{@code 345 * <dt><span class="returnLabel">Returns:</span></dt> 346 * <dd> [User-Provided Return-Value Information, as HTML, Here] </dd> 347 * }</DIV> 348 * 349 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 350 * 351 * <BR /><BR />Only methods may have return-values. Furthermore, only methods for which the 352 * programmer has provided a <B><CODE STYLE='color: blue;'>@return</CODE></B> 353 * taglet entry will the result of this method be non-null. 354 * 355 * @return An HTML-{@code Vector} of a method detail element's 356 * <B STYLE='color: red;'>Returns:</B> label. If the method does not have such a label, 357 * because the programmer did not provide a 358 * <B><CODE STYLE='color: blue;'>@return</CODE></B> taglet, this method will 359 * return null. 360 * 361 * @throws DetailsException If the {@code ReflHTML} instance on which this method is being 362 * invoked is not for an Method Detail, the invocation will generate a 363 * {@code DetailsException} 364 * 365 * @see Method#returnType 366 */ 367 public Vector<HTMLNode> returns() 368 { 369 if (entityAsEnum != Entity.METHOD) 370 371 throw new DetailsException( 372 "This ReflHTML is a Reflection of a(n) " + entityAsEnum.toString() + " details, " + 373 "however only Methods may have Return-Values." 374 ); 375 376 SubSection s = subSections.get(RETURNS_KEY); 377 return (s!= null) ? s.html : null; 378 } 379 380 /** 381 * Returns an HTML-{@code Vector} of the HTML used to display the 382 * <B STYLE='color: red;'>See Also:</B> segment of any detail element. 383 * 384 * <BR /><BR />This HTML is auto-generated by Java Doc using the 385 * <B><CODE STYLE='color: blue;'>@see</CODE></B> taglet's, which may be provided 386 * by a programmer in his {@code '.java'} source-code file. The HTML output generated by Java 387 * Doc is as below: 388 * 389 * <DIV CLASS=HTML>{@code 390 * <dt><span class="seeLabel">See Also:</span></dt> 391 * <dd><a href="#someMethod()"><code>someMethod()</code></a></dd> 392 * }</DIV> 393 * 394 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 395 * 396 * <BR /><BR />Only detail elements for which the programmer has provided at least one 397 * <B><CODE STYLE='color: blue;'>@see</CODE></B> taglet entry will the result of 398 * this method be non-null. 399 * 400 * @return An HTML-{@code Vector} of a method detail element's 401 * <B STYLE='color: red;'>See Also:</B> label. If the method does not have such a label, 402 * because the programmer did not provide any 403 * <B><CODE STYLE='color: blue;'>@see</CODE></B> taglet, this method will 404 * return null. 405 * 406 */ 407 public Vector<HTMLNode> seeAlso() 408 { 409 SubSection s = subSections.get(SEE_ALSO_KEY); 410 return (s!= null) ? s.html : null; 411 } 412 413 /** 414 * Returns an HTML-{@code Vector} of the HTML used to display the 415 * <B STYLE='color: red;'>Throws:</B> segment of a Method or Constructor Detail element. 416 * 417 * <BR /><BR />This also contains some of the information present in the field 418 * {@link Callable#exceptions}, which is reflected (using <B>{@code Java Parer}</B>) from the 419 * associated {@code 'java'} source-code file. 420 * 421 * <BR /><BR />This HTML is auto-generated by Java Doc using the 422 * <B><CODE STYLE='color: blue;'>@throws</CODE></B> taglet's, which may be provided 423 * by a programmer in his {@code '.java'} source-code file. If a method or constructor is 424 * throwing <I>checked exceptions</I>, Java Doc will auto-create a 'Throws:' label / segment. 425 * The HTML output generated by Java Doc is as below: 426 * 427 * <DIV CLASS=HTML>{@code 428 * <dt><span class="throwsLabel">Throws:</span></dt> 429 * <dd> [Text explaining thrown exceptions by a method or constructor]</dd> 430 * }</DIV> 431 * 432 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 433 * 434 * <BR /><BR />Only methods and constructors are capable of throwing exceptions. Furthermore, 435 * only details for which the programmer has provided a 436 * <B><CODE STYLE='color: blue;'>@throws</CODE></B> taglet entry (or which throw 437 * checked-exceptions) will the result of this method be non-null. 438 * 439 * @return An HTML-{@code Vector} of a method or constructor detail element's 440 * <B STYLE='color: red;'>Throws:</B> label. If the detail does not have such a label, this 441 * method will return null. 442 * 443 * @throws DetailsException If the {@code ReflHTML} instance on which this method is being 444 * invoked is <I><B>neither</B></I> a Method Detail <B><I>nor</I></B> a Constructor Detail, the 445 * invocation will generate a {@code DetailsException} 446 * 447 * @see Callable#exceptions 448 */ 449 public Vector<HTMLNode> throwing() 450 { 451 if ((entityAsEnum != Entity.METHOD) && (entityAsEnum != Entity.CONSTRUCTOR)) 452 453 throw new DetailsException( 454 "This ReflHTML is a Reflection of a(n) " + entityAsEnum.toString() + " details, " + 455 "however only Methods and Constructors may throw Exceptions." 456 ); 457 458 SubSection s = subSections.get(THROWS_KEY); 459 return (s!= null) ? s.html : null; 460 } 461 462 /** 463 * Returns an HTML-{@code Vector} of the HTML used to display the 464 * <B STYLE='color: red;'>Parmeters:</B> segment of a Method or Constructor Detail element. 465 * 466 * <BR /><BR />This also contains some of the information present in the fields 467 * {@link Callable#parameterNames} and {@link Callable#parameterTypes}, which is reflected 468 * (using <B>{@code Java Parer}</B>) from the associated {@code 'java'} source-code file. 469 * 470 * <BR /><BR />This HTML is auto-generated by Java Doc using the 471 * <B><CODE STYLE='color: blue;'>@param</CODE></B> taglet's, which may be provided 472 * by a programmer in his {@code '.java'} source-code file. The HTML output generated by Java 473 * Doc is as below: 474 * 475 * <DIV CLASS=HTML>{@code 476 * <dt><span class="paramLabel">Parameters:</span></dt> 477 * <dd><code>[Parameter Name]</code> - [Some Parameter Description]</dd> 478 * }</DIV> 479 * 480 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 481 * 482 * <BR /><BR />Only methods and constructors may accept input parameters. Furthermore, 483 * only details for which the programmer has provided a 484 * <B><CODE STYLE='color: blue;'>@param</CODE></B> taglet entry will there be 485 * parameter descriptive-text on a Java Doc Page. The result of this method will be non-null, 486 * only in cases where such descriptions have been included in their JavaDoc commenting. 487 * 488 * @return An HTML-{@code Vector} of a method or constructor detail element's 489 * <B STYLE='color: red;'>Parameters:</B> label. If the detail does not have such a label, 490 * this method will return null. 491 * 492 * @throws DetailsException If the {@code ReflHTML} instance on which this method is being 493 * invoked is <I><B>neither</B></I> a Method Detail <B><I>nor</I></B> a Constructor Detail, the 494 * invocation will generate a {@code DetailsException} 495 * 496 * @see Callable#parameterNames 497 * @see Callable#parameterTypes 498 */ 499 public Vector<HTMLNode> parameters() 500 { 501 if ((entityAsEnum != Entity.METHOD) && (entityAsEnum != Entity.CONSTRUCTOR)) 502 503 throw new DetailsException( 504 "This ReflHTML is a Reflection of a " + entityAsEnum.toString() + " details, " + 505 "however only Methods and Constructors may have Parameters." 506 ); 507 508 SubSection s = subSections.get(PARAMETERS_KEY); 509 return (s!= null) ? s.html : null; 510 } 511 512 /** 513 * Returns an HTML-{@code Vector} of the HTML used to display the 514 * <B STYLE='color: red;'>Type Parmeters:</B> segment of a Method or Constructor Detail 515 * element. 516 * 517 * <BR /><BR />This HTML is auto-generated by Java Doc using the 518 * <B><CODE STYLE='color: blue;'>@param</CODE> <CODE><T></CODE></B> taglet's, 519 * which may be provided by a programmer in his {@code '.java'} source-code file. The HTML 520 * output generated by Java Doc is as below: 521 * 522 * <DIV CLASS=HTML>{@code 523 * <dt><span class="paramLabel">Type Parameters:</span></dt> 524 * <dd><code>[Type Parameter <T>]</code> - [Some Type Parameter Description]</dd> 525 * }</DIV> 526 * 527 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 528 * 529 * <BR /><BR />Only methods and constructors will allow type-parameters. Furthermore, 530 * only details for which the programmer has provided a 531 * <B><CODE STYLE='color: blue;'>@param</CODE> <CODE><T></CODE></B> taglet 532 * entry will there be parameter descriptive-text on a Java Doc Page. The result of this method 533 * will be non-null, only in cases where such descriptions have been included in their 534 * JavaDoc commenting. 535 * 536 * @return An HTML-{@code Vector} of a method or constructor detail element's 537 * <B STYLE='color: red;'>Type Parameters:</B> label. If the detail does not have such a 538 * label, this method will return null. 539 * 540 * @throws DetailsException If the {@code ReflHTML} instance on which this method is being 541 * invoked is <I><B>neither</B></I> a Method Detail <B><I>nor</I></B> a Constructor Detail, the 542 * invocation will generate a {@code DetailsException} 543 */ 544 public Vector<HTMLNode> typeParameters() 545 { 546 if ((entityAsEnum != Entity.METHOD) && (entityAsEnum != Entity.CONSTRUCTOR)) 547 548 throw new DetailsException( 549 "This ReflHTML is a Reflection of a(n) " + entityAsEnum.toString() + " details, " + 550 "however only Methods and Constructors may have Type-Parameters." 551 ); 552 553 SubSection s = subSections.get(TYPE_PARAMETERS_KEY); 554 return (s!= null) ? s.html : null; 555 } 556 557 /** 558 * Returns an HTML-{@code Vector} of the HTML used to display the 559 * <B STYLE='color: red;'>Overrides:</B> segment of a Method Detail element. 560 * 561 * <BR /><BR />This HTML is auto-generated by Java Doc, for methods which override a parent 562 * class or interface. The HTML output generated by Java Doc is as below: 563 * 564 * <DIV CLASS=HTML>{@code 565 * <dt><span class="overrideSpecifyLabel">Overrides:</span></dt> 566 * <dd><code> [ Some Name ]</code> in interface <code> [Interface Name] </code></dd> 567 * }</DIV> 568 * 569 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 570 * 571 * <BR /><BR />Only methods may override other methods. The result of this method will 572 * be non-null, only in cases where the Method Detail on which this invocation was made is 573 * actually an overrided method. 574 * 575 * @return An HTML-{@code Vector} of a method detail element's 576 * <B STYLE='color: red;'>Overrides:</B> label. If the detail does not have such a label, this 577 * method will return null. 578 * 579 * @throws DetailsException If the {@code ReflHTML} detail instance on which this method is 580 * being invoked is not a Method Detail, then a {@code DetailsException} will throw. 581 */ 582 public Vector<HTMLNode> overrides() 583 { 584 if (entityAsEnum != Entity.METHOD) 585 586 throw new DetailsException( 587 "This ReflHTML is a Reflection of a(n) " + entityAsEnum.toString() + " details, " + 588 "however only Methods may have \"Overrides:\" Labels." 589 ); 590 591 SubSection s = subSections.get(OVERRIDES_KEY); 592 return (s!= null) ? s.html : null; 593 } 594 595 /** 596 * Returns an HTML-{@code Vector} of the HTML used to display the 597 * <B STYLE='color: red;'>Specified by:</B> segment of a Method Detail element. 598 * 599 * <BR /><BR />This HTML is auto-generated by Java Doc, for methods which implement another 600 * method that was specified by an interface which the type implements, or a method specified 601 * by an abstract parent super-class. The HTML output generated by Java Doc is as below: 602 * 603 * <DIV CLASS=HTML>{@code 604 * <dt><span class="overrideSpecifyLabel">Specified by:</span></dt> 605 * <dd><code> [ Some Name ]</code> in interface <code> [Interface Name] </code></dd> 606 * }</DIV> 607 * 608 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 609 * 610 * <BR /><BR />Only methods may implement a "specified-method" (obviously!) The result of this 611 * method will be non-null - only in cases where the Method Detail on which this invocation was 612 * made <I>actually implements another abstract method declaration.</I> 613 * 614 * @return An HTML-{@code Vector} of a method detail element's 615 * <B STYLE='color: red;'>Specified by:</B> label. If the detail does not have such a label, 616 * this method will return null. 617 * 618 * @throws DetailsException If the {@code ReflHTML} detail instance on which this method is 619 * being invoked is not a Method Detail, then a {@code DetailsException} will throw. 620 */ 621 public Vector<HTMLNode> specifiedBy() 622 { 623 if (entityAsEnum != Entity.METHOD) 624 625 throw new DetailsException( 626 "This ReflHTML is a Reflection of a(n) " + entityAsEnum.toString() + " details, " + 627 "however only Methods may have \"Specified-By:\" Labels." 628 ); 629 630 SubSection s = subSections.get(SPECIFIED_BY_KEY); 631 return (s!= null) ? s.html : null; 632 } 633 634 /** This will be implented at a later date. For now, this throws an exception. */ 635 public Vector<HTMLNode> author() 636 { 637 if (1 == 1) throw new Torello.Java.ToDoException("Not Tested Yet"); 638 639 SubSection s = subSections.get(AUTHOR_KEY); 640 return (s!= null) ? s.html : null; 641 } 642 643 /** 644 * Returns an HTML-{@code Vector} of the HTML used to display the 645 * <B STYLE='color: red;'>Specified by:</B> segment of a Method Detail element. 646 * 647 * <DIV CLASS=HTML>{@code 648 * <dt><span class="simpleTagLabel">Since:</span></dt> 649 * <dd> [ Version Number Information ]</dd> 650 * }</DIV> 651 * 652 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 653 * 654 * <BR /><BR />Only details for which the programmer has provided a 655 * <B><CODE STYLE='color: blue;'>@since</CODE></B> taglet entry will there be 'since' 656 * descriptive-text on a Java Doc Page. The result of this method will be non-null, only in 657 * cases where such version-information has been included in their JavaDoc commenting. 658 * 659 * @return An HTML-{@code Vector} of a method detail element's 660 * <B STYLE='color: red;'>Since:</B> label. If the detail does not have such a label, this 661 * method will return null. 662 */ 663 public Vector<HTMLNode> since() 664 { 665 SubSection s = subSections.get(SINCE_KEY); 666 return (s!= null) ? s.html : null; 667 } 668 669 /** 670 * Returns an HTML-{@code Vector} of the HTML used to display the 671 * <B STYLE='color: red;'>Navigation Button-Bar</B> of a detail element. 672 * 673 * <BR /><BR />This is a row of buttons that is present directly below the signature of an 674 * HTML Detail-Entry. This row of buttons is automatically generated by the Java-Doc Upgrader 675 * Tool. It isn't Standard JavaDoc HTML. 676 * 677 * <BR /><BR />The actual HTML inserted by the Upgrader-Tool is included directly below: 678 * 679 * <DIV CLASS=HTML>{@code 680 * <DIV CLASS=DetailNav> 681 * <A HREF='#openTagPWA()'>🡅</A> 682 * <A HREF='#isOpenTagPWA()'>🡇</A> 683 * <A onclick="flashSumm('MD244')">⇈</A> 684 * <A HREF='hilite-files/HTMLNode.java.html#L273'>⮫</A> 685 * <SPAN> 686 * <A onclick='minimize(244)'>🗕</A> 687 * <A onclick='partialize(244)'>🗗</A> 688 * <A onclick='maximize(244)'>🗖</A> 689 * </SPAN> 690 * <NOSCRIPT> 691 * <DIV ID=NoScriptMPMAB>JavaScript is disabled on your browser.</DIV> 692 * </NOSCRIPT> 693 * </DIV> 694 * }</DIV> 695 * 696 * <EMBED CLASS='external-html' DATA-FILE-ID=REFL_MODIFY> 697 * 698 * @return An HTML-{@code Vector} of the Java Doc 699 * <B STYLE='color: red;'>Navigation Button-Bar</B> segment of this detail. This method will 700 * never return null, as all detail-elements have these buttons. 701 */ 702 public Vector<HTMLNode> detailNavBar() 703 { return detailNavBar; } 704 705 706 // ******************************************************************************************** 707 // ******************************************************************************************** 708 // Constructor 709 // ******************************************************************************************** 710 // ******************************************************************************************** 711 712 713 private String detErrMsg(Vector<HTMLNode> html, DotPair location) 714 { 715 String htmlStr = Util.rangeToString(html, location); 716 return StrPrint.abbrevEnd(htmlStr, false, 300); 717 } 718 719 /** 720 * Constructs an instance of this class. 721 * 722 * @param entity This identifies which "Entity-Type" from which the HTML provided was derived. 723 * If the HTML-{@code Vector} passed to this constructor were taken from a "Method Detail" part 724 * of a Java Doc Web-Page, then this parameter would be passed {@code Entity.METHOD} 725 * 726 * @param location The exact location on the Java Doc Web-Page from whence the HTML was 727 * extracted. It is important to note that this class facilitates changes, additions, and 728 * removal of HTML tags to a specific Detail-Segment of a CIET <B>"Details Section"</B>. 729 * 730 * <BR /><BR />After the changes have been made, and all other HTML processors in this package 731 * have completed their updates, this HTML will need to replace the old-stuff in the page 732 * {@code Vector}. Keeping this location around makes this a simple replacement that has been 733 * optimized. 734 * 735 * <BR /><BR />Note that changing nodes in a {@code Vector<HTMLNode>}) can become profusely 736 * in-efficient <I>if those changes are done in-place!</I> By extracting small portions of 737 * the HTML-Vector, and only modifying small parts (all the while saving the original location 738 * of the HTMl) modifying HTML can be quickly and efficiently - <I>even when not using DOM 739 * Tree like data-structures.</I> 740 * 741 * @param entityAsEnum If it is necessary to ask whether this "Reference HTML SubSection" 742 * is an HTML sub-section for a Method, Field or Constructor etc... Rather than using the 743 * {@code getClass()} on field {@code entity}, you may use this Enumeration, instead. 744 * 745 * @param html The HTML of a Java Doc detail-section 746 * 747 * @throws IllegalArgumentException If the parameter {@code 'entity'} and 748 * {@code 'entityAsEnum'} do not reference the same type of detail-section. This is a quick 749 * check that isn't costly. In the HTML file processors of this package, this won't ever be 750 * thrown. 751 */ 752 753 // The ReflHTML-Constructor: is only called from JavaDocHTMLFile 754 // USES: Messager.assertFailHTML() (JavaDocHTMLParseException) 755 756 ReflHTML( 757 ENTITY entity, 758 DotPair location, 759 Vector<HTMLNode> html, 760 Entity entityAsEnum, 761 String htmlID, 762 String srcAsHTMLFileURL 763 ) 764 { 765 this.entity = entity; 766 this.location = location; 767 this.entityAsEnum = entityAsEnum; 768 this.htmlID = htmlID; 769 770 // This will never happen. ReflHTML's are constructed properly in JavaDocHTMLFile. 771 // This switch statement is practically-free, so, this prevents possible errors later on. 772 773 switch (entityAsEnum) 774 { 775 case METHOD: if (! (entity instanceof Method)) 776 throw ENTITY_MATCH(entity, entityAsEnum); 777 break; 778 779 case FIELD: if (! (entity instanceof Field)) 780 throw ENTITY_MATCH(entity, entityAsEnum); 781 break; 782 783 case CONSTRUCTOR: if (! (entity instanceof Constructor)) 784 throw ENTITY_MATCH(entity, entityAsEnum); 785 break; 786 787 case ENUM_CONSTANT: if (! (entity instanceof EnumConstant)) 788 throw ENTITY_MATCH(entity, entityAsEnum); 789 break; 790 791 case ANNOTATION_ELEM: if (! (entity instanceof AnnotationElem)) 792 throw ENTITY_MATCH(entity, entityAsEnum); 793 break; 794 } 795 796 797 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 798 // This is used over and over again, in every Messager.assertFailHTML 799 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 800 801 final String sig = this.entity.signature; // Makes for easier typing 802 803 804 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 805 // Partialize, Maximize & Minimize Buttons: "Wrapper <DIV>'s" location/placement 806 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 807 808 this.endingLI = TagNodeFind.last(html, location.start, location.end, TC.ClosingTags, "LI"); 809 810 if (this.endingLI == -1) Messager.assertFailHTML 811 ("There was no closing HTML <LI> Element in this Refl-Detail", sig); 812 813 814 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 815 // Convenience Method's & Constructor's add a CSS Class to the first <UL> 816 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 817 818 TagNode tn = html.elementAt(location.start).ifTagNode(); 819 820 if (tn == null) Messager.assertFailHTML( 821 "The first node in this detail is not a <UL>:\n" + detErrMsg(html, location), 822 sig 823 ); 824 825 this.openingUL = new TagNodeIndex(location.start, tn); 826 827 828 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 829 // HiLitedDetails needs an insertion-point 830 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 831 832 // There is a <DL>...</DL> (HTML Definitions List) that Java Doc uses. There should be one 833 // at the end of the Detail-Section, which is where the HiLited Detail is placed. If a 834 // closing </DL> is not found, then an opening and closing <DL> ... </DL> needs to created 835 // and inserted at the end 836 // 837 // REMEMBER: 'hiLitedDetail' is wrapped in a <DD>...</DD><DT>...</DT> 838 839 int insertionPoint = TagNodeFind.last 840 (html, location.start, location.end, TC.ClosingTags, "dl"); 841 842 this.needToAddOpenCloseDLsForHiLitedDetails = insertionPoint == -1; 843 844 // If a </DL> wasn't found, a new <DL> (Definition List), needs to be built. Also a new 845 // insertion point is needed. The details section ends with a closing '</LI>' element, 846 // which is where to insert the new <DL>...</DL> 847 // 848 // NOTE: **FIELDS** are the Detail-Elements that usually do not have a <DL>...</DL>, because 849 // there aren't many <SPAN> Label-Banners present in a field 850 851 if (insertionPoint == -1) 852 { 853 insertionPoint = TagNodeFind.last 854 (html, location.start, location.end, TC.ClosingTags, "li"); 855 856 if (insertionPoint == -1) Messager.assertFailHTML 857 ("There is a detail with no ending </DL> and no ending </LI>", sig); 858 } 859 860 this.hiLitedCode = Replaceable.empty(insertionPoint); 861 862 863 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 864 // Mandatory HTML Fields: name & signature 865 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 866 867 // One precaution is that this <H4> must be among the first 8 nodes in the sub-page, 868 // Except for Annotation Elements, which have several HTML Nodes at the start of the detail 869 870 this.name = TagNodePeekInclusive.first( 871 html, location.start, 872 ((this.entityAsEnum == Entity.ANNOTATION_ELEM) ? location.end : (location.start + 8)), 873 "h4" 874 ); 875 876 if (this.name == null) 877 878 Messager.assertFailHTML( 879 "There was no name <H4> found in the detail:\n" + 880 // StrIndent.indent(Util.pageToString(html), 4), 881 detErrMsg(html, location), 882 sig 883 ); 884 885 int sPos = this.name.location.end + 1; 886 887 // Here, it is required that the <PRE> have a class that has the word "Signature" 888 // Unfortunately, javadoc doesn't always insert the class... 889 890 this.signature = TagNodePeekInclusive.first(html, sPos, location.end, "pre"); 891 892 if (this.signature == null) 893 894 Messager.assertFailHTML( 895 "There was no signature <PRE> found in the detail:\n" + 896 // StrIndent.indent(Util.pageToString(html), 4), 897 detErrMsg(html, location), 898 sig 899 ); 900 901 902 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 903 // UPDATE "/src-html/" URL FOR INNER-CLASSES 904 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 905 // 906 // This may seem **TOTALLY AND COMPLETELY** out of place, but this minor clean-up is going 907 // to be done, **RIGHT HERE**, in the Refl... 908 // 909 // When applied to the Java-HTML JAR, this saves 100 MB of Java-Doc Files... 910 // 911 // NOTE: The check for whether this is done is done inside the calling class - which 912 // happens to be JavaDocHTMLFIle. If this URL-HREF replacement DOES-NOT need to 913 // happen, then the URL 'srcAsHTMLFileURL' will be null. 914 // 915 // If this "ReflHTML" instance is a emmber of a Nested-Type / Inner-Type, then and only 916 // then should this be needed... 917 918 if (srcAsHTMLFileURL != null) 919 { 920 TagNodeIndex tni = InnerTagPeek.first 921 (signature.html, "a", "href", href -> href.contains("/src-html/")); 922 923 if (tni == null) Messager.assertFailGeneralPurpose( 924 "Could not locate the link to the /src-html/ file, but srcAsHTMLFileURL " + 925 '[' + srcAsHTMLFileURL + "] exists", 926 sig 927 ); 928 929 String href = srcAsHTMLFileURL; 930 931 if (entity.location != null) href += "#line." + ((entity.location.jdcStartLine == -1) 932 ? entity.location.signatureStartLine 933 : entity.location.jdcStartLine); 934 935 signature.html.setElementAt(tni.n.setAV("HREF", href, SD.SingleQuotes), tni.index); 936 } 937 938 939 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 940 // Description HTML Field, it is not Mandatory 941 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 942 943 sPos = this.signature.location.end + 1; 944 945 SubSection subSection = InnerTagPeekInclusive.first 946 (html, sPos, location.end, "div", "class", TextComparitor.C, "block"); 947 948 if (subSection != null) 949 { 950 // JavaDoc Inserts a cute little note whenever a method overrides another method 951 // stating that the description has been copied from the overriden method. Afterwards, 952 // **A SECOND DIV IS INSERTED** that contains the text of the description from the 953 // method that is being overriden. This only occurs when the method that is doing the 954 // overriding (the method from 'this' ReflHTML) - does not contain any description-text 955 // 956 // When this happens, just insert **BOTH** <DIV> Elements into the Vector 957 958 /* 959 // Somewhat inefficient. This code is executed 10,000 times - for each and 960 // every detail element on each and every JavaDoc Page 961 962 int copiedPos = InnerTagFind.first( 963 html, subSection.location.start + 1, subSection.location.end, 964 "span", "class", TextComparitor.C, "descfrmTypeLabel" 965 ); 966 */ 967 String classStr; 968 969 if ( 970 // Much faster short-circuit boolean-evaluation 971 ((tn = html.elementAt(subSection.location.start + 1).ifTagNode()) != null) 972 && tn.tok.equals("span") 973 && ((classStr = tn.AV("class")) != null) 974 && classStr.equals("descfrmTypeLabel") 975 ) 976 // if (copiedPos != -1) 977 { 978 // This part of the loop is almost never executed (unless the class) was 979 // actually found. Out of 10,000 Details there are probably 20 methods like 980 // this. 981 982 this.descFromTypeLabel = true; 983 984 // Make sure to skip the text</SPAN></DIV> 985 SubSection ssCopied = InnerTagPeekInclusive.first( 986 html, subSection.location.start + 4, location.end, 987 "div", "class", TextComparitor.C, "block" 988 ); 989 990 if (ssCopied == null) Messager.assertFailHTML( 991 "A <SPAN CLASS=descfrmTypeLabel> Label was Found, but there was not a " + 992 "second <DIV CLASS=\"block\">:\n" + 993 detErrMsg(html, location), 994 sig 995 ); 996 997 /* 998 System.out.println( 999 "\n=====================================================" + 1000 "\ncopiedPos: " + copiedPos + 1001 "\nlocation.end: " + location.end + 1002 "\n\nSubSection: " + subSection.toString() + 1003 "\nLocation: " + subSection.location.toString() + 1004 "\n\nssCopied: " + ssCopied.toString() + 1005 "\nLocation: " + ssCopied.location.toString() + 1006 "\n=====================================================" 1007 ); 1008 */ 1009 1010 subSection = new SubSection( 1011 new DotPair(subSection.location.start, ssCopied.location.end), 1012 Util.cloneRange(html, subSection.location.start, ssCopied.location.end + 1) 1013 ); 1014 } 1015 else this.descFromTypeLabel = false; 1016 1017 // For whichever of the two cases that has occured, just insert the HTML into the table 1018 sPos = subSection.location.end + 1; 1019 subSections.put(DESCRIPTION_KEY, subSection); 1020 } 1021 else this.descFromTypeLabel = false; 1022 1023 1024 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1025 // Annotations Have this little "Default" thing 1026 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1027 // 1028 // <dt><SPAN CLASS=C21>Default:</SPAN></dt> 1029 // <dd>{}</dd> 1030 1031 // NOTE: This is 'temp' variable that is reused over and over in this method 1032 DotPair dp = TagNodeFindInclusive.first(html, sPos, -1, "dl"); 1033 1034 if (dp != null) 1035 { 1036 int defPos = TextNodeFind.first 1037 (html, dp.start, dp.end, s -> s.equals("Default:")); 1038 1039 if (defPos != -1) 1040 { 1041 dp = Surrounding.first(html, defPos, "dt"); 1042 subSections.put 1043 (ANNOTATION_DEFAULT_KEY, new SubSection(dp, Util.cloneRange(html, dp))); 1044 } 1045 } 1046 1047 1048 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1049 // <DL> Labels: <DT><SPAN CLASS="someLabel">Some Label</SPAN></DT><DD>...</DD> Fields. 1050 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1051 1052 final String[] spanClasses = { 1053 "paramLabel", "returnLabel", "seeLabel", "throwsLabel", "overrideSpecifyLabel", 1054 "simpleTagLabel" 1055 }; 1056 1057 int[] spans = InnerTagFind.all 1058 (html, sPos, location.end, "span", "class", TextComparitor.EQ, spanClasses); 1059 1060 for (int spanPos : spans) 1061 { 1062 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1063 // Build the 'location' (DotPair) of the HTML that "surrounds" the SPAN (DT/DD's) 1064 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1065 // 1066 // <DT><SPAN CLASS='someLabel'>Some Label</SPAN></DT> 1067 // <DD> Some User Code Information </DD> 1068 // <DD> For Parameters & Throws, there are multiple DD's </DD> 1069 1070 // First ensure that there is an opening <DT> directly befofre the <SPAN CLASS=Label> 1071 // The 'tn' was declared at the top of this method, it is a re-usable temp variable 1072 1073 tn = html.elementAt(spanPos - 1).openTag(); 1074 1075 if ((tn == null) || (! tn.tok.equals("dt"))) Messager.assertFailHTML( 1076 "There is a " + BGREEN + html.elementAt(spanPos).str + RESET + "\n" + 1077 "Not preceeded by an opening " + BGREEN + "<DT>" + RESET + "\n" + 1078 "Instead there is a " + BGREEN + html.elementAt(spanPos - 1).str + 1079 RESET, 1080 sig 1081 ); 1082 1083 // Passed the above requirement/test, so this is the start of the SubSection 1084 int locStart = spanPos - 1; 1085 1086 // The particular section we are observing ends as soon as another section begins, or 1087 // we encounter a </DL> element. a <DT> element implies a new section is starting, and 1088 // a </DL> element means all of the labels have been handled 1089 // 1090 // Find the ending </DD> of the last <DD>...</DD> pair 1091 1092 int locEnd = -1, len = html.size(); 1093 1094 // Find either a closing </DL> (meaning no more <SPAN CLASS='someLabel'> elements), 1095 // or an oopening <DT> - which is starting a new SPAN-LABEL 1096 1097 INNER_FOR_LOOP: 1098 for (int i = (spanPos + 1); i < len; i++) 1099 1100 if ((tn = html.elementAt(i).ifTagNode()) != null) 1101 1102 if ( (tn.tok.equals("dl") && tn.isClosing) // Closing </DL> 1103 || (tn.tok.equals("dt") && (! tn.isClosing)) // Opening <DT> 1104 ) 1105 { 1106 locEnd = i; 1107 break INNER_FOR_LOOP; 1108 } 1109 1110 // I still haven't found what I'm looking for... 1111 // There was not closing </DL>, nor an new, opening <DT> 1112 1113 if (locEnd == -1) Messager.assertFailHTML( 1114 "There is a " + BGREEN + html.elementAt(spanPos).str + RESET + ' ' + 1115 "which isn't terminated by a new <DT> or a closing </DL>", 1116 sig 1117 ); 1118 1119 // Back up through any TextNodes - which, usually, is just a '\n' newline character. 1120 while ((tn = html.elementAt(--locEnd).ifTagNode()) == null); 1121 1122 // Finally, make sure there is a closing </DD> which is the end of the 1123 // <DT>...</DT><DD>...</DD> Combination. Remember, there may only be one <DT>..<DT> 1124 // (with a <SPAN CLASS='someLabel'), but that <DT> may be followed by more than one 1125 // <DD>...</DD> list. Parameters and Throws Labels have severl <DD> pairs! 1126 1127 if ((! tn.isClosing) || (! tn.tok.equals("dd"))) Messager.assertFailHTML( 1128 "There is a " + BGREEN + html.elementAt(spanPos).str + RESET + ' ' + 1129 "which is missing a <DD> definition", 1130 sig 1131 ); 1132 1133 1134 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1135 // Finished Searching. Build the "SubSection" instance, and start the switch-statement 1136 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1137 1138 // 'dp' is a temp variable that was first used earlier 1139 dp = new DotPair(locStart, locEnd); 1140 1141 // A 'SubSection' includes both the location, and the HTML put together in a 1142 // wrapper-class (SubSection is wrapper for Vector<HTMLNode> & DotPair) 1143 1144 SubSection section = new SubSection(dp, Util.cloneRange(html, dp)); 1145 1146 // Temporary Variables for the switch statement 1147 String kind; 1148 TextNode txn; 1149 1150 // In case you missed it, the six labels that were searched are: 1151 // "paramLabel", "returnLabel", "seeLabel", "throwsLabel", "overrideSpecifyLabel", 1152 // and "simpleTagLabel" 1153 1154 CASE: 1155 switch (html.elementAt(spanPos).asTagNode().AV("class")) 1156 { 1157 case "returnLabel" : 1158 1159 if (subSections.containsKey(RETURNS_KEY)) 1160 Messager.assertFailHTML("There is a second 'returnLabel", sig); 1161 else 1162 subSections.put(RETURNS_KEY, section); 1163 1164 break CASE; 1165 1166 case "seeLabel" : 1167 1168 if (subSections.containsKey(SEE_ALSO_KEY)) 1169 Messager.assertFailHTML("There is a second 'seeLabel", sig); 1170 else 1171 subSections.put(SEE_ALSO_KEY, section); 1172 1173 break CASE; 1174 1175 case "throwsLabel" : 1176 1177 if (subSections.containsKey(THROWS_KEY)) 1178 Messager.assertFailHTML("There is a second 'throwsLabel", sig); 1179 else 1180 subSections.put(THROWS_KEY, section); 1181 1182 break CASE; 1183 1184 1185 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1186 // There can be two kinds of "paramLabel" 1187 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1188 // 1189 // One is used for regular-parameters, which is the most common, while the second 1190 // is for "Type-Parameters" (rare, but useful) 1191 1192 case "paramLabel" : 1193 1194 if ((txn = html.elementAt(spanPos + 1).ifTextNode()) == null) 1195 Messager.assertFailHTML 1196 ("There is a 'paramLabel' not followed by a TextNode", sig); 1197 1198 kind = txn.str; 1199 1200 if (kind.equals("Parameters:")) 1201 { 1202 if (subSections.containsKey(PARAMETERS_KEY)) 1203 Messager.assertFailHTML 1204 ("There is a second 'paramLabel' for parameters", sig); 1205 else 1206 subSections.put(PARAMETERS_KEY, section); 1207 } 1208 else if (kind.equals("Type Parameters:")) 1209 { 1210 if (subSections.containsKey(TYPE_PARAMETERS_KEY)) 1211 Messager.assertFailHTML 1212 ("There is a second 'paramLabel' for type-parameters", sig); 1213 else 1214 subSections.put(TYPE_PARAMETERS_KEY, section); 1215 } 1216 1217 else Messager.assertFailHTML( 1218 "Unknown Parameter Label Found:\n" + 1219 StrIndent.indent(Util.pageToString(section.html), 4), 1220 sig 1221 ); 1222 1223 break CASE; 1224 1225 1226 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1227 // There can be two kinds of "overrideSpecifyLabel" 1228 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1229 // (surprise, "override" and "specified by") 1230 1231 case "overrideSpecifyLabel" : 1232 1233 if ((txn = html.elementAt(spanPos + 1).ifTextNode()) == null) 1234 Messager.assertFailHTML 1235 ("There is a 'overrideSpecifyLabel' not followed by a TextNode", sig); 1236 1237 kind = txn.str; 1238 1239 if (kind.equals("Specified by:")) 1240 { 1241 if (subSections.containsKey(SPECIFIED_BY_KEY)) 1242 { 1243 SubSection first = subSections.get(SPECIFIED_BY_KEY); 1244 1245 if ((dp.start - first.location.end) > 2) 1246 1247 Messager.assertFailHTML( 1248 "There is a second 'overrideSpecifyLabel' for 'Specified " + 1249 "by:', and unfortunately it is not contiguous with the " + 1250 "previous one.", 1251 sig 1252 ); 1253 1254 dp = new DotPair(first.location.start, dp.end); 1255 section = new SubSection(dp, Util.cloneRange(html, dp)); 1256 } 1257 1258 subSections.put(SPECIFIED_BY_KEY, section); 1259 } 1260 1261 else if (kind.equals("Overrides:")) 1262 { 1263 if (subSections.containsKey(OVERRIDES_KEY)) 1264 Messager.assertFailHTML 1265 ("There is a second 'Overrides' label", sig); 1266 else 1267 subSections.put(OVERRIDES_KEY, section); 1268 } 1269 1270 else Messager.assertFailHTML( 1271 "Unknown Overrides/Specified-By Label Found:\n" + 1272 StrIndent.indent(Util.pageToString(section.html), 4), 1273 sig 1274 ); 1275 1276 break CASE; 1277 1278 1279 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1280 // There can many kinds of "simpleTagLabel" 1281 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1282 1283 case "simpleTagLabel" : 1284 1285 if ((txn = html.elementAt(spanPos + 1).ifTextNode()) == null) 1286 Messager.assertFailHTML 1287 ("There is a 'simpleTagLabel' not followed by a TextNode", sig); 1288 1289 kind = txn.str; 1290 1291 if (kind.equals("Since:")) 1292 { 1293 if (subSections.containsKey(SINCE_KEY)) 1294 Messager.assertFailHTML 1295 ("There is a second 'simpleTagLabel' for 'since'", sig); 1296 else 1297 subSections.put(SINCE_KEY, section); 1298 } 1299 else 1300 { 1301 // 99% of the classes in JavaHTML do not have these, no need to build 1302 // this array-list at construction-time, only build if used 1303 1304 if (miscSimpleTagLabels == null) 1305 miscSimpleTagLabels = new ArrayList<>(); 1306 1307 miscSimpleTagLabels.add 1308 (new TagNodeIndex(spanPos, html.elementAt(spanPos).asTagNode())); 1309 } 1310 } 1311 } 1312 } 1313 1314 // This should never happend 1315 private IllegalArgumentException ENTITY_MATCH(Declaration entity, Entity entityAsEnum) 1316 { 1317 return new IllegalArgumentException( 1318 "The 'Entity' passed to parameter 'entityAsEnum' [" + entityAsEnum + "], does " + 1319 "not match the type of parameter 'entity' [" + entity.getClass().getSimpleName() + 1320 "]. They must be the same." 1321 ); 1322 } 1323 1324 /** 1325 * Clone Constructor. 1326 * @param other Another instance of {@code ReflHTML} 1327 * @see #clone() 1328 */ 1329 @SuppressWarnings("unchecked") 1330 ReflHTML(ReflHTML<ENTITY> other) 1331 { 1332 this.entity = other.entity; /* not cloned, the reflected entity */ 1333 this.entityAsEnum = other.entityAsEnum; 1334 this.location = other.location; /* immutable, no need to clone */ 1335 this.endingLI = other.endingLI; 1336 this.htmlID = other.htmlID; 1337 this.openingUL = other.openingUL; 1338 this.name = other.name.clone(); 1339 this.signature = other.signature.clone(); 1340 this.descFromTypeLabel = other.descFromTypeLabel; 1341 1342 // The Code-HiLited Details "Special Additions" 1343 this.hiLitedCode = other.hiLitedCode; 1344 this.needToAddOpenCloseDLsForHiLitedDetails = other.needToAddOpenCloseDLsForHiLitedDetails; 1345 1346 // Cannot 'clone' the other.subSections, it assigned a value at initialization (at the top 1347 // where it is declared). Use 'TreeMap.putAll' instead 1348 1349 this.subSections.putAll(other.subSections); 1350 1351 // This is not inialized unless there are actually 'simpleTagLabels' in the detail 1352 this.miscSimpleTagLabels = (other.miscSimpleTagLabels != null) 1353 ? ((ArrayList<TagNodeIndex>) other.miscSimpleTagLabels.clone()) 1354 : null; 1355 } 1356 1357 1358 // ******************************************************************************************** 1359 // ******************************************************************************************** 1360 // java.lang.Cloneable, java.lang.Comparable 1361 // ******************************************************************************************** 1362 // ******************************************************************************************** 1363 1364 1365 /** 1366 * Java's {@code interface Cloneable} requirements. This provides a "Deep Clone", where all 1367 * internal {@code Vector's} and {@code SubSection's} are also cloned, rather than a 1368 * "Shallow Clone", having identical references. 1369 * 1370 * @return A new {@code ReflHTML} whose internal fields are identical to this one. 1371 */ 1372 public ReflHTML<ENTITY> clone() { return new ReflHTML<>(this); } 1373 1374 /** 1375 * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison 1376 * using the {@code location} field. 1377 * 1378 * <BR /><BR /><B><SPAN STYLE="color: red;">FINAL METHOD:</B></SPAN> This method is declared 1379 * {@code final}, and cannot be modified by sub-classes. 1380 * 1381 * @param other Any other {@code ReflHTML} to be compared to {@code 'this' ReflHTML} 1382 * 1383 * @return An integer that fulfils Java's {@code interface Comparable<T> public boolean 1384 * compareTo(T t)} method requirements. 1385 * 1386 * @see DotPair#compareTo(DotPair) 1387 */ 1388 public final int compareTo(ReflHTML other) 1389 { return this.location.compareTo(other.location); } 1390 1391 1392 // ******************************************************************************************** 1393 // ******************************************************************************************** 1394 // Rebuilding a ReflHTML from it's pieces 1395 // ******************************************************************************************** 1396 // ******************************************************************************************** 1397 1398 1399 private static final Vector<HTMLNode> TEMP_END_VEC = new Vector<>(1); 1400 1401 TreeSet<Replaceable> allReplaceables() 1402 { 1403 TreeSet<Replaceable> replaceables = new TreeSet<>(); 1404 SubSection ss = null; 1405 1406 replaceables.add(openingUL); 1407 replaceables.add(this.name); 1408 1409 replaceables.add 1410 (Replaceable.createInsertion(this.name.location.end + 1, this.detailNavBar)); 1411 1412 replaceables.add(this.signature); 1413 1414 1415 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1416 // Add "Maximize-Partialize-Minimize" Button <DIV>'s - EMBARRASING THAT THIS IS DONE HERE 1417 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1418 // 1419 // It seems like this isn't the best place to do this, but I simply am at a loss for words 1420 // about where I *SHOULD* put this stuff. 1421 1422 this.signature.html.add( 1423 0, 1424 new TextNode("<DIV CLASS=ORD ID=ORD" + this.entity.id + ">\n") 1425 ); 1426 1427 this.signature.html.add 1428 (new TextNode("\n<DIV CLASS=IRD ID=IRD" + this.entity.id + ">\n")); 1429 1430 Vector<HTMLNode> TEMP_VEC = new Vector<>(); 1431 1432 TEMP_VEC.add( 1433 new TextNode( 1434 "\n</DIV> <!-- IRD" + this.entity.id + " -->" + 1435 "\n</DIV> <!-- ORD" + this.entity.id + " -->\n\n" 1436 ) 1437 ); 1438 1439 replaceables.add(Replaceable.createInsertion(endingLI, TEMP_VEC)); 1440 1441 1442 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1443 // All of the other's 1444 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 1445 1446 if ((ss = subSections.get(DESCRIPTION_KEY)) != null) replaceables.add(ss); 1447 if ((ss = subSections.get(ANNOTATION_DEFAULT_KEY)) != null) replaceables.add(ss); 1448 if ((ss = subSections.get(RETURNS_KEY)) != null) replaceables.add(ss); 1449 if ((ss = subSections.get(SEE_ALSO_KEY)) != null) replaceables.add(ss); 1450 if ((ss = subSections.get(THROWS_KEY)) != null) replaceables.add(ss); 1451 if ((ss = subSections.get(PARAMETERS_KEY)) != null) replaceables.add(ss); 1452 if ((ss = subSections.get(TYPE_PARAMETERS_KEY)) != null) replaceables.add(ss); 1453 if ((ss = subSections.get(OVERRIDES_KEY)) != null) replaceables.add(ss); 1454 if ((ss = subSections.get(SPECIFIED_BY_KEY)) != null) replaceables.add(ss); 1455 if ((ss = subSections.get(AUTHOR_KEY)) != null) replaceables.add(ss); 1456 if ((ss = subSections.get(SINCE_KEY)) != null) replaceables.add(ss); 1457 1458 replaceables.add(hiLitedCode); 1459 1460 return replaceables; 1461 } 1462 1463 1464 // ******************************************************************************************** 1465 // ******************************************************************************************** 1466 // THE NEW-THING: Garbage-Collector Helper? 1467 // ******************************************************************************************** 1468 // ******************************************************************************************** 1469 // 1470 // Does this help? Is this "good" for the Garbage-Collect? Is this going to speed it up, 1471 // or slow it down? This is just a "C-Styled" FREE or DESTORY method... 1472 // It isn't publicly visible anyway... 1473 // 1474 // NOTE: Many of the null checks are completely superfluous, but not all of them... 1475 // In any case, the worst feeling in the world would be NPE for this silly little 1476 // "optimization" 1477 1478 void clear() 1479 { 1480 // public final TagNodeIndex openingUL; 1481 if (openingUL != null) openingUL.n = null; 1482 1483 // private final SubSection name; 1484 if (name != null) { name.html.clear(); name.html = null; } 1485 1486 // private final SubSection signature; 1487 if (signature != null) { signature.html.clear(); signature.html = null; } 1488 1489 // private final TreeMap<Character, SubSection> subSections = new TreeMap<>(); 1490 if (subSections != null) 1491 { 1492 for (SubSection ss : subSections.values()) 1493 { 1494 ss.html.clear(); 1495 ss.html = null; 1496 } 1497 1498 subSections.clear(); 1499 } 1500 1501 // private Replaceable hiLitedCode = null; 1502 if (hiLitedCode != null) { hiLitedCode.clearHTML(); hiLitedCode = null; } 1503 1504 // private ArrayList<TagNodeIndex> miscSimpleTagLabels = null; 1505 if (miscSimpleTagLabels != null) 1506 { 1507 miscSimpleTagLabels.clear(); 1508 miscSimpleTagLabels = null; 1509 } 1510 } 1511}