001package Torello.JavaDoc;
002
003import Torello.HTML.*;
004import Torello.HTML.NodeSearch.*;
005
006import Torello.Java.*;
007import Torello.Java.Additional.*;
008
009import static Torello.Java.C.*;
010
011import Torello.JavaDoc.Messager.Messager;
012import Torello.JavaDoc.Messager.Where_Am_I;
013import Torello.JDUInternal.Miscellaneous.Where.JDUUserAPI;
014
015import Torello.Java.ReadOnly.ReadOnlyList;
016
017import java.util.*;
018import java.util.stream.*;
019
020import java.util.function.Function;
021
022/**
023 * This class stores the HTML for a Summary-Table - which is the table at the top of a Java Doc
024 * Page listing all of one type of entities present in the CIET/Type.  
025 * 
026 * <EMBED CLASS='external-html' DATA-FILE-ID=PROG_MOD_HTML>
027 * <EMBED CLASS='external-html' DATA-FILE-ID=SUMM_TABLE_HTML>
028 * 
029 * @param <ENTITY> This will take one of six type's: {@link Method}, {@link Constructor},
030 * {@link Field}, {@link EnumConstant}, {@link AnnotationElem} or {@link NestedType}.   The HTML
031 * contained by this class correspond directly to the HTML contained by a Summary-Table of one of
032 * section of one of these Entities / Members.
033 */
034@JDHeaderBackgroundImg(EmbedTagFileID="REFLECTION_HTML_CLASS")
035public class SummaryTableHTML<ENTITY extends Declaration>
036{
037    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
038    protected static final long serialVersionUID = 1;
039
040    // When the Messager Reports its errors, this class passes this reference to the Messager
041    // to facilitate the printing of that information (What class encountered an error or warning
042    // that needs to be printed by the Messager).
043
044    private static final Where_Am_I WHERE_AM_I = JDUUserAPI.SummaryTableHTML;
045
046
047    // ********************************************************************************************
048    // ********************************************************************************************
049    // Summary-Table Header-Row Titles
050    // ********************************************************************************************
051    // ********************************************************************************************
052
053
054    // For the other "Entity Kinds":
055    // 
056    //  Entity.FIELD:           3 columns   (Modifier/Type, Name & Description)
057    //  Entity.METHOD:          3 columns   (Modifier/Type, Name & Description)
058    //  Entity.ANNOTATION_ELEM: 3 columns   (Modifier/Type, Name & Description)
059    //  Entity.INNER_CLASS:     3 columns   (Modifier/Type, Name & Description)
060    // 
061    //  Entity.ENUM_CONSTANT:   2 columns   (Name & Description)
062    // 
063    //  Entity.CONSTRUCTOR: VARIES - Sometimes "Modifier/Type" is included, and Sometimes not!
064    // 
065    // NOTE: Please see the FULL-EXTENDED-EXPLANATION BELOW (where this field is defined!)
066 
067    /**
068     * Column-Names for the varies types of columns in a Summary-Table
069     * 
070     * <BR /><BR />For each of the "Entity Kinds", these are the standard column names which are
071     * present inside of a typical Java-Doc Summary-Table.  Note that, generally, each of these
072     * "Entities" have very similar (if not, identical) Column-Names.  Only the last two entries in
073     * this table differ at all:
074     * 
075     * <BR /><BR /><TABLE ID=Col-Names-Table CLASS=JDBriefTable>
076     * <TR><TH>Summary-Kind</TH><TH>Columns</TH></TR>
077     * <TR>
078     *      <TD>{@link Entity#FIELD}:</TD>
079     *      <TD>3 columns (Modifier/Type, Field &amp; Description)</TD>
080     * </TR>
081     * <TR>
082     *      <TD>{@link Entity#METHOD}:</TD>
083     *      <TD>3 columns (Modifier/Type, Method &amp; Description)</TD>
084     * </TR>
085     * <TR>
086     *      <TD>{@link Entity#ANNOTATION_ELEM}:</TD>
087     *      <TD>3 columns (Modifier/Type, Required-Element or Optional-Element &amp;
088     *          Description)</TD>
089     * </TR>
090     * <TR>
091     *      <TD>{@link Entity#INNER_CLASS}:</TD>
092     *      <TD>3 columns   (Modifier, Class &amp; Description)</TD>
093     * </TR>
094     * 
095     * <TR><TD COLSPAN=2>&nbsp;</TD></TR>
096     * 
097     * <TR>
098     *      <TD>{@link Entity#ENUM_CONSTANT}:</TD>
099     *      <TD>2 columns (Name &amp; Description)</TD>
100     * </TR>
101     * 
102     * <TR><TD COLSPAN=2>&nbsp;</TD></TR>
103     * 
104     * <TR>
105     *      <TD>{@link Entity#CONSTRUCTOR}:</TD>
106     *      <TD> <B STYLE='color: red;'>VARIES</B>
107     *           Sometimes "Modifier/Type" is included, and Sometimes not!
108     *      </TD>
109     * </TR>
110     * </TABLE>
111     */
112    public enum ColNames
113    {
114        Method          ("Method"),
115        Field           ("Field"),
116        Constructor     ("Constructor"),
117        EnumConstant    ("Enum Constant"),
118        OptionalElement ("Optional Element"),
119        RequiredElement ("Required Element"),
120        Interface       ("Interface"),
121        Class           ("Class"),
122
123        Modifier        ("Modifier"),
124        ModifierType    ("Modifier and Type"),
125        Description     ("Description");
126
127        public final String colName;
128
129        private static final TreeMap<String, ColNames> namesTM = new TreeMap<>();
130
131        static 
132        {
133            ColNames.namesTM.put(ColNames.Method.colName,           ColNames.Method);
134            ColNames.namesTM.put(ColNames.Field.colName,            ColNames.Field);
135            ColNames.namesTM.put(ColNames.Constructor.colName,      ColNames.Constructor);
136            ColNames.namesTM.put(ColNames.EnumConstant.colName,     ColNames.EnumConstant);
137            ColNames.namesTM.put(ColNames.OptionalElement.colName,  ColNames.OptionalElement);
138            ColNames.namesTM.put(ColNames.RequiredElement.colName,  ColNames.RequiredElement);
139            ColNames.namesTM.put(ColNames.Interface.colName,        ColNames.Interface);
140            ColNames.namesTM.put(ColNames.Class.colName,            ColNames.Class);
141            ColNames.namesTM.put(ColNames.Modifier.colName,         ColNames.Modifier);
142            ColNames.namesTM.put(ColNames.ModifierType.colName,     ColNames.ModifierType);
143            ColNames.namesTM.put(ColNames.Description.colName,      ColNames.Description);
144        }
145
146        private ColNames(final String colName)
147        { this.colName = colName; }
148
149        public static ColNames findCol(final String colName)
150        { return ColNames.namesTM.get(colName); }
151    }
152
153
154    // ********************************************************************************************
155    // ********************************************************************************************
156    // Simple Constructor
157    // ********************************************************************************************
158    // ********************************************************************************************
159
160
161    public SummaryTableHTML(
162            final TagNodeIndex              openingCinzelH3,
163            final Entity                    tableType,
164            final TagNodeIndex              tableOpen,
165            final TagNodeIndex              tableClose,
166            final JavaDocHTMLFile           jdhf,
167            final Vector<HTMLNode>          headerRow,
168            final Vector<Vector<HTMLNode>>  tableRows,
169            final Vector<ENTITY>            rowEntities,
170            final boolean                   retainRemoveDescriptions,
171            final int                       numColumnsInOriginalTable,
172            final ReadOnlyList<ColNames>    initialColumns,
173            final ReadOnlyList<ColNames>    postProcessedColumns
174        )
175    {
176        this.openingCinzelH3            = openingCinzelH3;
177        this.tableType                  = tableType;
178        this.tableOpen                  = tableOpen;
179        this.tableClose                 = tableClose;
180        this.jdhf                       = jdhf;
181        this.headerRow                  = headerRow;
182        this.tableRows                  = tableRows;
183        this.rowEntities                = rowEntities;
184        this.retainRemoveDescriptions   = retainRemoveDescriptions;
185        this.numColumnsInOriginalTable  = numColumnsInOriginalTable;
186        this.initialColumns             = initialColumns;
187        this.postProcessedColumns       = postProcessedColumns;
188    }
189
190
191    // ********************************************************************************************
192    // ********************************************************************************************
193    // The Main Fields of this Class.
194    // ********************************************************************************************
195    // ********************************************************************************************
196
197
198    /** Indicates what type of Summary-Table this is (Methods, Fields, Constructor's, etc). */
199    public final Entity tableType;
200
201    /** The opening {@code <TABLE>} tag, for a Summary-Section Table */
202    public final TagNodeIndex tableOpen;
203
204    /** The closing {@code </TABLE>} tag, for a Summary-Section Table */
205    public final TagNodeIndex tableClose;
206
207    /**
208     * This is just a <B>"Back-Pointer"</B> to the {@link JavaDocHTMLFile} that contains this
209     * Summary-Table
210     */
211    public final JavaDocHTMLFile jdhf;
212
213
214    // There is an *EXTENDED* explanation of this newly added field in the Constructor
215    // above - at the top of this class.  Added 03/2025 (March, during "Java One Conference")
216
217    /**
218     * This {@code final} / constant {@code boolean}-Flag is simply provided to indicate whether
219     * or not the Upgrader-Logic has removed the Summary-Description Setences from the Table-Rows 
220     * of this table.
221     * 
222     * <BR /><BR />The default behavior for this Upgrader-Tool is to remove all Summary-Sentences 
223     * for every type / kind of Entity-Summary Table on each Java-Doc Web-Page.  Note, though, 
224     * that this "Default Behavior" is easily by-passed by providing a simple {@code Predicate} to 
225     * the Upgrader-Tool's Configuration-Class {@link Upgrade#setSummaryRemoveFilter(Predicate)}.
226     * 
227     * <BR /><BR />It shall be "an eventuality" to provide a "Fine Grained Control" over this 
228     * removal Descision-Predicate so that a user may specify which Entity Summary-Tables retain 
229     * their Summary-Sentences, and which shall have them stripped or removed from their Web-Page 
230     * UI's.
231     * 
232     * <BR /><BR />As of March of 2025, this feature is not available yet.  Either <B>ALL</B> 
233     * Summary-Sentences must be removed from <B>EVERY</B> Summary-Table located at the top of 
234     * a Java-Doc Web-Page, <B STYLE='color: red;'><I>*OR*</I></B> none of them shall be removed.
235     * 
236     * <BR /><BR />Again, see the Configuration-Setting Method in class <B>{@link Upgrade}</B> to 
237     * read more about this feature:
238     * <B>{@link Upgrade#setSummaryRemoveFilter(Predicate) setSummaryRemoveFilter}</B>
239     */
240    public final boolean retainRemoveDescriptions;
241
242
243    // The Red Banner-H3, with Cinzel-Font that says "Method Summary" or "Field Summary"
244    // Package-Private *AND* final
245    //
246    // EXPORTED BY THE EXPORT_PORTAL, Used in: CSSTagsTopAndSumm
247
248    final TagNodeIndex openingCinzelH3;
249
250
251    // The First Row / Title Row of a Summary-Section Table
252    // Package-Private *AND* final
253    //
254    // EXPORTED BY THE EXPORT_PORTAL, Used in: CleanSummaries and RearrangeEntitySummaries
255
256    final Vector<HTMLNode> headerRow;
257
258
259    // The HTML Row's of every row in the table, except the initial header-row,
260    // and this is "Package-Visible".  There is a getter below.
261
262    private Vector<Vector<HTMLNode>> tableRows;
263
264
265    // The actual Reflection-Declaration for each of these rows.  For Inner-Classes the type
266    // parameter 'ENTITY' is String.  For the other 5 it is their 'Declaration' inheriting class.
267    // This is also Package-Visible only.
268
269    private Vector<ENTITY> rowEntities;
270
271
272    // At least in JDK-11, The **CONSTRUCTOR-TABLE** that was generated for the following classes,
273    // had the following number of columns:
274    // 
275    // * Torello.HTML.TagNode - 2 Columns (Signature & Description)
276    // * Torello.HTML.HTMLNode - 3 Columns (Modifier/Type, Signature & Description)
277
278    /**
279     * The following integer should be an accurate count on the **ORIGINAL** number of columns that
280     * were created by 'javadoc' when the original HTML-Table was output.  For every one of the 
281     * Summary-Tables, this is an easy computation, except, apparently for Constructors...
282     */
283    public final int numColumnsInOriginalTable;
284
285    /**
286     * The column names present in this Summary-HTML Table.  To view the JDK-Standard Columns 
287     * which are present in a Java-Doc Summary-Table, please review the contents of 
288     * <B><A HREF=#Col-Names-Table>this table</A></B>
289     */
290    public final ReadOnlyList<ColNames> initialColumns;
291
292    /**
293     * One of the commonly features of the Upgrader-Tool is to remove the Summary-Sentence 
294     * Description-Column from the Entities in a Java-Doc Web-Page.  When this occurs, the
295     * {@link ColNames#Description} column is removed.
296     * 
297     * <BR /><BR />When the {@code Description}-Column of a Summary-Table has been removed, this
298     * list will contain one fewer element than the contents of the list {@link #initialColumns}
299     */
300    public final ReadOnlyList<ColNames> postProcessedColumns;
301
302
303    // ********************************************************************************************
304    // ********************************************************************************************
305    // Table-Rows: Number of Rows
306    // ********************************************************************************************
307    // ********************************************************************************************
308
309
310    /**
311     * Retrieve the total number of Table-Rows in the Summary-Table.
312     * @return The number of HTML {@code <TR>...</TR>} elements in this Summary-Table
313     */
314    public int numRows() { return tableRows.size(); }
315
316    /**
317     * Retrieve the number of Table-Rows that have Title-Bars in this Summary-Table.
318     * @return The number of HTML {@code <TR>...</TR>} elements in this Summary-Table which contain
319     * Title-Bars, rather than entity/member signature URL-Links.
320     */
321    public int numTitleBarRows()
322    {
323        int counter = 0;
324        for (ENTITY e : rowEntities) if (e == null) counter++;
325        return counter;
326    }
327
328    /**
329     * Retrieve the number of Entity/Member Signatures which occupy a Table-Row in this
330     * Summary-Table
331     * @return The number of HTML {@code <TR>...</TR>} elements in this Summary-Table which contain
332     * entity/member signature URL-Links.
333     */
334    public int numSignatureRows()
335    {
336        int counter = 0;
337        for (ENTITY e : rowEntities) if (e != null) counter++;
338        return counter;
339    }
340
341    /**
342     * This method simply scans the internal {@code 'rowEntities'} list / {@code Vector} to check
343     * each element to determine if it contains one of the User-Provided descriptive orange-banner
344     * titles, or contains an actual Entity/Member {@code URL}-Link.
345     * 
346     * <BR /><BR />The members of a type are listed in enum {@link Entity}.  JavaDoc Upgrader
347     * refers to Class or Interface members as "Entities."  A Summary-Table on a Java-Doc Page -
348     * <I>after a Summary HTML Table Sort - will have some HTML Table-Rows with Members / Entities,
349     * and some Rows having orange-colored horizontal banner Title-Bars</I>.
350     * 
351     * <BR /><BR />When the HTML Table-Row ({@code '<TR> ... </TR>'}) has an {@code <A>-URL}
352     * link to one of the members of the class (a method, field, constructor, etc...), the returned
353     * array will contain {@code TRUE} for that index.  When the row contains a Title-Bar, the
354     * array-index for that row will contain {@code FALSE}.
355     * 
356     * @return A {@code boolean[]}-Array whose length is equal to the number of rows in this
357     * Summary-Table, and whose {@code boolean} values are {@code TRUE} if the Table-Row contains
358     * a {@code URL}-Link to one of the entities (Methods, Constructors, Fields, etc...) of the
359     * CIET / Type.
360     */
361    public boolean[] memberRows()
362    {
363        boolean[]   ret = new boolean[rowEntities.size()];
364        int         i   = 0;
365
366        for (ENTITY e : rowEntities) ret[i++] = (e != null);
367
368        return ret;
369    }
370
371
372    // ********************************************************************************************
373    // ********************************************************************************************
374    // Table-Rows: Getters by index / row number
375    // ********************************************************************************************
376    // ********************************************************************************************
377
378
379    /**
380     * If you have a chosen / desired HTML Summary-Table Row (with a selected summary
381     * element/item) - you may pass the table-row index of that item to retrieve the
382     * {@code rowIndex}<SUP>th</SUP> instance of {@link ReflHTML} that contains the
383     * Detail-Element Parsed-HTML corresponding to that row.
384     * 
385     * @param rowIndex Any one of the Summary-HTML Table-Rows.  Each Summary-Table Row is either a
386     * Title-Bar {@code <TR>} / Row, or it is a {@link Entity} / Member Table {@code <TR>} Row.  
387     * {@link Entity}-Rows are HTML {@code <TR>}-Rows that simply contain an Anchor {@code <A>} 
388     * link to one of this CIET's Members / Entites.
389     * 
390     * <BR /><BR />For example, if {@code 'this'} Summary-Table instance were for Method's, and the
391     * Table-Row index for the {@code 'toString()'} Method were passed to parameter
392     * {@code 'rowIndex'}, this method would return the {@link ReflHTML} for the {@code toString}
393     * Method.
394     * 
395     * <BR /><BR />The returned {@link ReflHTML} instance would contain all of the parsed
396     * HTML information for the method {@code toString}.
397     * 
398     * <BR /><BR />If this parameter points to a Table-Row that contains an Orange-Colored 
399     * Title-Bar (generated by the Summary-Sorters), rather than an Entity/Member Signature,
400     * then this method will return null.
401     * 
402     * @return The parsed detailed HTML explanation for the Summary-Table item chosen by parameter
403     * {@code 'rowIndex'}.
404     *
405     * <BR /><BR /><B STYLE='color: red;'>IMPORTANT:</B> When parameter {@code 'rowIndex'} is
406     * passed a value that <I>is not out of bounds for the {@code 'rowEntities'} vector</I>,
407     * but is a row that contains an orange Title-Bar, in such cases there is no detail-member
408     * (no instance of {@code ReflHTML}) to return.  When a {@code 'rowIndex'} for a Title-Bar
409     * row is passed, this method will return null, gracefully.
410     * 
411     * @throws IndexOutOfBoundsException If {@code rowIndex} is not properly chosen as per the
412     * number of rows in the table.  If there are {@code '10'} rows-items in this table, then the
413     * {@code rowIndex} parameter should be between {@code '0'} and {@code '9'}.
414     */
415    @SuppressWarnings("unchecked")  // NOTE: The cast on the 'return' line.  It *IS* checked
416                                    // but the compiler isn't smart enough to see that!
417    public ReflHTML<ENTITY> getRowDetail(int rowIndex)
418    {
419        // Look up the "rowIndex" row in the "rowEntities" vector which just contains the list of
420        // rows on this Summary HTML Table.  The "ENTITY" is one of the 5 reflected-HTML classes
421        // used by this package (Method, Field, Constructor etc...)
422
423        ENTITY selectedEntityMember = rowEntities.elementAt(rowIndex);
424
425        // Some rows contain only title information.  In such cases, there is no detail-element
426        // associated with this table-row.  It is just a title!!  When the user has passed a title
427        // row to parameter 'rowIndex', just return null.
428
429        if (selectedEntityMember == null) return null;
430
431        // Use JavaDocHTMLFile.findReflHTML(int, Class) to get the ReflHTML needed.
432        // NOTE: this.tableType.upgraderReflectionClass <==> ENTITY.class
433
434        return (ReflHTML<ENTITY>) jdhf.findReflHTML
435            (selectedEntityMember.id, this.tableType.upgraderReflectionClass);
436    }
437
438    /**
439     * Retrieve the {@code i}<SUP>th</SUP> HTML {@code <TR>} (row) from  {@code this} Summary-Table
440     * 
441     * <BR /><BR /><B CLASS=JDDescLabel>{@link Entity}-Member Rows:</B>
442     * 
443     * <BR />If {@code 'rowIndex'} is pointing to one of the entities / members of the class (such
444     * as a Field, Method or Constructor etc...), then the HTML {@code <A ...>} Anchor-{@code URL}
445     * for that {@link Entity} is returned.  The returned HTML-{@code Vector} will contain
446     * everything between the {@code <TR>} and the {@code </TR>} for that Table-Row.
447     * 
448     * <BR /><BR /><B CLASS=JDDescLabel>Title-Bar Rows:</B>
449     *  
450     * <BR />Not every row in a Summary-Table is guaranteed to have an Entity/Member Signature
451     * instance.  Bear in mind that whenever a user sorts Summary-Table Row's into Categories or
452     * Sections, then any &amp; all Section / Category Title-Bar Rows will be present in the
453     * Summary-Table HTML.
454     * 
455     * <BR /><BR />Title-Bar rows are the horizontal, fading-orange bars that line the Table of
456     * Contents (Summary-Tables).  These orange-colored banners have a brief, one-sentence
457     * description for a small group of methods, fields or constructors.
458     * 
459     * <BR /><BR />If parameter {@code 'rowIndex'} is pointing to a Title-Bar, then the parsed
460     * HTML-{@code Vector} for that Title-Bar is returned. 
461     * 
462     * <BR /><BR />In all other cases, the entity/member Signature is returned as a  result from a
463     * call to this method.
464     * 
465     * @param rowIndex The row number to retrieve
466     * @return All HTML between the {@code <TR>} and the {@code </TR>} for one table-summary row.
467     * 
468     * @throws IndexOutOfBoundsException If {@code 'rowIndex'} is not within the bounds of the list
469     * of rows
470     */
471    public Vector<HTMLNode> getRowHTML(int rowIndex)
472    { return tableRows.elementAt(rowIndex); }
473
474    /**
475     * Retrieve the {@code i}<SUP>th</SUP> entity.  The returned instance will be one of the six
476     * subclasses of class {@code Declaration}, as decided by the type-parameter {@code ENTITY}.
477     * 
478     * <BR /><BR /><B CLASS=JDDescLabel>{@link Entity}-Member Rows:</B>
479     * 
480     * <BR />If {@code 'rowIndex'} is pointing to one of the entities / members of the class (such
481     * as a Field, Method or Constructor etc...), then the reflected-class for that {@link Method},
482     * {@link Field}, {@link Constructor} is returned.  If {@code 'this'} Summary-Table has
483     * Generic-Type {@code SummaryTableHTML<Field>}, then the returned {@link ENTITY} will be a
484     * {@link Field} class instance.
485     * 
486     * <BR /><BR /><B CLASS=JDDescLabel>Title-Bar Rows:</B>
487     * 
488     * <BR />Not every row in a Summary-Table is guaranteed to have an Entity/Member Signature
489     * instance.  Bear in mind that whenever a user sorts Summary-Table Row's into Categories or
490     * Sections, then any &amp; all Section / Category Title-Bar Rows will be present in the
491     * Summary-Table HTML.
492     * 
493     * <BR /><BR />Title-Bar rows are the horizontal, fading-orange bars that line the Table of
494     * Contents (Summary-Tables).  These orange-colored banners have a brief, one-sentence
495     * description for a small group of methods, fields or constructors.
496     * 
497     * <BR /><BR />If parameter {@code 'rowIndex'} is pointing to a Title-Bar, <I>then this method
498     * shall default and return null!</I>
499     * 
500     * @param rowIndex The entity-number (row-number) to retrieve from {@code this} Summary-Table.
501     * 
502     * @return The refected-information for one Summary-Table row.
503     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
504     * 
505     * @throws IndexOutOfBoundsException If {@code 'rowIndex'} is not within the bounds of the list
506     * of rows
507     */
508    public ENTITY getRowEntity(int rowIndex)
509    { return rowEntities.elementAt(rowIndex); }
510
511
512    // ********************************************************************************************
513    // ********************************************************************************************
514    // Table-Rows: Getters by index / row number, USING Ret2's for more complete information.
515    // ********************************************************************************************
516    // ********************************************************************************************
517
518
519    /**
520     * Retrieve <B STYLE='color: red;'><I>both</I></B> the row-HTML
521     * <B STYLE='color: red;'><I>and</I></B> the reflected-entity information for the
522     * {@code i}<SUP>th</SUP> row in {@code this} Summary-Table.
523     * 
524     * <BR /><BR />Not every row in a Summary-Table is guaranteed to have a Member Signature.  
525     * When Summary-Table's are sorted into categories or sections, then a Summary-Table may also
526     * have a Title-Bar row.  It is (hopefully) obvious that a Title-Bar row would not contain an
527     * associated {@code 'ENTITY'} (Method, Field, Constructor, etc...).
528     * 
529     * @param rowIndex The entity-number / row-number to retrieve from {@code this} Summary-Table.
530     * 
531     * @return An instance of 
532     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_ENTITY_VEC>
533     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
534     * 
535     * @throws IndexOutOfBoundsException If {@code 'rowIndex'} is not within the bounds of the list
536     * of rows
537     */
538    public Ret2<ENTITY, Vector<HTMLNode>> getRowEntityAndHTML(int rowIndex)
539    { return new Ret2<>(rowEntities.elementAt(rowIndex), tableRows.elementAt(rowIndex)); }
540
541    /**
542     * Retrieve <B STYLE='color: red;'><I>both</I></B> the row-HTML
543     * <B STYLE='color: red;'><I>and</I></B> and the corresponding / matching instance of 
544     * {@link ReflHTML} for the {@code i}<SUP>th</SUP> row in {@code this} Summary-Table
545     * 
546     * <BR /><BR />Not every row in a Summary-Table is guaranteed to have a Member Signature.  
547     * When Summary-Table's are sorted into categories or sections, then a Summary-Table may also
548     * have a Title-Bar row.  It is (hopefully) obvious that a Title-Bar row would not contain an
549     * associated {@code 'ReflHTML'} HTML Data-Object either.
550     * 
551     * @param rowIndex The entity-number / row-number to retrieve from {@code this} Summary-Table.
552     * 
553     * @return An instance of 
554     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_REFL_VEC>
555     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
556     * 
557     * @throws IndexOutOfBoundsException If {@code i} is not within the bounds of the list of rows
558     * @see #getRowDetail(int)
559     */
560    public Ret2<ReflHTML<ENTITY>, Vector<HTMLNode>> getRowDetailAndHTML(int rowIndex)
561    { return new Ret2<>(getRowDetail(rowIndex), tableRows.elementAt(rowIndex)); }
562
563
564    // ********************************************************************************************
565    // ********************************************************************************************
566    // Table-Rows: Stream's
567    // ********************************************************************************************
568    // ********************************************************************************************
569
570
571    /**
572     * A {@code Stream} that contains {@code this} Summary-Table's rows, as Vectorized-HTML
573     *
574     * @return A stream of Vectorized-HTML Table-Rows for {@code this} Summary-Table.
575     *
576     * <BR /><BR />Note that a Java {@code Stream} is easily converted into just about any
577     * necessary data-type, as explained in the table below:
578     *
579     * <EMBED CLASS='external-html' DATA-FILE-ID=STREAM_CONVERT_T>
580     */
581    public Stream<Vector<HTMLNode>> rowHTMLStream() { return tableRows.stream(); }
582
583    /**
584     * A {@code Stream} that contains all Summary-Table row-entities, as instances of the reflected
585     * information class {@code ENTITY} (this class' sole type-parameter).
586     * 
587     * <BR /><BR />Generic Type-Parameter {@code ENTITY} will be one of the six concrete subclasses
588     * of class {@link Declaration}.
589     * 
590     * @return A stream of entities contained by {@code this} Summary-Table.
591     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
592     *
593     * <BR /><BR />Note that a Java {@code Stream} is easily converted into just about any
594     * necessary data-type, as explained in the table below:
595     *
596     * <EMBED CLASS='external-html' DATA-FILE-ID=STREAM_CONVERT_T>
597     */
598    public Stream<ENTITY> rowEntityStream() { return rowEntities.stream(); }
599
600
601    // ********************************************************************************************
602    // ********************************************************************************************
603    // Table-Rows: Entire Table
604    // ********************************************************************************************
605    // ********************************************************************************************
606
607
608    /**
609     * Retrieve a {@code Stream} that contains <B><I>every</I></B> Summary-Table Row.
610     * 
611     * <BR /><BR />The specific contents of this {@code Stream} are instances of {@link Ret2},
612     * which contain <B STYLE='color: red;'><I>both</I></B> the reflected-entity information
613     * (instance of Type-Parameter {@code ENTITY}) <B STYLE='color: red;'><I>and</I></B> the
614     * Vectorized-HTML Table-Row, as well.
615     * 
616     * @return A Java Stream containing instances of 
617     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_ENTITY_VEC>
618     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
619     */
620    public Stream<Ret2<ENTITY, Vector<HTMLNode>>> entityAndHTMLStream()
621    {
622        final Stream.Builder<Ret2<ENTITY, Vector<HTMLNode>>> b = Stream.builder();
623
624        for (int rowIndex=0; rowIndex < rowEntities.size(); rowIndex++)
625            b.accept(new Ret2<>(rowEntities.elementAt(rowIndex), tableRows.elementAt(rowIndex)));
626
627        return b.build();
628    }
629
630    /**
631     * Retrieve the entire list of Table-Rows in this HTML Summary-Table into a {@code Vector}.
632     * 
633     * @return A Java Stream containing instances of 
634     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_REFL_VEC>
635     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
636     */
637    public Stream<Ret2<ReflHTML<ENTITY>, Vector<HTMLNode>>> reflAndHTMLStream()
638    {
639        final Stream.Builder<Ret2<ReflHTML<ENTITY>, Vector<HTMLNode>>> b = Stream.builder();
640
641        for (int rowIndex=0; rowIndex < rowEntities.size(); rowIndex++)
642            b.accept(new Ret2<>(getRowDetail(rowIndex), tableRows.elementAt(rowIndex)));
643
644        return b.build();
645    }
646
647
648    // ********************************************************************************************
649    // ********************************************************************************************
650    // Table-Rows: FIND-METHODS
651    // ********************************************************************************************
652    // ********************************************************************************************
653
654
655    private void CHECK_IS_CALLABLE()
656    {
657        if (this.tableType.isCallable()) return;
658
659        final String kind = this.tableType.upgraderReflectionClass.getSimpleName();
660
661        throw new UpgradeException(
662            "This 'find' method may only be used on SummaryTableHTML instances for Method or " +
663                "Constructor Summary Tables.\n" +
664            "This is a SummaryTableHTML<" + kind + "> instance, and this find method may not be " +
665                "used.\n" +
666            "CIET/Type Member Names for " + kind + "'s cannot be overloaded, so therefore you " +
667                "should use the simple/standard find(String) method instead."
668        );
669    }
670
671    private void CHECK_NUM_PARAMS(final int numParams)
672    {
673        if (numParams < 1) throw new IllegalArgumentException(
674            "This find method will only search for Callable's (Method's and Constructor's) that" +
675            "accept at least 1 parameter.  You have passed [" + numParams + "] to parameter " +
676            "'numParams'.  This is not allowed." +
677            ((numParams == 0)
678                ? "\nWhen searching for a zero-argument Callable, use " +
679                    "SummaryTableHTML.find(String)"
680                : "")
681        );
682    }
683
684    /**
685     * Retrieves the first Entity/Member whose name matches {@code name}.  When searching a
686     * {@code SummaryTableHTML<Field>}, {@code SummaryTableHTML<EnumConstant>} or 
687     * {@code SummaryTableHTML<AnnotationElem>}, the name of the entity/member will uniquely
688     * identify it amongst the others in the table.
689     * 
690     * <BR /><BR />Due to Java's function overloading, there may be many cases where a
691     * member {@code 'name'} is not sufficient to uniquely identify it (for Method's and 
692     * Constructor's).  In such cases (e.g. overloaded methods) this method simply return the index
693     * of the first match it finds.
694     * 
695     * @param name The name of the entity / member, as a {@code java.lang.String}
696     * 
697     * @return The index of the (first) HTML Table-Row that contains the specified {@link Entity}.
698     * If this Summary-Table does not have any member-signatures by that {@code 'name'}, then
699     * {@code -1} will be returned.
700     */
701    public int find(String name)
702    {
703        ENTITY e = null;
704
705        for (int i=0; i < rowEntities.size(); i++)
706
707            // After a sort, all Title-Rows have null Row-Entity elements
708            // Make sure to skip any row completely if it is a Title-Row
709
710            if ((e = rowEntities.elementAt(i)) != null)
711                if (e.name.equals(name))
712                    return i;
713
714        return -1;
715    }
716
717    /**
718     * Retrieves the first Entity/Member whose name matches {@code 'methodOrCtorName'}.
719     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
720     * 
721     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
722     * 
723     * @return The index of the first HTML Table-Row that matches this specified name.  If this
724     * Summary-Table does not have any (Method or Constructor) Member-Signatures by that name,
725     * then {@code -1} is returned.
726     */
727    public int findFirst(String methodOrCtorName)
728    {
729        CHECK_IS_CALLABLE();
730
731        ENTITY e = null;
732
733        for (int i=0; i < rowEntities.size(); i++)
734
735            // After a sort, all Title-Rows have null Row-Entity elements
736            // Make sure to skip any row completely if it is a Title-Row
737
738            if ((e = rowEntities.elementAt(i)) != null)
739                if (e.name.equals(methodOrCtorName))
740                    return i;
741
742        return -1;
743    }
744
745    /**
746     * Retrieves the first Entity/Member whose name matches {@code 'methodOrCtorName'}, 
747     * and accepts {@code 'numParams'} parameters.
748     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
749     * 
750     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
751     * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=ST_IAEX>
752     * 
753     * @return The index of the first HTML Table-Row that matches the provided specifications.  If
754     * this Summary-Table does not have any Member-Signatures with that name and accepting the
755     * specified number of parameters, then this method returns {@code -1}.
756     */
757    public int findFirst(String methodOrCtorName, int numParams)
758    {
759        CHECK_IS_CALLABLE();
760        CHECK_NUM_PARAMS(numParams);
761
762        for (int i=0; i < rowEntities.size(); i++)
763        {
764            final ENTITY e = rowEntities.elementAt(i);
765
766            // After a sort, all Title-Rows have null Row-Entity elements
767            // Make sure to skip any row completely if it is a Title-Row
768
769            if (e == null) continue;
770
771            if (e.name.equals(methodOrCtorName))
772                if (((Callable) e).numParameters() == numParams)
773                    return i;
774        }
775
776        return -1;
777    }
778
779    /**
780     * Retrieves all Entities/Member Table-Row Indices whose name matches
781     * {@code 'methodOrCtorName'}.
782     * 
783     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
784     * 
785     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
786     * 
787     * @return <EMBED CLASS='external-html' DATA-FILE-ID=ST_FIND_ALL_RET>
788     * 
789     * <DIV CLASS=EXAMPLE>{@code
790     * int[] tableRows = methodSummTable.findAll("someMethodName").toArray();
791     * }</DIV>
792     */
793    public IntStream findAll(String methodOrCtorName)
794    {
795        CHECK_IS_CALLABLE();
796
797        final IntStream.Builder b = IntStream.builder();
798
799        ENTITY e = null;
800
801        for (int i=0; i < rowEntities.size(); i++)
802
803            // After a sort, all Title-Rows have null Row-Entity elements
804            // Make sure to skip any row completely if it is a Title-Row
805
806            if ((e = rowEntities.elementAt(i)) != null)
807                if (e.name.equals(methodOrCtorName))
808                    b.accept(i);
809
810        return b.build();
811    }
812
813    /**
814     * Retrieves the first Entity/Member Table-Row Index whose name matches
815     * {@code 'methodOrCtorName'},  and accepts {@code 'numParams'} parameters.
816     * 
817     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
818     * 
819     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
820     * @param numParams <EMBED CLASS='external-html' DATA-FILE-ID=ST_NUM_PARAMS>
821     * 
822     * @return <EMBED CLASS='external-html' DATA-FILE-ID=ST_FIND_ALL_RET>
823     * 
824     * <DIV CLASS=EXAMPLE>{@code
825     * int[] tableRows = methodSummTable.findAll("someMethodName", 1).toArray();
826     * }</DIV>
827     * 
828     * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=ST_IAEX>
829     */
830    public IntStream findAll(String methodOrCtorName, int numParams)
831    {
832        CHECK_IS_CALLABLE();
833        CHECK_NUM_PARAMS(numParams);
834
835        final IntStream.Builder b = IntStream.builder();
836
837        for (int i=0; i < rowEntities.size(); i++)
838        {
839            final ENTITY e = rowEntities.elementAt(i);
840
841            // After a sort, all Title-Rows have null Row-Entity elements
842            // Make sure to skip any row completely if it is a Title-Row
843
844            if (e == null) continue;
845
846            if (e.name.equals(methodOrCtorName))
847                if (((Callable) e).numParameters() == numParams)
848                    b.accept(i);
849        }
850
851        return b.build();
852    }
853
854
855    // ********************************************************************************************
856    // ********************************************************************************************
857    // Package-Private Stuff
858    // ********************************************************************************************
859    // ********************************************************************************************
860
861
862    // Package-Private: Only used in RearrangeEntitySummaries
863    // EXPORTED BY THE EXPORT_PORTAL
864
865    void setTableRows(Vector<Vector<HTMLNode>> tableRows, Vector<ENTITY> rowEntities)
866    {
867        this.tableRows      = tableRows;
868        this.rowEntities    = rowEntities;
869    }
870
871
872    // ********************************************************************************************
873    // ********************************************************************************************
874    // REBUILD THE JAVADOC PAGE
875    // ********************************************************************************************
876    // ********************************************************************************************
877
878
879    // Used in the method below
880    private static final TextNode NEW_LINE = new TextNode("\n");
881
882    // Method below too
883    private static final Vector<Replaceable> EMPTY_VECTOR = new Vector<>();
884
885    Vector<Replaceable> allReplaceables()
886    {
887        // There are summary-tables whose only contents are the "Inherited Entities".  When that
888        // occurs, the 'tableOpen' and 'tableClose' NodeIndex-instances will be null.
889        //
890        // You still need to add the "Cinzel-H3" to the Banner that says "Method Summary" or
891        // "Field Summary" (or whichever SummaryTable this is).  So, in this case, return a Vector
892        // whose only contents are the TagNodeIndex Cinzel-H3 node.
893
894        if (tableOpen == null)
895        {
896            Vector<Replaceable> cinzelOnlyVec = new Vector<>();
897            cinzelOnlyVec.add(this.openingCinzelH3);
898            return cinzelOnlyVec;
899        }
900
901        final Vector<HTMLNode>  newTable            = new Vector<>();
902        final DotPair           oldTableLocation    = new DotPair(tableOpen.index, tableClose.index);
903
904        newTable.add(tableOpen.n);
905        newTable.add(NEW_LINE);
906        newTable.addAll(headerRow);
907        newTable.add(NEW_LINE);
908
909        for (Vector<HTMLNode> row : tableRows)
910        {
911            newTable.addAll(row);
912            newTable.add(NEW_LINE);
913        }
914
915        newTable.add(tableClose.n);
916        newTable.add(NEW_LINE);
917
918        final Vector<Replaceable> ret = new Vector<>();
919        ret.add(openingCinzelH3);
920        ret.add(Replaceable.create(oldTableLocation, newTable));
921
922        return ret;
923    }
924
925
926    // ********************************************************************************************
927    // ********************************************************************************************
928    // THE NEW-THING: Garbage-Collector Helper?
929    // ********************************************************************************************
930    // ********************************************************************************************
931    // 
932    // Does this help?  Is this "good" for the Garbage-Collect?  Is this going to speed it up,
933    // or slow it down?  This is just a "C-Styled" FREE or DESTORY method...
934    // It isn't publicly visible anyway...
935
936    void clear()
937    {
938        // public final TagNodeIndex tableOpen;
939        if (tableOpen != null) tableOpen.n = null;
940
941        // public final TagNodeIndex tableClose;
942        if (tableClose != null) tableClose.n = null;
943    
944        // final Vector<HTMLNode> headerRow;
945        if (headerRow != null) headerRow.clear();
946
947        // final TagNodeIndex openingCinzelH3;
948        if (openingCinzelH3 != null) openingCinzelH3.n = null;
949    
950        // private Vector<Vector<HTMLNode>> tableRows = new Vector<>();
951        if (tableRows != null)
952        {
953            for (Vector<HTMLNode> v : tableRows) if (v != null) v.clear();
954
955            tableRows.clear();
956            tableRows = null;
957        }
958    
959        // private Vector<ENTITY> rowEntities = new Vector<>();
960        if (rowEntities != null) { rowEntities.clear(); rowEntities = null; }
961    }
962
963
964    // ********************************************************************************************
965    // ********************************************************************************************
966    // DEBUG-PRINTING
967    // ********************************************************************************************
968    // ********************************************************************************************
969
970
971    private static final String STARS =
972        BYELLOW + "\n*****************************************\n" + RESET;
973
974    /**
975     * Prints an abbreviated-version of the contents of this instance, to a user-provided
976     * {@code Appendable}.  If the HTML requires more than four lines of text, only the first four
977     * lines are printed.
978     * 
979     * @param a This may be any Java Appendable.  If an {@code IOException} is thrown while writing
980     * to this {@code Appendable}, it will be caught an wrapped in an
981     * {@code IllegalArgumentException}, with the {@code IOException} set as the {@code cause}.
982     * 
983     * @throws IllegalArgumentException If {@code 'a'} throws an {@code IOException}
984     * 
985     * @see StrPrint#firstNLines(String, int)
986     * @see Util#pageToString(Vector)
987     * @see StrIndent#indent(String, int)
988     */
989    public void debugPrint(Appendable a)
990    {
991        try
992        {
993            if (tableType != null) a.append
994                (BCYAN + "this.tableType: " + RESET + this.tableType.toString() + "\n");
995            else
996                a.append(BRED + "this.tableType is null" + RESET);
997
998            if (tableOpen != null) a.append
999                (BCYAN + "this.tableOpen: " + RESET + this.tableOpen.n.str + "\n");
1000            else
1001                a.append(BRED + "this.tableOpen is null" + RESET);
1002
1003            if (tableClose != null) a.append
1004                (BCYAN + "this.tableClose: " + RESET + this.tableClose.n.str + "\n");
1005            else
1006                a.append(BRED + "this.tableClose is null" + RESET);
1007
1008            if (openingCinzelH3 != null) a.append
1009                (BCYAN + "this.openingCinzelH3: " + RESET + this.openingCinzelH3.n.str + "\n");
1010            else
1011                a.append(BRED + "this.openingCinzelH3 is null" + RESET);
1012
1013            if (headerRow != null) a.append(
1014                STARS + BCYAN + "this.headerRow:" + RESET + STARS +
1015                StrPrint.firstNLines(Util.pageToString(headerRow), 4) +
1016                '\n'
1017            );
1018
1019            for (int i=0; i < tableRows.size(); i++)
1020
1021                a.append(
1022                    BCYAN + "TABLE ROW " + (i+1) + RESET + '\n' +
1023                    BGREEN + "HTML:\n" + RESET +
1024                    StrIndent.indent
1025                        (Util.pageToString(tableRows.elementAt(i)).replace("\n", "\\n"), 4) +
1026                    '\n' +
1027                    BGREEN + "ENTITY:\n" + RESET +
1028                    StrIndent.indent
1029                        (rowEntities.elementAt(i).toString(PF.UNIX_COLORS | PF.JOW_INSTEAD), 4) +
1030                    '\n'
1031                );
1032        }
1033
1034        catch (java.io.IOException ioe)
1035        {
1036            throw new IllegalArgumentException(
1037                ioe
1038            );
1039        }
1040    }
1041
1042    
1043    /**
1044     * A really great way to view the contents of this class - <I>in just one page of text</I>.
1045     * 
1046     * @param numCharsWide The maximum line width to be printed to terminal.  This
1047     * number must be between 60 and 150, or else an exception shall throw.
1048     * 
1049     * @return The contents of this class-instance, as a {@code String}
1050     * 
1051     * @throws IllegalArgumentException If the parameter 'numCharsWide' was not passed a value 
1052     * within the aforementioned range.
1053     * 
1054     * @see StrPrint#printListAbbrev(Iterable, int, int, boolean, boolean, boolean)
1055     * @see StrPrint#printListAbbrev(Iterable, IntTFunction, int, int, boolean, boolean, boolean)
1056     */
1057    public String debugPrintDense(final int numCharsWide)
1058    {
1059        if ((numCharsWide < 60) || (numCharsWide > 150)) throw new IllegalArgumentException
1060            ("Parameter 'numCharsWide' wasn't passed a value between 60 and 150: " + numCharsWide);
1061
1062        return
1063            "rowEntities.size(): " + rowEntities.size() + '\n' +
1064            "rowEntities Vector Contents:" + // '\n' is automatically added
1065                StrPrint.printListAbbrev(rowEntities, numCharsWide, 4, false, true, true) + '\n' +
1066            "tableRows.size(): " + tableRows.size() + '\n' +
1067            "tableRows Vector Contents:" + // '\n' is automatically added
1068                StrPrint.printListAbbrev(
1069                    tableRows,
1070                    (int i, Vector<HTMLNode> tableRow) -> Util.pageToString(tableRow),
1071                    numCharsWide, 4, false, true, true
1072                );
1073    }
1074
1075    /**
1076     * Converts the contents of this class into a {@code String}
1077     * @return A Printable-{@code String}
1078     * @see #debugPrintDense(int)
1079     */
1080    public String toString()
1081    {
1082        final String oStr = (this.tableOpen == null)
1083            ? "null"
1084            : this.tableOpen.toString();
1085
1086        final String cStr = (this.tableClose == null)
1087            ? "null"
1088            : this.tableClose.toString();
1089
1090        final String hStr = (this.headerRow == null)
1091            ? "null"
1092            : StrPrint.abbrevEndRDSF(Util.pageToString(headerRow), 120, false);
1093
1094        return
1095            "tableType:  " + tableType + '\n' +
1096            "tableOpen:  " + oStr + '\n' +
1097            "tableClose: " + cStr + '\n' +
1098            "headerRow:  " + hStr + '\n' +
1099            debugPrintDense(120);
1100    }
1101}