001package Torello.HTML.Tools.JavaDoc;
002
003import Torello.HTML.*;
004import Torello.HTML.NodeSearch.*;
005
006import Torello.Java.StrReplace;
007import Torello.Java.StringParse;
008import Torello.Java.UnreachableError;
009
010import Torello.Java.Shell.C;
011
012import java.util.*;
013import java.io.*;
014
015/**
016 * <B STYLE='color:darkred;'>Java Doc HTML-File Reader:</B>
017 * 
018 * Find and retrieve the entities of any of the five Java Doc generated Detail Sections.
019 * 
020 * <BR /><BR /><EMBED CLASS="external-html" DATA-FILE-ID=DET_MAIN_DESC>
021 */
022@StaticFunctional
023public class Details
024{
025    private Details() { }
026
027    /**
028     * <EMBED CLASS='external-html' DATA-FILE-ID=JD_CTOR_DM>
029     * <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_WIDGET DATA-P1=Constructor> 
030     */
031    protected static final String JAVADOC_CONSTRUCTOR_DETAIL_MARKER =
032        "==== CONSTRUCTOR DETAIL ====";
033
034    /**
035     * <EMBED CLASS='external-html' DATA-FILE-ID=JD_FIELD_DM>
036     * <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_WIDGET DATA-P1=Field> 
037     */
038    protected static final String JAVADOC_FIELD_DETAIL_MARKER =
039        "==== FIELD DETAIL ====";
040
041    /**
042     * <EMBED CLASS='external-html' DATA-FILE-ID=JD_METH_DM>
043     * <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_WIDGET DATA-P1=Method>  
044     */
045    protected static final String JAVADOC_METHOD_DETAIL_MARKER =
046        "==== METHOD DETAIL ====";
047
048    /**
049     * <EMBED CLASS='external-html' DATA-FILE-ID=JD_EC_DM> 
050     * <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_WIDGET DATA-P1='Enum Constant'> 
051     */
052    protected static final String JAVADOC_ENUM_CONST_DETAIL_MARKER =
053        "==== ENUM CONSTANT DETAIL ====";
054
055    /**
056     * <EMBED CLASS='external-html' DATA-FILE-ID=JD_AE_DM>
057     * <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_WIDGET DATA-P1='Element'>
058     */
059    protected static final String JAVADOC_ANNOTATION_ELEMENT_DETAIL_MARKER =
060        "==== ANNOTATION TYPE MEMBER DETAIL ====";
061
062    /**
063     * Converts a Java {@code 'Entity'} to one of the 'Detail Section' {@code MARKER String's}.
064     *
065     * @param section This may be any of the entities, except {@link Entity#INNER_CLASS}.
066     * 
067     * @return The appropriate {@code 'MARKER'}, all of which are listed in the 'Fields' section
068     * at the top of this class.
069     */
070    protected static String entityToMarker(Entity section)
071    {
072        if (section == null) throw new NullPointerException
073            ("You have passed null to parameter 'section'.  This is not allowed here.");
074
075        switch (section)
076        {
077            case METHOD:            return JAVADOC_METHOD_DETAIL_MARKER;
078            case FIELD:             return JAVADOC_FIELD_DETAIL_MARKER;
079            case CONSTRUCTOR:       return JAVADOC_CONSTRUCTOR_DETAIL_MARKER;
080            case ENUM_CONSTANT:     return JAVADOC_ENUM_CONST_DETAIL_MARKER;
081            case ANNOTATION_ELEM:   return JAVADOC_ANNOTATION_ELEMENT_DETAIL_MARKER;
082
083            case INNER_CLASS:
084                throw new DetailsException(
085                    "You have passed 'innerClass' to this method in class Details, but inner-" +
086                    "classes do not have a 'Detail' section."
087                );
088
089            default:
090                System.out.println("There are no other Entities.");
091                throw new UnreachableError();
092        }
093    }
094
095    /**
096     * All Detail-Marker {@code CommentNode} positions that are available on the page.
097     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
098     * @return The same {@code int[]} returned by {@code CommentNodeFind.all}
099     * @see CommentNodeFind
100     */
101    public static int[] allEntityMarkers(Vector<HTMLNode> javaDocHTMLCIETPage)
102    {
103        return CommentNodeFind.all(
104            javaDocHTMLCIETPage, TextComparitor.CN_OR,
105            JAVADOC_CONSTRUCTOR_DETAIL_MARKER,
106            JAVADOC_FIELD_DETAIL_MARKER,
107            JAVADOC_METHOD_DETAIL_MARKER,
108            JAVADOC_ENUM_CONST_DETAIL_MARKER,
109            JAVADOC_ANNOTATION_ELEMENT_DETAIL_MARKER
110        );
111    }
112
113
114    // ********************************************************************************************
115    // ********************************************************************************************
116    // Retrieve Details - Entire 'Details' Section
117    // ********************************************************************************************
118    // ********************************************************************************************
119
120
121    /**
122     * Retrieves all HTML description/explanation 'Detail Section' elements inside the provided
123     * page, for a specific type of detail.  If parameter {@code 'section'} receives
124     * {@code Entity.METHOD}, all of the HTML 'Method Details' will be provided, as instances of
125     * {@code SubSection}, in the returned {@code Vector}.
126     * 
127     * <BR /><BR /><B>NOTE:</B> This method is identical to
128     * {@link #sectionAllDetailsDP(Vector, Entity)}, except that it returns {@link SubSection}
129     * instances, rather than {@link DotPair} instances.
130     * 
131     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
132     * 
133     * @param section Specifies which 'Detail Section' is being requested.  Note that 
134     * {@code Entity.INNER_CLASS} may not be used here.
135     * 
136     * @return A call to a {@code Peek} method is made, so this means that {@code SubSection} is
137     * being returned.  The {@code Vector<SubSection>} will contain the HTML, and the location in
138     * the page {@code Vector} for every detail (HTML Explanation) available in the specified
139     * 'Detail Section'.
140     * 
141     * @see #hasAnnotationElemDetails(Vector)
142     * @see #detailsSection(Vector, String)
143     * @see InnerTagPeekInclusive
144     * 
145     * @throws DetailsException If {@code Entity.INNER_CLASS} is pssed to parameter
146     * {@code 'section'}
147     */
148    public static Vector<SubSection> sectionAllDetails
149        (Vector<HTMLNode> javaDocHTMLCIETPage, Entity section)
150    {
151        // The Annotation Element Details have HTML that differs slightly from the other four
152        // detail sections for the other four 'Entities'
153
154        if (section == Entity.ANNOTATION_ELEM)
155        {
156            DotPair aeDetailsSection = hasAnnotationElemDetails(javaDocHTMLCIETPage);
157
158            if (aeDetailsSection == null) return new Vector<>();
159
160            return InnerTagPeekInclusive.all(
161                javaDocHTMLCIETPage, aeDetailsSection.start, aeDetailsSection.end,
162                "section", "role", TextComparitor.EQ, "region"
163            );
164        }
165        else
166        {
167            DotPair detailsSection = detailsSection(javaDocHTMLCIETPage, entityToMarker(section));
168
169            if (detailsSection == null) return new Vector<>();
170
171            return InnerTagPeekInclusive.all(
172                javaDocHTMLCIETPage, detailsSection.start, detailsSection.end,
173                "ul", "class", TextComparitor.C, "blockList", "blockListLast"
174            );
175        }
176    }
177
178    /**
179     * Retrieves all HTML description/explanation 'Detail Section' elements inside the provided
180     * page, for a specific type of detail.  If parameter {@code 'section'} receives
181     * {@code Entity.METHOD}, all of the HTML 'Method Details' will be provided, as instances of
182     * {@code SubSection}, in the returned {@code Vector}.
183     * 
184     * <BR /><BR /><B>NOTE:</B> This method is identical to
185     * {@link #sectionAllDetails(Vector, Entity)}, except that it returns {@link DotPair}
186     * instances, rather than {@link SubSection} instances.
187     * 
188     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
189     * 
190     * @param section Specifies which 'Detail Section' is being requested.  Note that 
191     * {@code Entity.INNER_CLASS} may not be used here.
192     * 
193     * @return A call to a {@code Find} method is made, so this means that {@code DotPair} is
194     * being returned.  The {@code Vector<DotPair>} will contain the HTML, and the location in
195     * the page {@code Vector} for every detail (HTML Explanation) available in the specified
196     * 'Detail Section'.
197     * 
198     * @see #hasAnnotationElemDetails(Vector)
199     * @see #detailsSection(Vector, String)
200     * @see InnerTagFindInclusive
201     * 
202     * @throws DetailsException If {@code Entity.INNER_CLASS} is pssed to parameter
203     * {@code 'section'}
204     */
205    public static Vector<DotPair> sectionAllDetailsDP
206        (Vector<HTMLNode> javaDocHTMLCIETPage, Entity section)
207    {
208        // The Annotation Element Details have HTML that differs slightly from the other four
209        // detail sections for the other four 'Entities'
210
211        if (section == Entity.ANNOTATION_ELEM)
212        {
213            DotPair aeDetailsSection = hasAnnotationElemDetails(javaDocHTMLCIETPage);
214
215            if (aeDetailsSection == null) return new Vector<>();
216
217            return InnerTagFindInclusive.all(
218                javaDocHTMLCIETPage, aeDetailsSection.start, aeDetailsSection.end,
219                "section", "role", TextComparitor.EQ, "region"
220            );
221        }
222        else
223        {
224            DotPair detailsSection = detailsSection(javaDocHTMLCIETPage, entityToMarker(section));
225
226            if (detailsSection == null) return new Vector<>();
227
228            return InnerTagFindInclusive.all(
229                javaDocHTMLCIETPage, detailsSection.start, detailsSection.end,
230                "ul", "class", TextComparitor.C, "blockList", "blockListLast"
231            );
232        }
233    }
234
235    /**
236     * <EMBED CLASS="external-html" DATA-FILE-ID=JD_HAS_DET>
237     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
238     * @return An instance of {@code class DotPair} that points to the begin and end index
239     * locations of input parameter {@code 'javaDocHTMLCIETPage'} were the primary <B>'Details
240     * Section'</B> resides.
241     * @see Torello.HTML.NodeSearch.InnerTagFindInclusive
242     */
243    public static DotPair hasDetails(Vector<HTMLNode> javaDocHTMLCIETPage)
244    {
245        return InnerTagFindInclusive.first
246            (javaDocHTMLCIETPage, "div", "class", TextComparitor.C, "details");
247    }
248
249    /**
250     * This will return a specific Java Doc Details Section on a Java Doc Generated HTML
251     * page.  This class is used internally.
252     * 
253     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
254     * 
255     * @param commentMarker This must be one of the five {@code 'MARKER' String's}, which
256     * are the {@code static} constants defined at the top of this class.  This marker will
257     * denote which JavaDoc Details Section is being requested.
258     * 
259     * @return This will return an index-pointer pair to an HTML {@code <UL>} and
260     * {@code </UL>} opening-closing pair.  This HTML {@code <UL>}-pointer should be
261     * the requested Details Section.
262     * 
263     * <BR /><BR />Null will be returned if there is no {@code CommentNode} containing the
264     * {@code 'commentMarker'}, or if - once that {@code CommentNode} is found - there is not
265     * {@code <UL CLASS='blockList'>} element found in the vicinity.
266     * 
267     * @see CommentNodeFind
268     * @see InnerTagFindInclusive
269     */
270    protected static DotPair detailsSection
271        (Vector<HTMLNode> javaDocHTMLCIETPage, String commentMarker)
272    {
273        int pos = CommentNodeFind.first
274            (javaDocHTMLCIETPage, TextComparitor.CN_CI, commentMarker);
275
276        if (pos == -1) return null;
277
278        DotPair ret = InnerTagFindInclusive.first
279            (javaDocHTMLCIETPage, pos, -1, "ul", "class", TextComparitor.C, "blockList");
280
281        // Make sure a <TABLE CLASS="memberSummary"...> was found, and that it is in the
282        // CLOSE VICINITY of pos - OTHERWISE return null;
283        if ((ret == null) || ((ret.start - pos) > 25)) return null;
284
285        return ret;
286    }
287
288    /**
289     * This method will retrieve an {@code HNLIInclusive Iterator} that iterates the unordered
290     * lists of any details section which is passed to this method.
291     * 
292     * <EMBED CLASS='external-html' DATA-FILE-ID=DET_ITER_EX>
293     * 
294     * <BR /><BR /><B STYLE='color: red;'>WARNING:</B> <I>This method cannot be used to retrieve
295     * details for {@code Annotation Elements}!</I>  The HTML for these details are wrapped in 
296     * something that differs (albeit very slightly).  To retrieve the specific details elements
297     * for {@code Annotation Element}, use the method
298     * {@link #annotationElemDetailsIterator(Vector)}
299     * 
300     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
301     * 
302     * @param detailsSection This instance of {@code DotPair} <I>should contain a complete
303     * Java Doc {@code 'Details'} section!</I>  This index-pointer pair should be retrieved
304     * from the {@code 'has'} methods in this class.  If an incorrect pointer is passed here,
305     * an exception is thrown!
306     * 
307     * @return This will return an instance of the 'HTML Node List Inclusive Iterator.'  This
308     * {@code Iterator} has a suite of methods that facilitate retrieving the contents of a
309     * particular element in the underlying HTML {@code Vector's} Unordered Lists. 
310     * 
311     * @throws DetailsException If the reference passed to {@code 'detailsSection'} is null,
312     * or if it does not point to a proper opening and closing HTML {@code <UL>} element.
313     * See the code included below to view the range of possible exception throws.
314     * 
315     * @see InnerTagInclusiveIterator
316     * @see TagNodeExpectedException
317     * @see OpeningTagNodeExpectedException
318     * @see ClosingTagNodeExpectedException
319     * @see HTMLTokException
320     */
321    public static HNLIInclusive detailsIterator
322        (Vector<HTMLNode> javaDocHTMLCIETPage, DotPair detailsSection)
323    {
324        if (javaDocHTMLCIETPage == null)
325            throw new NullPointerException("Parameter 'javaDocHTMLCIETPage' may not be null.");
326
327        if (detailsSection == null) throw new DetailsException(
328            "The Details Section Iterator you have requested cannot be built without a proper " +
329            "index-pointer 'DotPair' instance which points to a Details Section on the page " +
330            "you have passed to 'javadocHTMLCIETPage'.  The reference you have passed to " +
331            "'detailsSection' is null."
332        );
333
334        try
335        {
336            // Temporary Variables, used to do a few (quick) checks
337            HTMLNode    n;
338            TagNode     tn;
339    
340            n = javaDocHTMLCIETPage.elementAt(detailsSection.start);
341
342            if (! (n instanceof TagNode)) throw new TagNodeExpectedException(
343                "The HTMLNode at index 'detailsSection.start' did not contain a TagNode, but " +
344                "rather a " + n.getClass().getSimpleName()
345            );
346
347            tn = (TagNode) n;
348
349            if (tn.isClosing) throw new OpeningTagNodeExpectedException(
350                "The TagNode at index 'detailsSection.start' was a closing element whose " +
351                "'.isClosing' field was true.  This should be an HTML Opening <UL ...> " +
352                "element"
353            );
354
355            if (! tn.tok.equals("ul")) throw new HTMLTokException(
356                "The TagNode at index 'detailsSection.start' was not an HTML <UL> element " +
357                "because its '.tok' field was not \"ul\", but rather \"" + tn.tok + "\""
358            );
359
360            n = javaDocHTMLCIETPage.elementAt(detailsSection.end);
361
362            if (! (n instanceof TagNode)) throw new TagNodeExpectedException(
363                "The HTMLNode at index 'detailsSection.end' did not contain a TagNode, but " +
364                "rather a " + n.getClass().getSimpleName()
365            );
366
367            tn = (TagNode) n;
368
369            if (! tn.isClosing) throw new ClosingTagNodeExpectedException(
370                "The TagNode at index 'detailsSection.end' was an opening element whose " +
371                "'.isClosing' field was false.  This should be an HTML Opening </UL> " +
372                "element"
373            );
374
375            if (! tn.tok.equals("ul")) throw new HTMLTokException(
376                "The TagNode at index 'detailsSection.end' was not an HTML </UL> element " +
377                "because its '.tok' field was not \"ul\", but rather \"" + tn.tok + "\""
378            );
379        }
380        catch (Exception e)
381        {
382            throw new DetailsException(
383                "There was a problem with the DotPair Vector-index pointer you have passed  " +
384                "(parameter 'detailsSection').  This DotPair should contain a valid Detail " +
385                "Section Pointer for the Java Doc Web Page you have passed, but it did not.  " +
386                "Please see this exception getCause() method for more information.", e
387            );
388        }
389
390        // Actually building the iterator is really easy.  It is one line, followed by the
391        // cursor-restriction method-call!
392        HNLIInclusive ret = InnerTagInclusiveIterator.get(javaDocHTMLCIETPage,
393            "ul", "class", TextComparitor.C, "blockList", "blockListLast");
394
395        // '+ 1' is needed since there is an "outer <UL class='blockList'>" TagNode
396        // ==>  The "Enumerated-Constant Details (entire) Section" is 
397        //      also a <UL CLASS='blockList'> too!
398        ret.restrictCursor(detailsSection.start + 1, detailsSection.end);
399
400        return ret;
401    }
402
403    /**
404     * This is a helper method that is used by the {@code 'iterator'} Convenience Methods
405     * defined in this class.
406     * 
407     * <BR /><BR />Note that it is (likely) much more efficient to invoke the
408     * {@link #detailsIterator(Vector, DotPair)} method directly - <I>assuming you have already
409     * obtained a valid {@code DotPair} instance of the requisite 'Details Section' (using one of
410     * the {@code 'has'} methods!)</I>
411     * 
412     * <BR /><BR /><B STYLE='color:red;'>WARNING:</B> Do not invoke this method with the
413     * {@code 'commentMarker'} {@link #JAVADOC_ANNOTATION_ELEMENT_DETAIL_MARKER}.  
414     * {@code Annotation Details} use HTML that differs (slightly) from the other details sections.
415     * You must use the method {@link #annotationElemDetailsIterator(Vector)}, instead.
416     * 
417     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
418     * 
419     * @param commentMarker This Java {@code String} should be any one of the listed 
420     * {@code static, final} 'Comment Marker' {@code String's}, <I>all of which are defined at
421     * the top of this class.</I>
422     * 
423     * @return This will return a {@code 'Details Section Iterator'} that iterates the table
424     * rows (a.k.a. 'The Summaries') in the specified {@code 'Details Section'}.
425     * 
426     * @throws DetailsException This will throw if the specified 'Details Section' isn't
427     * found.
428     * 
429     * @see #detailsSection(Vector, String)
430     * @see #detailsIterator(Vector, DotPair)
431     */
432    protected static HNLIInclusive detailsIterator
433        (Vector<HTMLNode> javaDocHTMLCIETPage, String commentMarker)
434    {
435        DotPair dp = detailsSection(javaDocHTMLCIETPage, commentMarker);
436
437        if (dp == null) throw new DetailsException(
438            "The detail-section iterator you have requested cannot be built.  There was no " +
439            "Detail Section that matches the 'commentMarker' parameter you have passed (or " +
440            "you have not passed a valid comment marker).  Did you use one of the markers " +
441            "which are defined as static-final fields at the top of this class?"
442        );
443
444        return detailsIterator(javaDocHTMLCIETPage, dp);
445    }
446
447
448    // ********************************************************************************************
449    // ********************************************************************************************
450    // Constructor Details Section
451    // ********************************************************************************************
452    // ********************************************************************************************
453
454
455    /**
456     * <EMBED CLASS=defs DATA-P1=Constructor>
457     * <EMBED CLASS="external-html" DATA-FILE-ID=JD_CTOR_DET>
458     * <EMBED CLASS="external-html" DATA-FILE-ID=DETAIL_WIDGET> <!-- local vars -->
459     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
460     * @return <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_DP> <!-- local vars -->
461     * @see #detailsSection(Vector, String)
462     * @see #JAVADOC_CONSTRUCTOR_DETAIL_MARKER
463     */
464    public static final DotPair hasConstructorDetails (Vector<HTMLNode> javaDocHTMLCIETPage)
465    { return detailsSection(javaDocHTMLCIETPage, JAVADOC_CONSTRUCTOR_DETAIL_MARKER); }
466
467    /**
468     * Convenience Method.
469     * <BR />Invokes: {@link #detailsIterator(Vector, String)}
470     * <BR />Passes: {@link #JAVADOC_CONSTRUCTOR_DETAIL_MARKER}
471     * <BR /><B STYLE='color:red'>IMPORTANT:</B> If you have called {@code hasConstructorDetails}
472     * already, it is more efficient to invoke {@link #detailsIterator(Vector, DotPair)}
473     * directly, using that {@code DotPair} instead.
474     */
475    public static HNLIInclusive constructorDetailsIterator(Vector<HTMLNode> javaDocHTMLCIETPage)
476    { return detailsIterator(javaDocHTMLCIETPage, JAVADOC_CONSTRUCTOR_DETAIL_MARKER); }
477
478
479    // ********************************************************************************************
480    // ********************************************************************************************
481    // Field Details Section
482    // ********************************************************************************************
483    // ********************************************************************************************
484
485
486    /**
487     * <EMBED CLASS=defs DATA-P1=Field>
488     * <EMBED CLASS="external-html" DATA-FILE-ID=JD_FIELD_DET>
489     * <EMBED CLASS="external-html" DATA-FILE-ID=DETAIL_WIDGET> <!-- local vars -->
490     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
491     * @return <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_DP> <!-- local vars -->
492     * @see #detailsSection(Vector, String)
493     * @see #JAVADOC_FIELD_DETAIL_MARKER
494     */
495    public static final DotPair hasFieldDetails(Vector<HTMLNode> javaDocHTMLCIETPage)
496    { return detailsSection(javaDocHTMLCIETPage, JAVADOC_FIELD_DETAIL_MARKER); }
497
498    /**
499     * Convenience Method.
500     * <BR />Invokes: {@link #detailsIterator(Vector, String)}
501     * <BR />Passes: {@link #JAVADOC_FIELD_DETAIL_MARKER}
502     * <BR /><B STYLE='color:red'>IMPORTANT:</B> If you have called {@code hasFieldDetails}
503     * already, it is more efficient to invoke {@link #detailsIterator(Vector, DotPair)}
504     * directly, using that {@code DotPair} instead.
505     */
506    public static HNLIInclusive fieldDetailsIterator(Vector<HTMLNode> javaDocHTMLCIETPage)
507    { return detailsIterator(javaDocHTMLCIETPage, JAVADOC_FIELD_DETAIL_MARKER); }
508
509
510    // ********************************************************************************************
511    // ********************************************************************************************
512    // Method Details Section
513    // ********************************************************************************************
514    // ********************************************************************************************
515
516
517    /**
518     * <EMBED CLASS=defs DATA-P1=Method>
519     * <EMBED CLASS="external-html" DATA-FILE-ID=JD_METH_DET>
520     * <EMBED CLASS="external-html" DATA-FILE-ID=DETAIL_WIDGET> <!-- local vars -->
521     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
522     * @return <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_DP> <!-- local vars -->
523     * @see #detailsSection(Vector, String)
524     * @see #JAVADOC_METHOD_DETAIL_MARKER
525     */
526    public static final DotPair hasMethodDetails(Vector<HTMLNode> javaDocHTMLCIETPage)
527    { return detailsSection(javaDocHTMLCIETPage, JAVADOC_METHOD_DETAIL_MARKER); }
528
529    /**
530     * Convenience Method.
531     * <BR />Invokes: {@link #detailsIterator(Vector, String)}
532     * <BR />Passes: {@link #JAVADOC_METHOD_DETAIL_MARKER}
533     * <BR /><B STYLE='color:red'>IMPORTANT:</B> If you have called {@code hasMethodDetails}
534     * already, it is more efficient to invoke {@link #detailsIterator(Vector, DotPair)}
535     * directly, using that {@code DotPair} instead.
536     */
537    public static HNLIInclusive methodDetailsIterator(Vector<HTMLNode> javaDocHTMLCIETPage)
538    { return detailsIterator(javaDocHTMLCIETPage, JAVADOC_METHOD_DETAIL_MARKER); }
539
540
541    // ********************************************************************************************
542    // ********************************************************************************************
543    // Enum Constant Details Section
544    // ********************************************************************************************
545    // ********************************************************************************************
546
547
548    /**
549     * <EMBED CLASS=defs DATA-P1='Enum Constant'>
550     * <EMBED CLASS="external-html" DATA-FILE-ID=JD_EC_DET>
551     * <EMBED CLASS="external-html" DATA-FILE-ID=DETAIL_WIDGET>  <!-- local vars -->
552     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
553     * @return <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_DP> <!-- local vars -->
554     * @see #detailsSection(Vector, String)
555     * @see #JAVADOC_ENUM_CONST_DETAIL_MARKER
556     */
557    public static final DotPair hasEnumConstDetails(Vector<HTMLNode> javaDocHTMLCIETPage)
558    { return detailsSection(javaDocHTMLCIETPage, JAVADOC_ENUM_CONST_DETAIL_MARKER); }
559
560    /**
561     * Convenience Method.
562     * <BR />Invokes: {@link #detailsIterator(Vector, String)}
563     * <BR />Passes: {@link #JAVADOC_ENUM_CONST_DETAIL_MARKER}
564     * <BR /><B STYLE='color:red'>IMPORTANT:</B> If you have called {@code hasEnumConstDetails}
565     * already, it is more efficient to invoke {@link #detailsIterator(Vector, DotPair)}
566     * directly, using that {@code DotPair} instead.
567     */
568    public static HNLIInclusive enumConstDetailsIterator(Vector<HTMLNode> javaDocHTMLCIETPage)
569    { return detailsIterator(javaDocHTMLCIETPage, JAVADOC_ENUM_CONST_DETAIL_MARKER); }
570
571
572    // ********************************************************************************************
573    // ********************************************************************************************
574    // Annotation Element Details Section
575    // ********************************************************************************************
576    // ********************************************************************************************
577
578
579    /**
580     * <EMBED CLASS=defs DATA-P1=Element>
581     * <EMBED CLASS="external-html" DATA-FILE-ID=JD_AE_DET> 
582     * <EMBED CLASS="external-html" DATA-FILE-ID=DETAIL_WIDGET> <!-- local vars -->
583     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
584     * @return <EMBED CLASS='external-html' DATA-FILE-ID=DETAIL_DP> <!-- local vars -->
585     * @see Torello.HTML.NodeSearch.CommentNodeFind
586     * @see Torello.HTML.NodeSearch.InnerTagFind
587     * @see Util.Inclusive#find(Vector, int)
588     * @see #JAVADOC_ANNOTATION_ELEMENT_DETAIL_MARKER
589     */
590    public static final DotPair hasAnnotationElemDetails(Vector<HTMLNode> javaDocHTMLCIETPage)
591    {
592        int elemDetailsPos = CommentNodeFind.first
593            (javaDocHTMLCIETPage, TextComparitor.CN_CI, JAVADOC_ANNOTATION_ELEMENT_DETAIL_MARKER);
594
595        if (elemDetailsPos == -1) return null;
596
597        // NOTE: We use 'last' and 'elemDetailsPos' as the endPos here (slightly different)
598        int sPos = InnerTagFind.last(
599            javaDocHTMLCIETPage, 0, elemDetailsPos, "ul", "class",
600            TextComparitor.C, "blockList"
601        );
602
603        if (sPos == -1) return null;
604
605        int ePos = Util.Inclusive.find(javaDocHTMLCIETPage, sPos);
606
607        if (ePos == -1) return null;
608
609        return new DotPair(sPos, ePos);
610    }
611
612    /**
613     * <EMBED CLASS='external-html' DATA-FILE-ID=JD_AE_ITER>
614     * 
615     * @param javaDocHTMLCIETPage <EMBED CLASS="external-html" DATA-FILE-ID=JDHCIETP>
616     * 
617     * @return This will return an instance of the 'HTML Node List Inclusive Iterator.'  This
618     * {@code Iterator} has a suite of methods that facilitate retrieving the contents of an
619     * {@code Element Details} section's Unordered Lists.
620     * 
621     * <BR /><BR />The {@code <UL>} elements iterated contain {@code Annotation Element}
622     * explanations &amp; definitions.
623     * 
624     * @see Torello.HTML.NodeSearch.InnerTagInclusiveIterator
625     * @see #hasAnnotationElemDetails(Vector)
626     * @throws DetailsException If there is not {@code Element Details} section on this page.
627     */
628    public static HNLIInclusive annotationElemDetailsIterator(Vector<HTMLNode> javaDocHTMLCIETPage)
629    {
630        DotPair annotationElemDetailsSection = hasAnnotationElemDetails(javaDocHTMLCIETPage);
631
632        if (annotationElemDetailsSection == null) throw new DetailsException(
633            "The detail-section iterator you have requested cannot be built.  There was no " +
634            "Annotation Element Detail Section on this page."
635        );
636
637        HNLIInclusive ret = InnerTagInclusiveIterator.get
638            (javaDocHTMLCIETPage, "section", "role", TextComparitor.EQ, "region");
639
640        ret.restrictCursor(annotationElemDetailsSection);
641
642        return ret;
643    }
644
645
646    // ********************************************************************************************
647    // ********************************************************************************************
648    // Package Private Remove Details
649    // ********************************************************************************************
650    // ********************************************************************************************
651
652
653    // Package Private.  This is done in JavaDocHTMLFile, through the 'Upgrade' Configuration
654    // Predicates
655    //
656    // MESSAGER: ONLY 'println' / 'isVerbose'
657
658    static void removeAllDetails(Vector<HTMLNode> fileVec)
659    {
660        int numDetailNodesRemoved = InnerTagRemoveInclusive.first
661            (fileVec, "div", "class", TextComparitor.C, "details");
662
663        if (Messager.isVerbose()) Messager.println(
664            '\t' + StringParse.rightSpacePad("Removed: ", 25) + C.BRED +
665            "[" + StringParse.zeroPad10e4(numDetailNodesRemoved) +
666            "]" + C.RESET + " description section nodes."
667        );
668
669        // Finds all "relative links" on the page.  These are the ones that point to the method
670        // Details, and all of them need to be removed
671        Vector<DotPair> links =
672            InnerTagFindInclusive.all(fileVec, "a", "href", TextComparitor.SW, "#");
673
674        // Convert the list of start-and-end points to an integer array.
675        int[] linksPos = DotPair.endPointsToPosArray(links, true);
676
677        // Remove them!  AGAIN: These are the links to the "Method Details" in the NodeSearch
678        // classes.  Remember - The Method Details are removed from the NodeSearch classes
679        Util.removeNodesOPT(fileVec, linksPos);
680
681        if (Messager.isVerbose()) Messager.println(
682            '\t' + StringParse.rightSpacePad("Removed: ", 25) + C.BRED +
683            "[" + StringParse.zeroPad10e4(linksPos.length) +
684            "]" + C.RESET + " Summary (<A HREF=>...</A>) Anchor Nodes."
685        );
686    }
687
688    // Package Private.  This is done in JavaDocHTMLFile, through the 'Upgrade' Configuration
689    // Predicates
690    //
691    // MESSAGER: ONLY 'println' / 'isVerbose'
692
693    static void removeAllDetails
694        (Vector<HTMLNode> javaDocHTMLCIETPage, Entity entity)
695    {
696        // This should never happen.  It is called in JavaDocHTMLFile, and that class does not
697        // use INNER_CLASS as the entity.
698        if (entity == Entity.INNER_CLASS) throw new DetailsException(
699            "INNER_CLASS' was passed to parameter 'entity', but Inner Classes do not have a " +
700            "Detail Section"
701        );
702
703        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
704        // Removes the entire detail-descriptions for the specific section/entity
705        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
706
707        // This gets the location for the "Comment Node Marker" for the specific 'Detail Section'
708        // that has been slated for removal.
709        int detailsMarkerPos =
710            CommentNodeFind.first(javaDocHTMLCIETPage, TextComparitor.CN, entityToMarker(entity));
711
712        // There is not details section on this page for the specified 'entity' (Method, Field
713        // Constructor, etc...)
714        if (detailsMarkerPos == -1) return;
715
716        // Get rid of the marker comment!
717        javaDocHTMLCIETPage.removeElementAt(detailsMarkerPos);
718
719        // The "Detail Section" that should be removed is wrapped in a 
720        // <SECTION ROLE='region'> ... </SECTION> HTML Tag.
721        // REMOVE IT, THAT'S ALL
722        int removed = InnerTagRemoveInclusive.first(
723            javaDocHTMLCIETPage, detailsMarkerPos, -1, "section", "role",
724            TextComparitor.EQ_CI, "region"
725        );
726
727        if (Messager.isVerbose()) Messager.println(
728            "Removed: " + C.BRED +
729            "[" + StringParse.zeroPad10e4(removed) +
730            "] " + C.RESET + entity.toString() + " Details Nodes."
731        );
732
733        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
734        // Removes the <A HREF=...> for the summary-descriptions inside the **SUMMARY-SECTION***
735        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
736
737        Vector<DotPair> links = null;
738
739        if (entity != Entity.ANNOTATION_ELEM)
740        {
741            // This gets the location for the "Comment Node Marker" for the specific
742            // 'Summary Section' that has been slated for removal.
743
744            int summaryMarkerPos = CommentNodeFind.first(
745                javaDocHTMLCIETPage, TextComparitor.CN,
746                /* Summaries. */ HELPER.entityToMarker(entity)
747            );
748
749            // Theoretically, this can never happen, so throw an exception.
750            if (summaryMarkerPos == -1) throw new DetailsException(
751                "There seems to be a " + entity.toString() + " Details Section, but not a " +
752                entity.toString() + " Summary Section.  Java Doc Error."
753            );
754
755            // This gets the entire <SECTION ROLE='region'> ... </SECTION> which holds the entire
756            // summary table for a specific section-entity.  (Fields, Methods, Constructors, etc..)
757            DotPair summDP  = InnerTagFindInclusive.first(
758                javaDocHTMLCIETPage, summaryMarkerPos, -1, "section", "role",
759                TextComparitor.EQ_CI, "region"
760            );
761
762            // This removes the <A HREF=...> for all of the links in the summary section.
763            links = InnerTagFindInclusive.all(
764                javaDocHTMLCIETPage, summDP.start, summDP.end,
765                "a", "href", TextComparitor.SW, "#"
766            );
767        }
768        // Annotaton Elements have two types of summaries section.
769        // Carbon copy of the above stuff, but done twice
770        else
771        {
772            links = new Vector<>();
773
774            int summaryMarkerPos = CommentNodeFind.first(
775                javaDocHTMLCIETPage, TextComparitor.CN,
776                // Summaries.JAVADOC_REQUIRED_ANNOTATION_ELEMENT_SUMMARY_MARKER
777                "==== ANNOTATION TYPE REQUIRED MEMBER SUMMARY ===="
778            );
779
780            if (summaryMarkerPos != -1)
781            {
782                DotPair summDP  = InnerTagFindInclusive.first(
783                    javaDocHTMLCIETPage, detailsMarkerPos, -1, "section", "role",
784                    TextComparitor.EQ_CI, "region"
785                );
786
787                if (summDP != null)
788                    links.addAll(InnerTagFindInclusive.all(
789                        javaDocHTMLCIETPage, summDP.start, summDP.end,
790                        "a", "href", TextComparitor.SW, "#"
791                    ));
792            }
793
794            summaryMarkerPos = CommentNodeFind.first(
795                javaDocHTMLCIETPage, TextComparitor.CN,
796                // Summaries.JAVADOC_OPTIONAL_ANNOTATION_ELEMENT_SUMMARY_MARKER
797                "==== ANNOTATION TYPE OPTIONAL MEMBER SUMMARY ===="
798            );
799
800            if (summaryMarkerPos != -1)
801            {
802                DotPair summDP  = InnerTagFindInclusive.first(
803                    javaDocHTMLCIETPage, detailsMarkerPos, -1, "section", "role",
804                    TextComparitor.EQ_CI, "region"
805                );
806
807                if (summDP != null)
808                    links.addAll(InnerTagFindInclusive.all(
809                        javaDocHTMLCIETPage, summDP.start, summDP.end,
810                        "a", "href", TextComparitor.SW, "#"
811                    ));
812            }
813        }
814
815        // This should never happen.  It is better to throw an informative exception, rather
816        // than an NPE, or meaningless one.
817        if ((links == null) || (links.size() == 0)) throw new DetailsException(
818            "There was either no " + entity.toString() + " Summary Exception or that section " +
819            "was empty."
820        );
821
822        // Only remove the anchors, not  the text.
823        int[] linksPos = DotPair.endPointsToPosArray(links, true);
824    
825        // Remove them!
826        Util.removeNodesOPT(javaDocHTMLCIETPage, linksPos);
827
828        if (Messager.isVerbose()) Messager.println(
829            "Removed: " + C.BRED +
830            "[" + StringParse.zeroPad10e4(linksPos.length) +
831            "] " + C.RESET + entity.toString() + " Summary Anchor (<A HREF=>...</A>) Nodes."
832        );
833    }
834}