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                // In such cases, this is not an error, but it is also not a summary table.  In
791                // these cases, just 'continue' and there will not be an instantiated Summary Table
792                // for the particular entity, of this particular Type/CIET.
793                //
794                // Start at the current <H3> position - *PLUS ONE* - and look for the next <H3>.
795                // That <H3> will have text that says "inherited from"
796
797                int checkIfInheritedPos = TagNodeFind.first
798                    (fileVec, pos+1, pos + 30, TC.OpeningTags, "h3");
799
800                // System.out.println(fileVec.elementAt(pos+1).str);
801
802                // If this marker didn't have a table, **AND** doesn't have anything it inherited,
803                // then this has to be an unhandled / assertion-fail
804
805                if (! fileVec.elementAt(checkIfInheritedPos + 1).str.contains("inherited from"))
806                    Messager.assertFailHTML
807                        ("Summary <H3> not followed by <TABLE CLASS=memberSummary>", null);
808
809                // NOTE: the "else" here is that the constructor will just set the "Opening H3"
810                //       parameter (this.cinzelH3), and then exit immediately, before setting
811                //       all the other fields to null
812            }
813
814            // This could easily be 'switched' based on the marker-kind, but it would still be a
815            // string assignment, since the "get all markers" just returns a vector-index location,
816            // rather than the name of the marker.
817            //
818            // NOTE: If the "tableLocation" is null (because there were only inherited-entities,
819            //       from the super-class, and no declared entities, then the SummaryTableHTML
820            //       constructor just sets the openingH3, and exits);
821
822            switch (fileVec.elementAt(pos + 1).str)
823            {
824                case "Method Summary": retMethodSummaryTable = new SummaryTableHTML<>
825                        (fileVec, tableLocation, openingH3, Entity.METHOD, jscf, jdhf);
826                    break;
827
828                case "Constructor Summary": retConstructorSummaryTable = new SummaryTableHTML<>
829                        (fileVec, tableLocation, openingH3, Entity.CONSTRUCTOR, jscf, jdhf);
830                    break;
831
832                case "Field Summary": retFieldSummaryTable = new SummaryTableHTML<>
833                        (fileVec, tableLocation, openingH3, Entity.FIELD, jscf, jdhf);
834                    break;
835
836                case "Enum Constant Summary": retECSummaryTable = new SummaryTableHTML<>
837                        (fileVec, tableLocation, openingH3, Entity.ENUM_CONSTANT, jscf, jdhf);
838                    break;
839
840                case "Optional Element Summary": retOAESummaryTable = new SummaryTableHTML<>
841                        (fileVec, tableLocation, openingH3, Entity.ANNOTATION_ELEM, jscf, jdhf);
842                    break;
843
844                case "Required Element Summary": retRAESummaryTable = new SummaryTableHTML<>
845                        (fileVec, tableLocation, openingH3, Entity.ANNOTATION_ELEM, jscf, jdhf);
846                    break;
847
848                case "Nested Class Summary": retNTSummaryTable = new SummaryTableHTML<>
849                        (fileVec, tableLocation, openingH3, Entity.INNER_CLASS, jscf, jdhf);
850                    break;
851
852                default: Messager.assertFailHTML
853                    ("Unrecognized Summary Table Type", fileVec.elementAt(pos + 1).str);
854            }
855        }
856
857        // Just return these built summary table.  It is likely that many of these will be null.
858        return new Ret7<>(
859            retMethodSummaryTable,
860            retFieldSummaryTable,
861            retConstructorSummaryTable,
862            retECSummaryTable,
863            retOAESummaryTable,
864            retRAESummaryTable,
865            retNTSummaryTable
866        );
867    }
868
869
870    // ********************************************************************************************
871    // ********************************************************************************************
872    // private constructor
873    // ********************************************************************************************
874    // ********************************************************************************************
875
876
877    @SuppressWarnings("unchecked") // The (ENTITY) getter.apply(row); line...
878    private SummaryTableHTML(
879            Vector<HTMLNode>    fileVec,    
880            DotPair             tableLocation,
881            TagNodeIndex        openingH3,
882            Entity              tableType,
883            JavaSourceCodeFile  jscf,
884            JavaDocHTMLFile     jdhf
885        )
886    {
887        this.jdhf = jdhf;
888
889        // This literally just sets the TagNodeIndex field "cinzelH3" - which is the title /
890        // header / banner in red with rounded corners.  The rest is null.
891        //
892        // 'tableLocation' will be null whenever there is a Summary-Table whose only contents
893        // are the "Inherited Entities" (Type's that inherit, methods for example, but do not
894        // declare any methods of their own).
895
896        if (tableLocation == null)
897        {
898            this.cinzelH3   = openingH3;
899            this.tableType  = tableType;
900
901            // Set this stuff to null, and exit
902            this.tableOpen = this.tableClose = null;
903            this.headerRow = null;
904
905            return;
906        }
907
908        // These were built directly above, the element being retrieved is guaranteed to be a <TABLE>
909        // ... unless InnerTagFindInclusive is broken (and it isn't)... or the page suddenly changed ...
910        // (which it can't, this is a private method) ... no need to do assert's here
911
912        this.tableOpen = new TagNodeIndex
913            (tableLocation.start, fileVec.elementAt(tableLocation.start).ifTagNode());
914
915        this.tableClose = new TagNodeIndex
916            (tableLocation.end, fileVec.elementAt(tableLocation.end).ifTagNode());
917
918        // This specifies which type of Summary-Table this is... Method, Field, Enum-Constant...
919        this.tableType = tableType;
920
921        // This is the CINZEL-font Banner-Header-Label that just says "Method Summaries"
922        // or "Field Summaries" or "Optional Annotation Element Summaries"
923
924        this.cinzelH3 = openingH3;
925
926
927        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
928        // Build a "Getter" for Converting a Summary-Row into an **ENTITY** / Reflection instance
929        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
930        // 
931        // By using a 'getter' function, this switch-statement can be run *OUTSIDE OF THE LOOP*.
932        // The other way to do this, is put the switch inside the loop, and it will be executed
933        // for every row in the table, rather than only once.
934
935        Function<String, ENTITY> getter = null;
936
937        switch (tableType)
938        {
939
940            // The following notice was placed in each of these switch/case statements.
941            // It applies to all 6 of them, but is only left here at the top:
942            //
943            // This is called twice:
944            //      Once from JavaDocHTMLFile: using the Detail-HTML-Signature
945            //      Once from SummaryTableHTML: using the Summary-HTML-Signature
946            //
947            // MESSAGER:
948            //  1) INVOKES:     assertFailHTML
949            //  2) INVOKED-BY:  SummaryTableHTML-Constructor & JavaDocHTMLFile-Constructor
950            //  3) RETURNS:     HTML-Parsed (stripped) Torello.JavaDoc.Method
951            //  4) THROWS:      JavaDocHTMLParseException (assertFailHTML)
952
953            case METHOD:
954
955                getter = (String row) ->
956                    (ENTITY) SignatureParse.parseMethodSignature(row, jscf, jdhf);
957
958                break;
959
960            case CONSTRUCTOR:
961
962                getter = (String row) ->
963                    (ENTITY) SignatureParse.parseConstructorSignature(row, jscf, jdhf);
964
965                break;
966
967            case FIELD:
968
969                // NOTE: 'true' is passed to the 'hasGenericParameters' boolean
970                //
971                // Passing 'true' seems like cheating, but that's what RearrangeEntitySummaries
972                // was doing.  Actually, it is irrelevant because HERE, the Field that is
973                // returned was RETRIEVED not GENERATED - and that literally, just requires the
974                // name of the field.  *AND* when getting the name of the field from the
975                // signature, the 'generic-parameters' are not important.
976
977                getter = (String row) ->
978                    (ENTITY) SignatureParse.parseFieldSignature(row, true, jscf, jdhf);
979
980                break;
981
982            case ENUM_CONSTANT:
983
984                getter = (String row) ->
985                    (ENTITY) SignatureParse.parseECSignature(row, jscf, jdhf);
986
987                break;
988
989            case ANNOTATION_ELEM:
990
991                getter = (String row) ->
992                    (ENTITY) SignatureParse.parseAESignature(row, jscf, jdhf);
993
994                break;
995
996            case INNER_CLASS:
997
998                getter = (String row) ->
999                    (ENTITY) SignatureParse.parseNTSignature(row, jscf, jdhf);
1000
1001                break;
1002        }
1003
1004
1005        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1006        // Retrieve / extract all Summary Table-Row's
1007        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1008
1009        // Retrieve all Table row <TR>'s
1010        //
1011        // Before the Summary-Table has been modified by the Java Doc Upgrader, the entries in the
1012        // table are all the <TR>'s (it's that simple)... Creating <TR>'s that have titles, and
1013        // other non-entity contents is *NOT* done *UNTIL* RearrangeEntitySumamries
1014
1015        Vector<Vector<HTMLNode>> rows = TagNodeGetL1Inclusive.all
1016            (fileVec, tableLocation.start, tableLocation.end, "tr");
1017
1018        // Now, iterate through all of the <TR>'s.  The first <TR> needs to be assigned to the
1019        // NodeIndex that will hold the FIRST ROW.  If the table isn't sorted, it will need to be
1020        // retained to be re-inserted.
1021
1022        // this.headerRow = rows.elementAt(0);
1023
1024        int firstRowEndTR = TagNodeFind.first
1025            (fileVec, tableLocation.start, tableLocation.end, TC.ClosingTags, "TR");
1026
1027        this.headerRow = Util.cloneRange(fileVec, tableLocation.start + 1, firstRowEndTR + 1);
1028
1029        // Skip the header-row, it was just saved in the previous line
1030        boolean first = true;
1031
1032
1033        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1034        // These temporary loop-variables are needed to do the CSS-ID insert (or lack-thereof)
1035        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1036
1037        ENTITY  entity = null;
1038        String  abbrev = this.tableType.abbrev; // Two-character CSS-ID abbreviation-string
1039
1040        boolean startingPosIsEnumOrCtorCheck =
1041            (this.tableType == Entity.ENUM_CONSTANT) ||
1042            (this.tableType == Entity.CONSTRUCTOR);
1043
1044        boolean detailsRemoved =
1045                ((this.tableType == Entity.METHOD)          && jdhf.methodDetailsRemoved)
1046            ||  ((this.tableType == Entity.CONSTRUCTOR)     && jdhf.constructorDetailsRemoved)
1047            ||  ((this.tableType == Entity.FIELD)           && jdhf.fieldDetailsRemoved)
1048            ||  ((this.tableType == Entity.ENUM_CONSTANT)   && jdhf.ecDetailsRemoved)
1049            ||  ((this.tableType == Entity.ANNOTATION_ELEM) && jdhf.aeDetailsRemoved);
1050
1051        // System.out.println
1052        //      ("Starting: " + BRED + "table has " + rows.size() + " rows." + RESET);
1053
1054        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1055        // Iterate the Summary <TABLE> rows, and insert them into 'tableRows' and 'rowEntites'
1056        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
1057        //
1058        // NOTE: This loop is *ALSO* where the Summary-Row CSS-ID is inserted.  An ID is not
1059        //       inserted (on the off chance / kind-of rare) that the relevant Details-Section
1060        //       was requested to be removed by the user.
1061
1062        for (Vector<HTMLNode> row : rows)
1063
1064            if (first) first = false;
1065
1066            else
1067            {
1068                // System.out.println("ROW HTML:\n" + Util.pageToString(row.html));
1069                String rowStr = extractSignature(row, this.tableType);
1070                // System.out.println("rowStr: " + BYELLOW + rowStr + RESET + '\n');
1071
1072
1073                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1074                // Here the List of HTML-Rows and the List of Row-ENTITY (Vector) are filled up
1075                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1076
1077                // This is the internal-Vector that contains all of the Summary-Table Row HTML
1078                this.tableRows.add(row);
1079
1080                // Use the "getter" to extract / retrieve the ENTITy (Method, Field, Constructor,
1081                // EnumConstant, etc...)
1082
1083                entity = getter.apply(rowStr);
1084
1085                // Save the ENTITY into the parallel 'rowEntities' Vector
1086                this.rowEntities.add(entity);
1087
1088
1089                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1090                // CSS Entity-Row-ID - This CSS-ID is used by the NavButtons Bar
1091                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
1092                //
1093                // This CSS-ID is inserted into the Summary-Row <A> Anchor: <A ID=entityID ...>
1094                // This CSS-ID is the exact same ID that is later added to the <A HREF=entityID>
1095                // for the Double-Up Arrow Button (⇈) of the corresponding ReflHTML Detail-Section
1096
1097                TagNode tn          = null;
1098                boolean insertedID  = false;
1099
1100                int i = startingPosIsEnumOrCtorCheck
1101                    ? 0
1102                    : TagNodeFind.nth(row, 2, TC.OpeningTags, "td", "th") + 1;
1103
1104                INNER:
1105                for (; i < row.size(); i++)
1106
1107                    if ((tn = row.elementAt(i).openTag()) != null)
1108                        if (tn.tok.equals("a"))
1109                        {
1110                            row.setElementAt(tn.setID(abbrev + entity.id, null), i);
1111                            insertedID = true;
1112                            break INNER;
1113                        }
1114
1115                if (! insertedID) if (! detailsRemoved) Messager.assertFailHTML(
1116                    "Failed to Insert CSS-ID [" + abbrev + entity.id + "] into Summary " +
1117                    "Table Row", rowStr
1118                );
1119            }
1120    }
1121
1122    // *** THIS MAY NEED TO CHANGE ***
1123    // CURRENTLY: In Java Doc for Java 11, the first two columns hold the return type and the
1124    //            rest of the signature.
1125    //
1126    // COPIED DIRECTLY FROM 'RearrangeEntitySummaries' CHANGED FOR USING 'dp' INSTEAD OF
1127    // Vector
1128
1129    private String extractSignature(Vector<HTMLNode> tableRow, Entity tableType)
1130    {
1131        Vector<DotPair> cols = TagNodeFindInclusive.all(tableRow, "td", "th");
1132
1133        StringBuffer    sb  = new StringBuffer();
1134        TextNode        txn = null;
1135
1136        DotPair dp = cols.elementAt(0);
1137
1138        for (int i=dp.start+1; i < dp.end; i++)
1139            if ((txn = tableRow.elementAt(i).ifTextNode()) != null)
1140                sb.append(txn.str);
1141
1142        // Enum-Constants have one row of 'constant-name' and then one row of description.  The
1143        // others have two rows: a row of 'type/modifiers' and a row of 'signature/name'
1144
1145        if (tableType == Entity.ENUM_CONSTANT) return sb.toString().trim();
1146
1147        // Constructors may have two or three rows.  If there is a modifier, then there are three,
1148        // if there are no modifiers for the constructors, then there are only two.  If there are
1149        // two, exit now
1150
1151        if (tableType == Entity.CONSTRUCTOR) if (cols.size() == 2) return sb.toString().trim();
1152
1153        sb.append(' ');
1154
1155        dp = cols.elementAt(1);
1156
1157        for (int i=dp.start+1; i < dp.end; i++)
1158            if ((txn = tableRow.elementAt(i).ifTextNode()) != null)
1159                sb.append(txn.str);
1160
1161        return sb.toString().trim();
1162    }
1163
1164
1165    // ********************************************************************************************
1166    // ********************************************************************************************
1167    // REBUILD THE JAVADOC PAGE
1168    // ********************************************************************************************
1169    // ********************************************************************************************
1170
1171
1172    // Used in the method below
1173    private static final TextNode NEW_LINE = new TextNode("\n");
1174
1175    // Method below too
1176    private static final Vector<Replaceable> EMPTY_VECTOR = new Vector<>();
1177
1178    Vector<Replaceable> allReplaceables()
1179    {
1180        // There are summary-tables whose only contents are the "Inherited Entities".  When that
1181        // occurs, the 'tableOpen' and 'tableClose' NodeIndex-instances will be null
1182
1183        if (tableOpen == null) return EMPTY_VECTOR;
1184
1185        Vector<HTMLNode>    newTable            = new Vector<>();
1186        DotPair             oldTableLocation    = new DotPair(tableOpen.index, tableClose.index);
1187
1188        newTable.add(tableOpen.n);
1189        newTable.add(NEW_LINE);
1190        newTable.addAll(headerRow);
1191        newTable.add(NEW_LINE);
1192
1193        for (Vector<HTMLNode> row : tableRows)
1194        {
1195            newTable.addAll(row);
1196            newTable.add(NEW_LINE);
1197        }
1198
1199        newTable.add(tableClose.n);
1200        newTable.add(NEW_LINE);
1201
1202        Vector<Replaceable> ret = new Vector<>();
1203        ret.add(cinzelH3);
1204        ret.add(Replaceable.create(oldTableLocation, newTable));
1205
1206        return ret;
1207    }
1208
1209
1210    // ********************************************************************************************
1211    // ********************************************************************************************
1212    // THE NEW-THING: Garbage-Collector Helper?
1213    // ********************************************************************************************
1214    // ********************************************************************************************
1215    // 
1216    // Does this help?  Is this "good" for the Garbage-Collect?  Is this going to speed it up,
1217    // or slow it down?  This is just a "C-Styled" FREE or DESTORY method...
1218    // It isn't publicly visible anyway...
1219
1220    void clear()
1221    {
1222        // public final TagNodeIndex tableOpen;
1223        if (tableOpen != null) tableOpen.n = null;
1224
1225        // public final TagNodeIndex tableClose;
1226        if (tableClose != null) tableClose.n = null;
1227    
1228        // final Vector<HTMLNode> headerRow;
1229        if (headerRow != null) headerRow.clear();
1230
1231        // final TagNodeIndex cinzelH3;
1232        if (cinzelH3 != null) cinzelH3.n = null;
1233    
1234        // private Vector<Vector<HTMLNode>> tableRows = new Vector<>();
1235        if (tableRows != null)
1236        {
1237            for (Vector<HTMLNode> v : tableRows) if (v != null) v.clear();
1238
1239            tableRows.clear();
1240            tableRows = null;
1241        }
1242    
1243        // private Vector<ENTITY> rowEntities = new Vector<>();
1244        if (rowEntities != null) { rowEntities.clear(); rowEntities = null; }
1245    }
1246
1247
1248    // ********************************************************************************************
1249    // ********************************************************************************************
1250    // DEBUG-PRINTING
1251    // ********************************************************************************************
1252    // ********************************************************************************************
1253
1254
1255    private static final String STARS =
1256        BYELLOW + "\n*****************************************\n" + RESET;
1257
1258    /**
1259     * Prints an abbreviated-version of the contents of this instance, to a user-provided
1260     * {@code Appendable}.  If the HTML requires more than four lines of text, only the first four
1261     * lines are printed.
1262     * 
1263     * @param a This may be any Java Appendable.  If an {@code IOException} is thrown while writing
1264     * to this {@code Appendable}, it will be caught an wrapped in an
1265     * {@code IllegalArgumentException}, with the {@code IOException} set as the {@code cause}.
1266     * 
1267     * @throws IllegalArgumentException If {@code 'a'} throws an {@code IOException}
1268     * 
1269     * @see StrPrint#firstNLines(String, int)
1270     * @see Util#pageToString(Vector)
1271     * @see StrIndent#indent(String, int)
1272     */
1273    public void debugPrint(Appendable a)
1274    {
1275        try
1276        {
1277            if (tableType != null) a.append
1278                (BCYAN + "this.tableType: " + RESET + this.tableType.toString() + "\n");
1279            else
1280                a.append(BRED + "this.tableType is null" + RESET);
1281
1282            if (tableOpen != null) a.append
1283                (BCYAN + "this.tableOpen: " + RESET + this.tableOpen.n.str + "\n");
1284            else
1285                a.append(BRED + "this.tableOpen is null" + RESET);
1286
1287            if (tableClose != null) a.append
1288                (BCYAN + "this.tableClose: " + RESET + this.tableClose.n.str + "\n");
1289            else
1290                a.append(BRED + "this.tableClose is null" + RESET);
1291
1292            if (cinzelH3 != null) a.append
1293                (BCYAN + "this.cinzelH3: " + RESET + this.cinzelH3.n.str + "\n");
1294            else
1295                a.append(BRED + "this.cinzelH3 is null" + RESET);
1296
1297            if (headerRow != null) a.append(
1298                STARS + BCYAN + "this.headerRow:" + RESET + STARS +
1299                StrPrint.firstNLines(Util.pageToString(headerRow), 4) +
1300                '\n'
1301            );
1302
1303            for (int i=0; i < tableRows.size(); i++)
1304
1305                a.append(
1306                    BCYAN + "TABLE ROW " + (i+1) + RESET + '\n' +
1307                    BGREEN + "HTML:\n" + RESET +
1308                    StrIndent.indent
1309                        (Util.pageToString(tableRows.elementAt(i)).replace("\n", "\\n"), 4) +
1310                    '\n' +
1311                    BGREEN + "ENTITY:\n" + RESET +
1312                    StrIndent.indent
1313                        (rowEntities.elementAt(i).toString(PF.UNIX_COLORS | PF.JOW_INSTEAD), 4) +
1314                    '\n'
1315                );
1316        }
1317        catch (java.io.IOException ioe)
1318        {
1319            throw new IllegalArgumentException(
1320                ioe
1321            );
1322        }
1323    }
1324
1325    
1326    /**
1327     * A really great way to view the contents of this class - <I>in just one page of text</I>.
1328     * 
1329     * @param numCharsWide The maximum line width to be printed to terminal.  This
1330     * number must be between 60 and 150, or else an exception shall throw.
1331     * 
1332     * @return The contents of this class-instance, as a {@code String}
1333     * 
1334     * @throws IllegalArgumentException If the parameter 'numCharsWide' was not passed a value 
1335     * within the aforementioned range.
1336     * 
1337     * @see StrPrint#printListAbbrev(Iterable, int, int, boolean, boolean, boolean)
1338     * @see StrPrint#printListAbbrev(Iterable, IntTFunction, int, int, boolean, boolean, boolean)
1339     */
1340    public String debugPrintDense(final int numCharsWide)
1341    {
1342        if ((numCharsWide < 60) || (numCharsWide > 150)) throw new IllegalArgumentException
1343            ("Parameter 'numCharsWide' wasn't passed a value between 60 and 150: " + numCharsWide);
1344
1345        return
1346            "rowEntities.size(): " + rowEntities.size() + '\n' +
1347            "rowEntities Vector Contents:" + // '\n' is automatically added
1348                StrPrint.printListAbbrev(rowEntities, numCharsWide, 4, false, true, true) + '\n' +
1349            "tableRows.size(): " + tableRows.size() + '\n' +
1350            "tableRows Vector Contents:" + // '\n' is automatically added
1351                StrPrint.printListAbbrev(
1352                    tableRows,
1353                    (int i, Vector<HTMLNode> tableRow) -> Util.pageToString(tableRow),
1354                    numCharsWide, 4, false, true, true
1355                );
1356    }
1357
1358    /**
1359     * Converts the contents of this class into a {@code String}
1360     * @return A Printable-{@code String}
1361     * @see #debugPrintDense(int)
1362     */
1363    public String toString()
1364    {
1365        return
1366            "tableType:  " + tableType + '\n' +
1367            "tableOpen:  " + tableOpen.toString() + '\n' +
1368            "tableClose: " + tableClose.toString() + '\n' +
1369            "headerRow:  " + StrPrint.abbrevEndRDSF(Util.pageToString(headerRow), 120, false) +
1370                '\n' +
1371            debugPrintDense(120);
1372    }
1373}