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.GeneralPurpose.Messager;
011
012import Torello.JDUInternal.ParseHTML.SignatureParse;
013import Torello.JDUInternal.ParseJavaSource.JavaSourceCodeFile;
014
015import java.util.*;
016import java.util.stream.*;
017
018import java.util.function.Function;
019
020/**
021 * This class stores the HTML for a Summary-Table - which is the table at the top of a Java Doc
022 * Page listing all of one type of entities present in the CIET/Type.  
023 * 
024 * <EMBED CLASS='external-html' DATA-FILE-ID=PROG_MOD_HTML>
025 * <EMBED CLASS='external-html' DATA-FILE-ID=SUMM_TABLE_HTML>
026 * 
027 * @param <ENTITY> This will take one of six type's: {@link Method}, {@link Constructor},
028 * {@link Field}, {@link EnumConstant}, {@link AnnotationElem} or {@link NestedType}.   The HTML
029 * contained by this class correspond directly to the HTML contained by a Summary-Table of one of
030 * section of one of these Entities / Members.
031 */
032@JDHeaderBackgroundImg(EmbedTagFileID="REFLECTION_HTML_CLASS")
033public class SummaryTableHTML<ENTITY extends Declaration>
034{
035    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
036    protected static final long serialVersionUID = 1;
037
038
039    // ********************************************************************************************
040    // ********************************************************************************************
041    // Main CommentNode Marker's for Finding Summaries (Formerly of class "Summaries.java")
042    // ********************************************************************************************
043    // ********************************************************************************************
044
045
046    // Copied from the now-legacy class Summaries
047    private static final String[] MARKERS =
048    {
049        // public static final String JAVADOC_CONSTRUCTOR_SUMMARY_MARKER =
050        "==== CONSTRUCTOR SUMMARY ====",
051
052        // private static final String JAVADOC_FIELD_SUMMARY_MARKER =
053        "==== FIELD SUMMARY ====",
054
055        // public static final String JAVADOC_METHOD_SUMMARY_MARKER =
056        "==== METHOD SUMMARY ====",
057
058        // public static final String JAVADOC_NESTED_CLASS_SUMMARY_MARKER =
059        "==== NESTED CLASS SUMMARY ====",
060
061        // public static final String JAVADOC_ENUM_CONST_SUMMARY_MARKER =
062        "==== ENUM CONSTANT SUMMARY ====",
063
064        // public static final String JAVADOC_OPTIONAL_ANNOTATION_ELEMENT_SUMMARY_MARKER =
065        "==== ANNOTATION TYPE OPTIONAL MEMBER SUMMARY ====",
066
067        // public static final String JAVADOC_REQUIRED_ANNOTATION_ELEMENT_SUMMARY_MARKER =
068        "==== ANNOTATION TYPE REQUIRED MEMBER SUMMARY ===="
069    };
070
071
072    // ********************************************************************************************
073    // ********************************************************************************************
074    // The Main Fields of this Class.
075    // ********************************************************************************************
076    // ********************************************************************************************
077
078
079    /** Indicates what type of Summary-Table this is (Methods, Fields, Constructor's, etc). */
080    public final Entity tableType;
081
082    /** The opening {@code <TABLE>} tag, for a Summary-Section Table */
083    public final TagNodeIndex tableOpen;
084
085    /** The closing {@code </TABLE>} tag, for a Summary-Section Table */
086    public final TagNodeIndex tableClose;
087
088    // The First Row / Title Row of a Summary-Section Table
089    // Package-Private *AND* final
090    //
091    // EXPORTED BY THE EXPORT_PORTAL, Used in: CleanSummaries and RearrangeEntitySummaries
092
093    final Vector<HTMLNode> headerRow;
094
095    // The Red Banner-H3, with Cinzel-Font that says "Method Summary" or "Field Summary"
096    // Package-Private *AND* final
097    //
098    // EXPORTED BY THE EXPORT_PORTAL, Used in: CSSTagsTopAndSumm
099
100    final TagNodeIndex cinzelH3;
101
102    // The HTML Row's of every row in the table, except the initial header-row,
103    // and this is "Package-Visible".  There is a getter below.
104
105    private Vector<Vector<HTMLNode>> tableRows = new Vector<>();
106
107    // The actual Reflection-Declaration for each of these rows.  For Inner-Classes the type
108    // parameter 'ENTITY' is String.  For the other 5 it is their 'Declaration' inheriting class.
109    // This is also Package-Visible only.
110
111    private Vector<ENTITY> rowEntities = new Vector<>();
112
113    // back-pointer to the JavaDocHTMLFile that contained this Summary-Table
114    private final JavaDocHTMLFile jdhf;
115
116
117    // ********************************************************************************************
118    // ********************************************************************************************
119    // Table-Rows: Number of Rows
120    // ********************************************************************************************
121    // ********************************************************************************************
122
123
124    /**
125     * Retrieve the total number of Table-Rows in the Summary-Table.
126     * @return The number of HTML {@code <TR>...</TR>} elements in this Summary-Table
127     */
128    public int numRows() { return tableRows.size(); }
129
130    /**
131     * Retrieve the number of Table-Rows that have Title-Bars in this Summary-Table.
132     * @return The number of HTML {@code <TR>...</TR>} elements in this Summary-Table which contain
133     * Title-Bars, rather than entity/member signature URL-Links.
134     */
135    public int numTitleBarRows()
136    {
137        int counter = 0;
138        for (ENTITY e : rowEntities) if (e == null) counter++;
139        return counter;
140    }
141
142    /**
143     * Retrieve the number of Entity/Member Signatures which occupy a Table-Row in this
144     * Summary-Table
145     * @return The number of HTML {@code <TR>...</TR>} elements in this Summary-Table which contain
146     * entity/member signature URL-Links.
147     */
148    public int numSignatureRows()
149    {
150        int counter = 0;
151        for (ENTITY e : rowEntities) if (e != null) counter++;
152        return counter;
153    }
154
155    /**
156     * This method simply scans the internal {@code 'rowEntities'} list / {@code Vector} to check
157     * each element to determine if it contains one of the User-Provided descriptive orange-banner
158     * titles, or contains an actual Entity/Member {@code URL}-Link.
159     * 
160     * <BR /><BR />The members of a type are listed in enum {@link Entity}.  JavaDoc Upgrader
161     * refers to Class or Interface members as "Entities."  A Summary-Table on a Java-Doc Page -
162     * <I>after a Summary HTML Table Sort - will have some HTML Table-Rows with Members / Entities,
163     * and some Rows having orange-colored horizontal banner Title-Bars</I>.
164     * 
165     * <BR /><BR />When the HTML Table-Row ({@code '<TR> ... </TR>'}) has an {@code <A>-URL}
166     * link to one of the members of the class (a method, field, constructor, etc...), the returned
167     * array will contain {@code TRUE} for that index.  When the row contains a Title-Bar, the
168     * array-index for that row will contain {@code FALSE}.
169     * 
170     * @return A {@code boolean[]}-Array whose length is equal to the number of rows in this
171     * Summary-Table, and whose {@code boolean} values are {@code TRUE} if the Table-Row contains
172     * a {@code URL}-Link to one of the entities (Methods, Constructors, Fields, etc...) of the
173     * CIET / Type.
174     */
175    public boolean[] memberRows()
176    {
177        boolean[]   ret = new boolean[rowEntities.size()];
178        int         i   = 0;
179
180        for (ENTITY e : rowEntities) ret[i++] = (e != null);
181
182        return ret;
183    }
184
185
186    // ********************************************************************************************
187    // ********************************************************************************************
188    // Table-Rows: Getters by index / row number
189    // ********************************************************************************************
190    // ********************************************************************************************
191
192
193    /**
194     * If you have a chosen / desired HTML Summary-Table Row (with a selected summary
195     * element/item) - you may pass the table-row index of that item to retrieve the
196     * {@code rowIndex}<SUP>th</SUP> instance of {@link ReflHTML} that contains the
197     * Detail-Element Parsed-HTML corresponding to that row.
198     * 
199     * @param rowIndex Any one of the Summary-HTML Table-Rows.  Each Summary-Table Row is either a
200     * Title-Bar {@code <TR>} / Row, or it is a {@link Entity} / Member Table {@code <TR>} Row.  
201     * {@link Entity}-Rows are HTML {@code <TR>}-Rows that simply contain an Anchor {@code <A>} 
202     * link to one of this CIET's Members / Entites.
203     * 
204     * <BR /><BR />For example, if {@code 'this'} Summary-Table instance were for Method's, and the
205     * Table-Row index for the {@code 'toString()'} Method were passed to parameter
206     * {@code 'rowIndex'}, this method would return the {@link ReflHTML} for the {@code toString}
207     * Method.
208     * 
209     * <BR /><BR />The returned {@link ReflHTML} instance would contain all of the parsed
210     * HTML information for the method {@code toString}.
211     * 
212     * <BR /><BR />If this parameter points to a Table-Row that contains an Orange-Colored 
213     * Title-Bar (generated by the Summary-Sorters), rather than an Entity/Member Signature,
214     * then this method will return null.
215     * 
216     * @return The parsed detailed HTML explanation for the Summary-Table item chosen by parameter
217     * {@code 'rowIndex'}.
218     *
219     * <BR /><BR /><B STYLE='color: red;'>IMPORTANT:</B> When parameter {@code 'rowIndex'} is
220     * passed a value that <I>is not out of bounds for the {@code 'rowEntities'} vector</I>,
221     * but is a row that contains an orange Title-Bar, in such cases there is no detail-member
222     * (no instance of {@code ReflHTML}) to return.  When a {@code 'rowIndex'} for a Title-Bar
223     * row is passed, this method will return null, gracefully.
224     * 
225     * @throws IndexOutOfBoundsException If {@code rowIndex} is not properly chosen as per the
226     * number of rows in the table.  If there are {@code '10'} rows-items in this table, then the
227     * {@code rowIndex} parameter should be between {@code '0'} and {@code '9'}.
228     */
229    @SuppressWarnings("unchecked")  // NOTE: The cast on the 'return' line.  It *IS* checked
230                                    // but the compiler isn't smart enough to see that!
231    public ReflHTML<ENTITY> getRowDetail(int rowIndex)
232    {
233        // Look up the "rowIndex" row in the "rowEntities" vector which just contains the list of
234        // rows on this Summary HTML Table.  The "ENTITY" is one of the 5 reflected-HTML classes
235        // used by this package (Method, Field, Constructor etc...)
236
237        ENTITY selectedEntityMember = rowEntities.elementAt(rowIndex);
238
239        // Some rows contain only title information.  In such cases, there is no detail-element
240        // associated with this table-row.  It is just a title!!  When the user has passed a title
241        // row to parameter 'rowIndex', just return null.
242
243        if (selectedEntityMember == null) return null;
244
245        // Use JavaDocHTMLFile.findReflHTML(int, Class) to get the ReflHTML needed.
246        // NOTE: this.tableType.upgraderReflectionClass <==> ENTITY.class
247
248        return (ReflHTML<ENTITY>) jdhf.findReflHTML
249            (selectedEntityMember.id, this.tableType.upgraderReflectionClass);
250    }
251
252    /**
253     * Retrieve the {@code i}<SUP>th</SUP> HTML {@code <TR>} (row) from  {@code this} Summary-Table
254     * 
255     * <BR /><BR /><B CLASS=JDDescLabel>{@link Entity}-Member Rows:</B>
256     * 
257     * <BR />If {@code 'rowIndex'} is pointing to one of the entities / members of the class (such
258     * as a Field, Method or Constructor etc...), then the HTML {@code <A ...>} Anchor-{@code URL}
259     * for that {@link Entity} is returned.  The returned HTML-{@code Vector} will contain
260     * everything between the {@code <TR>} and the {@code </TR>} for that Table-Row.
261     * 
262     * <BR /><BR /><B CLASS=JDDescLabel>Title-Bar Rows:</B>
263     *  
264     * <BR />Not every row in a Summary-Table is guaranteed to have an Entity/Member Signature
265     * instance.  Bear in mind that whenever a user sorts Summary-Table Row's into Categories or
266     * Sections, then any &amp; all Section / Category Title-Bar Rows will be present in the
267     * Summary-Table HTML.
268     * 
269     * <BR /><BR />Title-Bar rows are the horizontal, fading-orange bars that line the Table of
270     * Contents (Summary-Tables).  These orange-colored banners have a brief, one-sentence
271     * description for a small group of methods, fields or constructors.
272     * 
273     * <BR /><BR />If parameter {@code 'rowIndex'} is pointing to a Title-Bar, then the parsed
274     * HTML-{@code Vector} for that Title-Bar is returned. 
275     * 
276     * <BR /><BR />In all other cases, the entity/member Signature is returned as a  result from a
277     * call to this method.
278     * 
279     * @param rowIndex The row number to retrieve
280     * @return All HTML between the {@code <TR>} and the {@code </TR>} for one table-summary row.
281     * 
282     * @throws IndexOutOfBoundsException If {@code 'rowIndex'} is not within the bounds of the list
283     * of rows
284     */
285    public Vector<HTMLNode> getRowHTML(int rowIndex)
286    { return tableRows.elementAt(rowIndex); }
287
288    /**
289     * Retrieve the {@code i}<SUP>th</SUP> entity.  The returned instance will be one of the six
290     * subclasses of class {@code Declaration}, as decided by the type-parameter {@code ENTITY}.
291     * 
292     * <BR /><BR /><B CLASS=JDDescLabel>{@link Entity}-Member Rows:</B>
293     * 
294     * <BR />If {@code 'rowIndex'} is pointing to one of the entities / members of the class (such
295     * as a Field, Method or Constructor etc...), then the reflected-class for that {@link Method},
296     * {@link Field}, {@link Constructor} is returned.  If {@code 'this'} Summary-Table has
297     * Generic-Type {@code SummaryTableHTML<Field>}, then the returned {@link ENTITY} will be a
298     * {@link Field} class instance.
299     * 
300     * <BR /><BR /><B CLASS=JDDescLabel>Title-Bar Rows:</B>
301     * 
302     * <BR />Not every row in a Summary-Table is guaranteed to have an Entity/Member Signature
303     * instance.  Bear in mind that whenever a user sorts Summary-Table Row's into Categories or
304     * Sections, then any &amp; all Section / Category Title-Bar Rows will be present in the
305     * Summary-Table HTML.
306     * 
307     * <BR /><BR />Title-Bar rows are the horizontal, fading-orange bars that line the Table of
308     * Contents (Summary-Tables).  These orange-colored banners have a brief, one-sentence
309     * description for a small group of methods, fields or constructors.
310     * 
311     * <BR /><BR />If parameter {@code 'rowIndex'} is pointing to a Title-Bar, <I>then this method
312     * shall default and return null!</I>
313     * 
314     * @param rowIndex The entity-number (row-number) to retrieve from {@code this} Summary-Table.
315     * 
316     * @return The refected-information for one Summary-Table row.
317     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
318     * 
319     * @throws IndexOutOfBoundsException If {@code 'rowIndex'} is not within the bounds of the list
320     * of rows
321     */
322    public ENTITY getRowEntity(int rowIndex)
323    { return rowEntities.elementAt(rowIndex); }
324
325
326    // ********************************************************************************************
327    // ********************************************************************************************
328    // Table-Rows: Getters by index / row number, USING Ret2's for more complete information.
329    // ********************************************************************************************
330    // ********************************************************************************************
331
332
333    /**
334     * Retrieve <B STYLE='color: red;'><I>both</I></B> the row-HTML
335     * <B STYLE='color: red;'><I>and</I></B> the reflected-entity information for the
336     * {@code i}<SUP>th</SUP> row in {@code this} Summary-Table.
337     * 
338     * <BR /><BR />Not every row in a Summary-Table is guaranteed to have a Member Signature.  
339     * When Summary-Table's are sorted into categories or sections, then a Summary-Table may also
340     * have a Title-Bar row.  It is (hopefully) obvious that a Title-Bar row would not contain an
341     * associated {@code 'ENTITY'} (Method, Field, Constructor, etc...).
342     * 
343     * @param rowIndex The entity-number / row-number to retrieve from {@code this} Summary-Table.
344     * 
345     * @return An instance of 
346     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_ENTITY_VEC>
347     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
348     * 
349     * @throws IndexOutOfBoundsException If {@code 'rowIndex'} is not within the bounds of the list
350     * of rows
351     */
352    public Ret2<ENTITY, Vector<HTMLNode>> getRowEntityAndHTML(int rowIndex)
353    { return new Ret2<>(rowEntities.elementAt(rowIndex), tableRows.elementAt(rowIndex)); }
354
355    /**
356     * Retrieve <B STYLE='color: red;'><I>both</I></B> the row-HTML
357     * <B STYLE='color: red;'><I>and</I></B> and the corresponding / matching instance of 
358     * {@link ReflHTML} for the {@code i}<SUP>th</SUP> row in {@code this} Summary-Table
359     * 
360     * <BR /><BR />Not every row in a Summary-Table is guaranteed to have a Member Signature.  
361     * When Summary-Table's are sorted into categories or sections, then a Summary-Table may also
362     * have a Title-Bar row.  It is (hopefully) obvious that a Title-Bar row would not contain an
363     * associated {@code 'ReflHTML'} HTML Data-Object either.
364     * 
365     * @param rowIndex The entity-number / row-number to retrieve from {@code this} Summary-Table.
366     * 
367     * @return An instance of 
368     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_REFL_VEC>
369     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
370     * 
371     * @throws IndexOutOfBoundsException If {@code i} is not within the bounds of the list of rows
372     * @see #getRowDetail(int)
373     */
374    public Ret2<ReflHTML<ENTITY>, Vector<HTMLNode>> getRowDetailAndHTML(int rowIndex)
375    { return new Ret2<>(getRowDetail(rowIndex), tableRows.elementAt(rowIndex)); }
376
377
378    // ********************************************************************************************
379    // ********************************************************************************************
380    // Table-Rows: Stream's
381    // ********************************************************************************************
382    // ********************************************************************************************
383
384
385    /**
386     * A {@code Stream} that contains {@code this} Summary-Table's rows, as Vectorized-HTML
387     *
388     * @return A stream of Vectorized-HTML Table-Rows for {@code this} Summary-Table.
389     *
390     * <BR /><BR />Note that a Java {@code Stream} is easily converted into just about any
391     * necessary data-type, as explained in the table below:
392     *
393     * <EMBED CLASS='external-html' DATA-FILE-ID=STREAM_CONVERT_T>
394     */
395    public Stream<Vector<HTMLNode>> rowHTMLStream() { return tableRows.stream(); }
396
397    /**
398     * A {@code Stream} that contains all Summary-Table row-entities, as instances of the reflected
399     * information class {@code ENTITY} (this class' sole type-parameter).
400     * 
401     * <BR /><BR />Generic Type-Parameter {@code ENTITY} will be one of the six concrete subclasses
402     * of class {@link Declaration}.
403     * 
404     * @return A stream of entities contained by {@code this} Summary-Table.
405     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
406     *
407     * <BR /><BR />Note that a Java {@code Stream} is easily converted into just about any
408     * necessary data-type, as explained in the table below:
409     *
410     * <EMBED CLASS='external-html' DATA-FILE-ID=STREAM_CONVERT_T>
411     */
412    public Stream<ENTITY> rowEntityStream() { return rowEntities.stream(); }
413
414
415    // ********************************************************************************************
416    // ********************************************************************************************
417    // Table-Rows: Entire Table
418    // ********************************************************************************************
419    // ********************************************************************************************
420
421
422    /**
423     * Retrieve a {@code Stream} that contains <B><I>every</I></B> Summary-Table Row.
424     * 
425     * <BR /><BR />The specific contents of this {@code Stream} are instances of {@link Ret2},
426     * which contain <B STYLE='color: red;'><I>both</I></B> the reflected-entity information
427     * (instance of Type-Parameter {@code ENTITY}) <B STYLE='color: red;'><I>and</I></B> the
428     * Vectorized-HTML Table-Row, as well.
429     * 
430     * @return A Java Stream containing instances of 
431     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_ENTITY_VEC>
432     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
433     */
434    public Stream<Ret2<ENTITY, Vector<HTMLNode>>> entityAndHTMLStream()
435    {
436        Stream.Builder<Ret2<ENTITY, Vector<HTMLNode>>> b = Stream.builder();
437
438        for (int rowIndex=0; rowIndex < rowEntities.size(); rowIndex++)
439            b.accept(new Ret2<>(rowEntities.elementAt(rowIndex), tableRows.elementAt(rowIndex)));
440
441        return b.build();
442    }
443
444    /**
445     * Retrieve the entire list of Table-Rows in this HTML Summary-Table into a {@code Vector}.
446     * 
447     * @return A Java Stream containing instances of 
448     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_RET2_REFL_VEC>
449     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ENTITY_GP>
450     */
451    public Stream<Ret2<ReflHTML<ENTITY>, Vector<HTMLNode>>> reflAndHTMLStream()
452    {
453        Stream.Builder<Ret2<ReflHTML<ENTITY>, Vector<HTMLNode>>> b = Stream.builder();
454
455        for (int rowIndex=0; rowIndex < rowEntities.size(); rowIndex++)
456            b.accept(new Ret2<>(getRowDetail(rowIndex), tableRows.elementAt(rowIndex)));
457
458        return b.build();
459    }
460
461
462    // ********************************************************************************************
463    // ********************************************************************************************
464    // Table-Rows: FIND-METHODS
465    // ********************************************************************************************
466    // ********************************************************************************************
467
468
469    private void CHECK_IS_CALLABLE()
470    {
471        if (this.tableType.isCallable()) return;
472
473        String kind = this.tableType.upgraderReflectionClass.getSimpleName();
474
475        throw new UpgradeException(
476            "This 'find' method may only be used on SummaryTableHTML instances for Method or " +
477                "Constructor Summary Tables.\n" +
478            "This is a SummaryTableHTML<" + kind + "> instance, and this find method may not be " +
479                "used.\n" +
480            "CIET/Type Member Names for " + kind + "'s cannot be overloaded, so therefore you " +
481                "should use the simple/standard find(String) method instead."
482        );
483    }
484
485    private void CHECK_NUM_PARAMS(int numParams)
486    {
487        if (numParams < 1) throw new IllegalArgumentException(
488            "This find method will only search for Callable's (Method's and Constructor's) that" +
489            "accept at least 1 parameter.  You have passed [" + numParams + "] to parameter " +
490            "'numParams'.  This is not allowed." +
491            ((numParams == 0)
492                ? "\nWhen searching for a zero-argument Callable, use " +
493                    "SummaryTableHTML.find(String)"
494                : "")
495        );
496    }
497
498    /**
499     * Retrieves the first Entity/Member whose name matches {@code name}.  When searching a
500     * {@code SummaryTableHTML<Field>}, {@code SummaryTableHTML<EnumConstant>} or 
501     * {@code SummaryTableHTML<AnnotationElem>}, the name of the entity/member will uniquely
502     * identify it amongst the others in the table.
503     * 
504     * <BR /><BR />Due to Java's function overloading, there may be many cases where a
505     * member {@code 'name'} is not sufficient to uniquely identify it (for Method's and 
506     * Constructor's).  In such cases (e.g. overloaded methods) this method simply return the index
507     * of the first match it finds.
508     * 
509     * @param name The name of the entity / member, as a {@code java.lang.String}
510     * 
511     * @return The index of the (first) HTML Table-Row that contains the specified {@link Entity}.
512     * If this Summary-Table does not have any member-signatures by that {@code 'name'}, then
513     * {@code -1} will be returned.
514     */
515    public int find(String name)
516    {
517        ENTITY e = null;
518
519        for (int i=0; i < rowEntities.size(); i++)
520
521            // After a sort, all Title-Rows have null Row-Entity elements
522            // Make sure to skip any row completely if it is a Title-Row
523
524            if ((e = rowEntities.elementAt(i)) != null)
525                if (e.name.equals(name))
526                    return i;
527
528        return -1;
529    }
530
531    /**
532     * Retrieves the first Entity/Member whose name matches {@code 'methodOrCtorName'}.
533     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
534     * 
535     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
536     * 
537     * @throws SummaryTableException <EMBED CLASS='external-html' DATA-FILE-ID=ST_SUMM_EX>
538     * 
539     * @return The index of the first HTML Table-Row that matches this specified name.  If this
540     * Summary-Table does not have any (Method or Constructor) Member-Signatures by that name,
541     * then {@code -1} is returned.
542     */
543    public int findFirst(String methodOrCtorName)
544    {
545        CHECK_IS_CALLABLE();
546
547        ENTITY e = null;
548
549        for (int i=0; i < rowEntities.size(); i++)
550
551            // After a sort, all Title-Rows have null Row-Entity elements
552            // Make sure to skip any row completely if it is a Title-Row
553
554            if ((e = rowEntities.elementAt(i)) != null)
555                if (e.name.equals(methodOrCtorName))
556                    return i;
557
558        return -1;
559    }
560
561    /**
562     * Retrieves the first Entity/Member whose name matches {@code 'methodOrCtorName'}, 
563     * and accepts {@code 'numParams'} parameters.
564     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
565     * 
566     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
567     * @throws SummaryTableException <EMBED CLASS='external-html' DATA-FILE-ID=ST_SUMM_EX>
568     * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=ST_IAEX>
569     * 
570     * @return The index of the first HTML Table-Row that matches the provided specifications.  If
571     * this Summary-Table does not have any Member-Signatures with that name and accepting the
572     * specified number of parameters, then this method returns {@code -1}.
573     */
574    public int findFirst(String methodOrCtorName, int numParams)
575    {
576        CHECK_IS_CALLABLE();
577        CHECK_NUM_PARAMS(numParams);
578
579        for (int i=0; i < rowEntities.size(); i++)
580        {
581            ENTITY e = rowEntities.elementAt(i);
582
583            // After a sort, all Title-Rows have null Row-Entity elements
584            // Make sure to skip any row completely if it is a Title-Row
585
586            if (e == null) continue;
587
588            if (e.name.equals(methodOrCtorName))
589                if (((Callable) e).numParameters() == numParams)
590                    return i;
591        }
592
593        return -1;
594    }
595
596    /**
597     * Retrieves all Entities/Member Table-Row Indices whose name matches
598     * {@code 'methodOrCtorName'}.
599     * 
600     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
601     * 
602     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
603     * 
604     * @return <EMBED CLASS='external-html' DATA-FILE-ID=ST_FIND_ALL_RET>
605     * 
606     * <DIV CLASS=EXAMPLE>{@code
607     * int[] tableRows = methodSummTable.findAll("someMethodName").toArray();
608     * }</DIV>
609     * 
610     * @throws SummaryTableException <EMBED CLASS='external-html' DATA-FILE-ID=ST_SUMM_EX>
611     */
612    public IntStream findAll(String methodOrCtorName)
613    {
614        CHECK_IS_CALLABLE();
615
616        IntStream.Builder   b = IntStream.builder();
617        ENTITY              e = null;
618
619        for (int i=0; i < rowEntities.size(); i++)
620
621            // After a sort, all Title-Rows have null Row-Entity elements
622            // Make sure to skip any row completely if it is a Title-Row
623
624            if ((e = rowEntities.elementAt(i)) != null)
625                if (e.name.equals(methodOrCtorName))
626                    b.accept(i);
627
628        return b.build();
629    }
630
631    /**
632     * Retrieves the first Entity/Member Table-Row Index whose name matches
633     * {@code 'methodOrCtorName'},  and accepts {@code 'numParams'} parameters.
634     * 
635     * <EMBED CLASS='external-html' DATA-FILE-ID=ST_ONLY_CALBL>
636     * 
637     * @param methodOrCtorName <EMBED CLASS='external-html' DATA-FILE-ID=ST_M_OR_C_NAME>
638     * @param numParams <EMBED CLASS='external-html' DATA-FILE-ID=ST_NUM_PARAMS>
639     * 
640     * @return <EMBED CLASS='external-html' DATA-FILE-ID=ST_FIND_ALL_RET>
641     * 
642     * <DIV CLASS=EXAMPLE>{@code
643     * int[] tableRows = methodSummTable.findAll("someMethodName", 1).toArray();
644     * }</DIV>
645     * 
646     * @throws SummaryTableException <EMBED CLASS='external-html' DATA-FILE-ID=ST_SUMM_EX>
647     * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=ST_IAEX>
648     */
649    public IntStream findAll(String methodOrCtorName, int numParams)
650    {
651        CHECK_IS_CALLABLE();
652        CHECK_NUM_PARAMS(numParams);
653
654        IntStream.Builder b = IntStream.builder();
655
656        for (int i=0; i < rowEntities.size(); i++)
657        {
658            ENTITY e = rowEntities.elementAt(i);
659
660            // After a sort, all Title-Rows have null Row-Entity elements
661            // Make sure to skip any row completely if it is a Title-Row
662
663            if (e == null) continue;
664
665            if (e.name.equals(methodOrCtorName))
666                if (((Callable) e).numParameters() == numParams)
667                    b.accept(i);
668        }
669
670        return b.build();
671    }
672
673
674    // ********************************************************************************************
675    // ********************************************************************************************
676    // Package-Private Stuff
677    // ********************************************************************************************
678    // ********************************************************************************************
679
680
681    // Package-Private: Only used in RearrangeEntitySummaries
682    // EXPORTED BY THE EXPORT_PORTAL
683
684    void setTableRows(Vector<Vector<HTMLNode>> tableRows, Vector<ENTITY> rowEntities)
685    {
686        this.tableRows      = tableRows;
687        this.rowEntities    = rowEntities;
688    }
689
690
691    // ********************************************************************************************
692    // ********************************************************************************************
693    // STATIC BUILDER-GETTER FOR THIS CLASS (the constructor is private)
694    // ********************************************************************************************
695    // ********************************************************************************************
696
697
698    // This method is called by JavaDocHTMLFile, and it builds / parses all of the
699    // SummaryTableHTML's in one step.  This is because looking for them would be less efficient if
700    // searching for the 'markers' were done seven different times, rather than all at once, using
701    // a single serach.
702    //
703    // These seven returned-tables are assigned to the JavaDocHTMLFile fields for each of the
704    // summary-table kinds/types.
705
706    @SuppressWarnings("rawtypes")
707    static Ret7<
708            SummaryTableHTML<Method>,
709            SummaryTableHTML<Field>,
710            SummaryTableHTML<Constructor>,
711            SummaryTableHTML<EnumConstant>,
712            SummaryTableHTML<AnnotationElem>,
713            SummaryTableHTML<AnnotationElem>,
714            SummaryTableHTML<NestedType>
715        >
716    parseAllSummaryTables
717        (Vector<HTMLNode> fileVec, JavaSourceCodeFile jscf, JavaDocHTMLFile jdhf)
718    {
719        // These are all inserted
720        SummaryTableHTML<Method>            retMethodSummaryTable        = null;
721        SummaryTableHTML<Field>             retFieldSummaryTable         = null;
722        SummaryTableHTML<Constructor>       retConstructorSummaryTable   = null;
723        SummaryTableHTML<EnumConstant>      retECSummaryTable            = null;
724        SummaryTableHTML<AnnotationElem>    retOAESummaryTable           = null;
725        SummaryTableHTML<AnnotationElem>    retRAESummaryTable           = null;
726        SummaryTableHTML<NestedType>        retNTSummaryTable            = null;
727
728        // Retrieve all the pointers to the Summary-Sections.  They all begin with the Java Doc
729        // HTML Comment <!-- == Method Summary == --> (with the word "Method" replaced by whatever
730        // type of summary it actually is)
731        //
732        // This is a method that used to be in the old "Summaries.java" (deprecated)
733
734        int[] markerPosArr = /* Summaries.allEntityMarkers(fileVec); */
735            CommentNodeFind.all(fileVec, TextComparitor.CN_OR, MARKERS);
736
737        // Loop through all of the HTML Comments like: <!-- == Method Summary == -->
738        for (int i=0; i < markerPosArr.length; i++)
739        {
740            int markerPos = markerPosArr[i];
741
742            /*
743            System.out.println(
744                BGREEN + "Marker Pos: " + markerPos + RESET + ' ' +
745                fileVec.elementAt(markerPos).str
746            );
747            */
748
749            // The <H3> looks like these (after inserting the CSS Tag 'C26'), which is done later
750            // The <H3> should be within the next 30 nodes...
751            //
752            // <h3 class=C26>Optional Element Summary</h3> 
753            // <h3 class=C26>Method Summary</h3>
754            //
755            // NOTE: This *ALSO* could be the "<H3> ... inherited from </H3>"" if it did not have
756            //       any actual entities declared in its own type.  If it is an *ONLY* inherited 
757            //       then the <H3> will be closer to 30 nodes away, not 20.
758
759            int pos = TagNodeFind.first
760                (fileVec, markerPos, markerPos + 30, TC.OpeningTags, "h3");
761
762            // This is the Red-Banner H3 CINZEL Title-Bar saying "Method Summaries"
763            TagNodeIndex openingH3 = new TagNodeIndex(pos, (TagNode) fileVec.elementAt(pos));
764
765            if (pos == -1)
766                Messager.assertFailHTML("Summary Marker is not followed by an <H3>", null);
767
768            // If this is *ACCIDENTALLY* left-off, *AND* this is one of those cases, where there
769            // are only *INHERITED* methods (no actual methods defined), then the FindInclusive
770            // will return the table for the *NEXT MARKER* - which is a mistake!
771            //
772            // This sets the FindInclusive for <TABLE>...</TABLE> to limit the search-range
773            // to the start of the NEXT-MARKER-POS (or PAGE-END, if this is the last marker).
774
775            int endSearchPos = ((i+1) < markerPosArr.length) ? markerPosArr[i+1] : -1;
776
777            // Now, the Summary Table should be directly below the <H3> Tag, use the restricted
778            // range that was just computed in the previous line.
779
780            DotPair tableLocation = InnerTagFindInclusive.first
781                (fileVec, pos, endSearchPos, "table", "class", TextComparitor.C, "memberSummary");
782
783            if (tableLocation == null)
784            {
785                // There are classes which do not define any methods at all, but stil have a
786                // Summary-Section for methods.  If a Type inherits from another type, the method
787                // Summary Section will have a small list at the bottom of all the methods that
788                // are inherited from it's super-class or interface.
789                //
790                // REMEMBER: All classes inherit from java.lang.Object !  This issue hapens when 
791                // there are classes which simply don't have any methods - OR AT THE LEAST, DON'T 
792                // HAVE ANY "public" or "protected" (Java-Doc'ed) Methods.
793                //
794                // In such cases, this is not an error, but it is also not a summary table that 
795                // has Method or Field Detail Anchor-Links to Method-Details, Field-Details, etc...
796                //
797                // Start at the current <H3> position - *PLUS ONE* - and look for the next <H3>.
798                // That <H3> will have text that says "inherited from"
799                //
800                // All this "if branch" actually does at all is an error-check.  In the upcoming
801                // switch-statement, this is handled by this class SummaryTableHTML-Constructor.
802
803                int checkIfInheritedPos = TagNodeFind.first
804                    (fileVec, pos+1, pos + 30, TC.OpeningTags, "h3");
805
806                // System.out.println(fileVec.elementAt(pos+1).str);
807                // 
808                // If this marker didn't have a table, **AND** doesn't have anything it inherited,
809                // then this has to be an unhandled / assertion-fail
810
811                if (! fileVec.elementAt(checkIfInheritedPos + 1).str.contains("inherited from"))
812                    Messager.assertFailHTML
813                        ("Summary <H3> not followed by <TABLE CLASS=memberSummary>", null);
814
815                // Next, the constructor will just set the "Opening H3" parameter (this.cinzelH3),
816                // and then exit immediately, before setting all the other fields to null
817            }
818
819            // This could easily be 'switched' based on the marker-kind, but it would still be a
820            // string assignment, since the "get all markers" just returns a vector-index location,
821            // rather than the name of the marker.
822            //
823            // NOTE: If the "tableLocation" is null (because there were only inherited-entities,
824            //       from the super-class, and no declared entities, then the SummaryTableHTML
825            //       constructor just sets the openingH3, and exits);
826
827            switch (fileVec.elementAt(pos + 1).str)
828            {
829                case "Method Summary": retMethodSummaryTable = new SummaryTableHTML<>
830                        (fileVec, tableLocation, openingH3, Entity.METHOD, jscf, jdhf);
831                    break;
832
833                case "Constructor Summary": retConstructorSummaryTable = new SummaryTableHTML<>
834                        (fileVec, tableLocation, openingH3, Entity.CONSTRUCTOR, jscf, jdhf);
835                    break;
836
837                case "Field Summary": retFieldSummaryTable = new SummaryTableHTML<>
838                        (fileVec, tableLocation, openingH3, Entity.FIELD, jscf, jdhf);
839                    break;
840
841                case "Enum Constant Summary": retECSummaryTable = new SummaryTableHTML<>
842                        (fileVec, tableLocation, openingH3, Entity.ENUM_CONSTANT, jscf, jdhf);
843                    break;
844
845                case "Optional Element Summary": retOAESummaryTable = new SummaryTableHTML<>
846                        (fileVec, tableLocation, openingH3, Entity.ANNOTATION_ELEM, jscf, jdhf);
847                    break;
848
849                case "Required Element Summary": retRAESummaryTable = new SummaryTableHTML<>
850                        (fileVec, tableLocation, openingH3, Entity.ANNOTATION_ELEM, jscf, jdhf);
851                    break;
852
853                case "Nested Class Summary": retNTSummaryTable = new SummaryTableHTML<>
854                        (fileVec, tableLocation, openingH3, Entity.INNER_CLASS, jscf, jdhf);
855                    break;
856
857                default: Messager.assertFailHTML
858                    ("Unrecognized Summary Table Type", fileVec.elementAt(pos + 1).str);
859            }
860        }
861
862        // Just return these built summary table.  It is likely that many of these will be null.
863        return new Ret7<>(
864            retMethodSummaryTable,
865            retFieldSummaryTable,
866            retConstructorSummaryTable,
867            retECSummaryTable,
868            retOAESummaryTable,
869            retRAESummaryTable,
870            retNTSummaryTable
871        );
872    }
873
874
875    // ********************************************************************************************
876    // ********************************************************************************************
877    // private constructor
878    // ********************************************************************************************
879    // ********************************************************************************************
880
881
882    @SuppressWarnings("unchecked") // The (ENTITY) getter.apply(row); line...
883    private SummaryTableHTML(
884            Vector<HTMLNode>    fileVec,    
885            DotPair             tableLocation,
886            TagNodeIndex        openingH3,
887            Entity              tableType,
888            JavaSourceCodeFile  jscf,
889            JavaDocHTMLFile     jdhf
890        )
891    {
892        this.jdhf = jdhf;
893
894        // This literally just sets the TagNodeIndex field "cinzelH3" - which is the title /
895        // header / banner in red with rounded corners.  The rest is null.
896        //
897        // 'tableLocation' will be null whenever there is a Summary-Table whose only contents
898        // are the "Inherited Entities" (Type's that inherit, methods for example, but do not
899        // declare any methods of their own).
900
901        if (tableLocation == null)
902        {
903            this.cinzelH3   = openingH3;
904            this.tableType  = tableType;
905
906            // Set this stuff to null, and exit
907            this.tableOpen = this.tableClose = null;
908            this.headerRow = null;
909
910            // System.out.println("jdhf.simpleName: " + jdhf.simpleName);
911            // Torello.Java.Q.BP();
912
913            return;
914        }
915
916        // These were built directly above, the element being retrieved is guaranteed to be a <TABLE>
917        // ... unless InnerTagFindInclusive is broken (and it isn't)... or the page suddenly changed ...
918        // (which it can't, this is a private method) ... no need to do assert's here
919
920        this.tableOpen = new TagNodeIndex
921            (tableLocation.start, fileVec.elementAt(tableLocation.start).ifTagNode());
922
923        this.tableClose = new TagNodeIndex
924            (tableLocation.end, fileVec.elementAt(tableLocation.end).ifTagNode());
925
926        // This specifies which type of Summary-Table this is... Method, Field, Enum-Constant...
927        this.tableType = tableType;
928
929        // This is the CINZEL-font Banner-Header-Label that just says "Method Summaries"
930        // or "Field Summaries" or "Optional Annotation Element Summaries"
931
932        this.cinzelH3 = openingH3;
933
934
935        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
936        // Build a "Getter" for Converting a Summary-Row into an **ENTITY** / Reflection instance
937        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
938        // 
939        // By using a 'getter' function, this switch-statement can be run *OUTSIDE OF THE LOOP*.
940        // The other way to do this, is put the switch inside the loop, and it will be executed
941        // for every row in the table, rather than only once.
942
943        Function<String, ENTITY> getter = null;
944
945        switch (tableType)
946        {
947
948            // The following notice was placed in each of these switch/case statements.
949            // It applies to all 6 of them, but is only left here at the top:
950            //
951            // This is called twice:
952            //      Once from JavaDocHTMLFile: using the Detail-HTML-Signature
953            //      Once from SummaryTableHTML: using the Summary-HTML-Signature
954            //
955            // MESSAGER:
956            //  1) INVOKES:     assertFailHTML
957            //  2) INVOKED-BY:  SummaryTableHTML-Constructor & JavaDocHTMLFile-Constructor
958            //  3) RETURNS:     HTML-Parsed (stripped) Torello.JavaDoc.Method
959            //  4) THROWS:      JavaDocHTMLParseException (assertFailHTML)
960
961            case METHOD:
962
963                getter = (String row) ->
964                    (ENTITY) SignatureParse.parseMethodSignature(row, jscf, jdhf);
965
966                break;
967
968            case CONSTRUCTOR:
969
970                getter = (String row) ->
971                    (ENTITY) SignatureParse.parseConstructorSignature(row, jscf, jdhf);
972
973                break;
974
975            case FIELD:
976
977                // NOTE: 'true' is passed to the 'hasGenericParameters' boolean
978                //
979                // Passing 'true' seems like cheating, but that's what RearrangeEntitySummaries
980                // was doing.  Actually, it is irrelevant because HERE, the Field that is
981                // returned was RETRIEVED not GENERATED - and that literally, just requires the
982                // name of the field.  *AND* when getting the name of the field from the
983                // signature, the 'generic-parameters' are not important.
984
985                getter = (String row) ->
986                    (ENTITY) SignatureParse.parseFieldSignature(row, true, jscf, jdhf);
987
988                break;
989
990            case ENUM_CONSTANT:
991
992                getter = (String row) ->
993                    (ENTITY) SignatureParse.parseECSignature(row, jscf, jdhf);
994
995                break;
996
997            case ANNOTATION_ELEM:
998
999                getter = (String row) ->
1000                    (ENTITY) SignatureParse.parseAESignature(row, jscf, jdhf);
1001
1002                break;
1003
1004            case INNER_CLASS:
1005
1006                getter = (String row) ->
1007                    (ENTITY) SignatureParse.parseNTSignature(row, jscf, jdhf);
1008
1009                break;
1010        }
1011
1012
1013        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1014        // Retrieve / extract all Summary Table-Row's
1015        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1016
1017        // Retrieve all Table row <TR>'s
1018        //
1019        // Before the Summary-Table has been modified by the Java Doc Upgrader, the entries in the
1020        // table are all the <TR>'s (it's that simple)... Creating <TR>'s that have titles, and
1021        // other non-entity contents is *NOT* done *UNTIL* RearrangeEntitySumamries
1022
1023        Vector<Vector<HTMLNode>> rows = TagNodeGetL1Inclusive.all
1024            (fileVec, tableLocation.start, tableLocation.end, "tr");
1025
1026        // Now, iterate through all of the <TR>'s.  The first <TR> needs to be assigned to the
1027        // NodeIndex that will hold the FIRST ROW.  If the table isn't sorted, it will need to be
1028        // retained to be re-inserted.
1029
1030        // this.headerRow = rows.elementAt(0);
1031
1032        int firstRowEndTR = TagNodeFind.first
1033            (fileVec, tableLocation.start, tableLocation.end, TC.ClosingTags, "TR");
1034
1035        this.headerRow = Util.cloneRange(fileVec, tableLocation.start + 1, firstRowEndTR + 1);
1036
1037        // Skip the header-row, it was just saved in the previous line
1038        boolean first = true;
1039
1040
1041        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1042        // These temporary loop-variables are needed to do the CSS-ID insert (or lack-thereof)
1043        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1044
1045        ENTITY  entity = null;
1046        String  abbrev = this.tableType.abbrev; // Two-character CSS-ID abbreviation-string
1047
1048        boolean startingPosIsEnumOrCtorCheck =
1049            (this.tableType == Entity.ENUM_CONSTANT) ||
1050            (this.tableType == Entity.CONSTRUCTOR);
1051
1052        boolean detailsRemoved =
1053                ((this.tableType == Entity.METHOD)          && jdhf.methodDetailsRemoved)
1054            ||  ((this.tableType == Entity.CONSTRUCTOR)     && jdhf.constructorDetailsRemoved)
1055            ||  ((this.tableType == Entity.FIELD)           && jdhf.fieldDetailsRemoved)
1056            ||  ((this.tableType == Entity.ENUM_CONSTANT)   && jdhf.ecDetailsRemoved)
1057            ||  ((this.tableType == Entity.ANNOTATION_ELEM) && jdhf.aeDetailsRemoved);
1058
1059        // System.out.println
1060        //      ("Starting: " + BRED + "table has " + rows.size() + " rows." + RESET);
1061
1062        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1063        // Iterate the Summary <TABLE> rows, and insert them into 'tableRows' and 'rowEntites'
1064        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1065        //
1066        // NOTE: This loop is *ALSO* where the Summary-Row CSS-ID is inserted.  An ID is not
1067        //       inserted (on the off chance / kind-of rare) that the relevant Details-Section
1068        //       was requested to be removed by the user.
1069
1070        for (Vector<HTMLNode> row : rows)
1071
1072            if (first) first = false;
1073
1074            else
1075            {
1076                // System.out.println("ROW HTML:\n" + Util.pageToString(row.html));
1077                String rowStr = extractSignature(row, this.tableType);
1078                // System.out.println("rowStr: " + BYELLOW + rowStr + RESET + '\n');
1079
1080
1081                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1082                // Here the List of HTML-Rows and the List of Row-ENTITY (Vector) are filled up
1083                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1084
1085                // This is the internal-Vector that contains all of the Summary-Table Row HTML
1086                this.tableRows.add(row);
1087
1088                // Use the "getter" to extract / retrieve the ENTITy (Method, Field, Constructor,
1089                // EnumConstant, etc...)
1090
1091                entity = getter.apply(rowStr);
1092
1093                // Save the ENTITY into the parallel 'rowEntities' Vector
1094                this.rowEntities.add(entity);
1095
1096
1097                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1098                // CSS Entity-Row-ID - This CSS-ID is used by the NavButtons Bar
1099                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1100                //
1101                // This CSS-ID is inserted into the Summary-Row <A> Anchor: <A ID=entityID ...>
1102                // This CSS-ID is the exact same ID that is later added to the <A HREF=entityID>
1103                // for the Double-Up Arrow Button (⇈) of the corresponding ReflHTML Detail-Section
1104
1105                TagNode tn          = null;
1106                boolean insertedID  = false;
1107
1108                int i = startingPosIsEnumOrCtorCheck
1109                    ? 0
1110                    : TagNodeFind.nth(row, 2, TC.OpeningTags, "td", "th") + 1;
1111
1112                INNER:
1113                for (; i < row.size(); i++)
1114
1115                    if ((tn = row.elementAt(i).openTag()) != null)
1116                        if (tn.tok.equals("a"))
1117                        {
1118                            row.setElementAt(tn.setID(abbrev + entity.id, null), i);
1119                            insertedID = true;
1120                            break INNER;
1121                        }
1122
1123                if (! insertedID) if (! detailsRemoved) Messager.assertFailHTML(
1124                    "Failed to Insert CSS-ID [" + abbrev + entity.id + "] into Summary " +
1125                    "Table Row", rowStr
1126                );
1127            }
1128    }
1129
1130    // *** THIS MAY NEED TO CHANGE ***
1131    // CURRENTLY: In Java Doc for Java 11, the first two columns hold the return type and the
1132    //            rest of the signature.
1133    //
1134    // COPIED DIRECTLY FROM 'RearrangeEntitySummaries' CHANGED FOR USING 'dp' INSTEAD OF
1135    // Vector
1136
1137    private String extractSignature(Vector<HTMLNode> tableRow, Entity tableType)
1138    {
1139        Vector<DotPair> cols = TagNodeFindInclusive.all(tableRow, "td", "th");
1140
1141        StringBuffer    sb  = new StringBuffer();
1142        TextNode        txn = null;
1143
1144        DotPair dp = cols.elementAt(0);
1145
1146        for (int i=dp.start+1; i < dp.end; i++)
1147            if ((txn = tableRow.elementAt(i).ifTextNode()) != null)
1148                sb.append(txn.str);
1149
1150        // Enum-Constants have one row of 'constant-name' and then one row of description.  The
1151        // others have two rows: a row of 'type/modifiers' and a row of 'signature/name'
1152
1153        if (tableType == Entity.ENUM_CONSTANT) return sb.toString().trim();
1154
1155        // Constructors may have two or three rows.  If there is a modifier, then there are three,
1156        // if there are no modifiers for the constructors, then there are only two.  If there are
1157        // two, exit now
1158
1159        if (tableType == Entity.CONSTRUCTOR) if (cols.size() == 2) return sb.toString().trim();
1160
1161        sb.append(' ');
1162
1163        dp = cols.elementAt(1);
1164
1165        for (int i=dp.start+1; i < dp.end; i++)
1166            if ((txn = tableRow.elementAt(i).ifTextNode()) != null)
1167                sb.append(txn.str);
1168
1169        return sb.toString().trim();
1170    }
1171
1172
1173    // ********************************************************************************************
1174    // ********************************************************************************************
1175    // REBUILD THE JAVADOC PAGE
1176    // ********************************************************************************************
1177    // ********************************************************************************************
1178
1179
1180    // Used in the method below
1181    private static final TextNode NEW_LINE = new TextNode("\n");
1182
1183    // Method below too
1184    private static final Vector<Replaceable> EMPTY_VECTOR = new Vector<>();
1185
1186    Vector<Replaceable> allReplaceables()
1187    {
1188        // There are summary-tables whose only contents are the "Inherited Entities".  When that
1189        // occurs, the 'tableOpen' and 'tableClose' NodeIndex-instances will be null.
1190        //
1191        // You still need to add the "Cinzel-H3" to the Banner that says "Method Summary" or
1192        // "Field Summary" (or whichever SummaryTable this is).  So, in this case, return a Vector
1193        // whose only contents are the TagNodeIndex Cinzel-H3 node.
1194
1195        if (tableOpen == null)
1196        {
1197            Vector<Replaceable> cinzelOnlyVec = new Vector<>();
1198            cinzelOnlyVec.add(this.cinzelH3);
1199            return cinzelOnlyVec;
1200        }
1201
1202        Vector<HTMLNode>    newTable            = new Vector<>();
1203        DotPair             oldTableLocation    = new DotPair(tableOpen.index, tableClose.index);
1204
1205        newTable.add(tableOpen.n);
1206        newTable.add(NEW_LINE);
1207        newTable.addAll(headerRow);
1208        newTable.add(NEW_LINE);
1209
1210        for (Vector<HTMLNode> row : tableRows)
1211        {
1212            newTable.addAll(row);
1213            newTable.add(NEW_LINE);
1214        }
1215
1216        newTable.add(tableClose.n);
1217        newTable.add(NEW_LINE);
1218
1219        Vector<Replaceable> ret = new Vector<>();
1220        ret.add(cinzelH3);
1221        ret.add(Replaceable.create(oldTableLocation, newTable));
1222
1223        return ret;
1224    }
1225
1226
1227    // ********************************************************************************************
1228    // ********************************************************************************************
1229    // THE NEW-THING: Garbage-Collector Helper?
1230    // ********************************************************************************************
1231    // ********************************************************************************************
1232    // 
1233    // Does this help?  Is this "good" for the Garbage-Collect?  Is this going to speed it up,
1234    // or slow it down?  This is just a "C-Styled" FREE or DESTORY method...
1235    // It isn't publicly visible anyway...
1236
1237    void clear()
1238    {
1239        // public final TagNodeIndex tableOpen;
1240        if (tableOpen != null) tableOpen.n = null;
1241
1242        // public final TagNodeIndex tableClose;
1243        if (tableClose != null) tableClose.n = null;
1244    
1245        // final Vector<HTMLNode> headerRow;
1246        if (headerRow != null) headerRow.clear();
1247
1248        // final TagNodeIndex cinzelH3;
1249        if (cinzelH3 != null) cinzelH3.n = null;
1250    
1251        // private Vector<Vector<HTMLNode>> tableRows = new Vector<>();
1252        if (tableRows != null)
1253        {
1254            for (Vector<HTMLNode> v : tableRows) if (v != null) v.clear();
1255
1256            tableRows.clear();
1257            tableRows = null;
1258        }
1259    
1260        // private Vector<ENTITY> rowEntities = new Vector<>();
1261        if (rowEntities != null) { rowEntities.clear(); rowEntities = null; }
1262    }
1263
1264
1265    // ********************************************************************************************
1266    // ********************************************************************************************
1267    // DEBUG-PRINTING
1268    // ********************************************************************************************
1269    // ********************************************************************************************
1270
1271
1272    private static final String STARS =
1273        BYELLOW + "\n*****************************************\n" + RESET;
1274
1275    /**
1276     * Prints an abbreviated-version of the contents of this instance, to a user-provided
1277     * {@code Appendable}.  If the HTML requires more than four lines of text, only the first four
1278     * lines are printed.
1279     * 
1280     * @param a This may be any Java Appendable.  If an {@code IOException} is thrown while writing
1281     * to this {@code Appendable}, it will be caught an wrapped in an
1282     * {@code IllegalArgumentException}, with the {@code IOException} set as the {@code cause}.
1283     * 
1284     * @throws IllegalArgumentException If {@code 'a'} throws an {@code IOException}
1285     * 
1286     * @see StrPrint#firstNLines(String, int)
1287     * @see Util#pageToString(Vector)
1288     * @see StrIndent#indent(String, int)
1289     */
1290    public void debugPrint(Appendable a)
1291    {
1292        try
1293        {
1294            if (tableType != null) a.append
1295                (BCYAN + "this.tableType: " + RESET + this.tableType.toString() + "\n");
1296            else
1297                a.append(BRED + "this.tableType is null" + RESET);
1298
1299            if (tableOpen != null) a.append
1300                (BCYAN + "this.tableOpen: " + RESET + this.tableOpen.n.str + "\n");
1301            else
1302                a.append(BRED + "this.tableOpen is null" + RESET);
1303
1304            if (tableClose != null) a.append
1305                (BCYAN + "this.tableClose: " + RESET + this.tableClose.n.str + "\n");
1306            else
1307                a.append(BRED + "this.tableClose is null" + RESET);
1308
1309            if (cinzelH3 != null) a.append
1310                (BCYAN + "this.cinzelH3: " + RESET + this.cinzelH3.n.str + "\n");
1311            else
1312                a.append(BRED + "this.cinzelH3 is null" + RESET);
1313
1314            if (headerRow != null) a.append(
1315                STARS + BCYAN + "this.headerRow:" + RESET + STARS +
1316                StrPrint.firstNLines(Util.pageToString(headerRow), 4) +
1317                '\n'
1318            );
1319
1320            for (int i=0; i < tableRows.size(); i++)
1321
1322                a.append(
1323                    BCYAN + "TABLE ROW " + (i+1) + RESET + '\n' +
1324                    BGREEN + "HTML:\n" + RESET +
1325                    StrIndent.indent
1326                        (Util.pageToString(tableRows.elementAt(i)).replace("\n", "\\n"), 4) +
1327                    '\n' +
1328                    BGREEN + "ENTITY:\n" + RESET +
1329                    StrIndent.indent
1330                        (rowEntities.elementAt(i).toString(PF.UNIX_COLORS | PF.JOW_INSTEAD), 4) +
1331                    '\n'
1332                );
1333        }
1334        catch (java.io.IOException ioe)
1335        {
1336            throw new IllegalArgumentException(
1337                ioe
1338            );
1339        }
1340    }
1341
1342    
1343    /**
1344     * A really great way to view the contents of this class - <I>in just one page of text</I>.
1345     * 
1346     * @param numCharsWide The maximum line width to be printed to terminal.  This
1347     * number must be between 60 and 150, or else an exception shall throw.
1348     * 
1349     * @return The contents of this class-instance, as a {@code String}
1350     * 
1351     * @throws IllegalArgumentException If the parameter 'numCharsWide' was not passed a value 
1352     * within the aforementioned range.
1353     * 
1354     * @see StrPrint#printListAbbrev(Iterable, int, int, boolean, boolean, boolean)
1355     * @see StrPrint#printListAbbrev(Iterable, IntTFunction, int, int, boolean, boolean, boolean)
1356     */
1357    public String debugPrintDense(final int numCharsWide)
1358    {
1359        if ((numCharsWide < 60) || (numCharsWide > 150)) throw new IllegalArgumentException
1360            ("Parameter 'numCharsWide' wasn't passed a value between 60 and 150: " + numCharsWide);
1361
1362        return
1363            "rowEntities.size(): " + rowEntities.size() + '\n' +
1364            "rowEntities Vector Contents:" + // '\n' is automatically added
1365                StrPrint.printListAbbrev(rowEntities, numCharsWide, 4, false, true, true) + '\n' +
1366            "tableRows.size(): " + tableRows.size() + '\n' +
1367            "tableRows Vector Contents:" + // '\n' is automatically added
1368                StrPrint.printListAbbrev(
1369                    tableRows,
1370                    (int i, Vector<HTMLNode> tableRow) -> Util.pageToString(tableRow),
1371                    numCharsWide, 4, false, true, true
1372                );
1373    }
1374
1375    /**
1376     * Converts the contents of this class into a {@code String}
1377     * @return A Printable-{@code String}
1378     * @see #debugPrintDense(int)
1379     */
1380    public String toString()
1381    {
1382        final String oStr = (this.tableOpen == null)
1383            ? "null"
1384            : this.tableOpen.toString();
1385
1386        final String cStr = (this.tableClose == null)
1387            ? "null"
1388            : this.tableClose.toString();
1389
1390        final String hStr = (this.headerRow == null)
1391            ? "null"
1392            : StrPrint.abbrevEndRDSF(Util.pageToString(headerRow), 120, false);
1393
1394        return
1395            "tableType:  " + tableType + '\n' +
1396            "tableOpen:  " + oStr + '\n' +
1397            "tableClose: " + cStr + '\n' +
1398            "headerRow:  " + hStr + '\n' +
1399            debugPrintDense(120);
1400    }
1401}