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