001package Torello.HTML.Tools.JavaDoc;
002
003import Torello.HTML.*;
004import Torello.HTML.NodeSearch.*;
005import Torello.Java.StrCmpr;
006
007import java.util.*;
008
009/**
010 * Exception that may be thrown when erroneous-input is provided to class <B>{@link Details}</B>
011 * or <B>{@link ReflHTML}</B>.  These classes throw exceptions, rather than printing errors to
012 * the messager, since they may be called, externally, by the end-users.  Those classes are not 
013 * strictly limited to internal-use.
014 * 
015 * @see Details
016 * @see ReflHTML
017 */
018public class DetailsException extends IllegalArgumentException
019{
020    /** <EMBED CLASS="external-html" DATA-FILE-ID="SVUIDEX">  */
021    public static final long serialVersionUID = 1;
022
023    /**
024     * This is a helpful message explaining how to ensure that a sub-section of a vectorized-HTML
025     * Documentation Web-Page is properly formatted according to the 'details' section of a
026     * Java-Doc page.
027     */
028    protected static final String PLEASE_USE =
029        "Please use the Details iterator(); Methods to retrieve a details section for a " +
030        "Method, Field, Constructor or Enumerated-Constant.";
031
032    /**
033     * This is the message used for explaining how to retrieve an iterator of the 'details'
034     * section for an Annotation Java-Doc page.
035     */
036    protected static final String PLEASE_USE_ANNOT =
037        "Please use the Details iterator(); Methods to retrieve a details section for " +
038        "the Annotation Elements.";
039
040    /** Constructs a {@code DetailsException} with no detail message. */
041    public DetailsException()
042    { super(); }
043
044    /**
045     * Constructs a {@code DetailsException} with the specified detail message.
046     * @param message the detail message.
047     */
048    public DetailsException(String message)
049    { super(message); }
050
051    /**
052     * Constructs a new exception with the specified detail message and cause.
053     * 
054     * <BR /><BR /><B>NOTE:</B> The detail message associated with cause is not automatically
055     * incorporated in this exception's detail message.
056     * 
057     * @param message The detail message (which is saved for later retrieval by the
058     * {@code Throwable.getMessage()} method).
059     * 
060     * @param cause the cause (which is saved for later retrieval by the
061     * {@code Throwable.getCause()} method). (A null value is permitted, and indicates that the
062     * cause is nonexistent or unknown.)
063     */
064    public DetailsException(String message, Throwable cause)
065    { super(message, cause); }
066
067    /**
068     * Constructs a new exception with the specified cause and a detail message of
069     * {@code (cause==null ? null : cause.toString())} (which typically contains the class and
070     * detail message of cause). This constructor is useful for exceptions that are little more
071     * than wrappers for other throwables.
072     * 
073     * @param cause The cause (which is saved for later retrieval by the
074     * {@code Throwable.getCause()} method). (A null value is permitted, and indicates that the
075     * cause is nonexistent or unknown.)
076     */
077    public DetailsException(Throwable cause)
078    { super(cause); }
079
080    /**
081     * This check method is used to ensure that a passed-parameter vectorized-HTML sub-page to one
082     * of the {@code DetailsPartMethods, DetailsPartConstructors} or {@code DetailsPartFields} is a
083     * properly formatted HTML Sub-Section. The purpose of the iterators within {@code class
084     * Details} is to retrieve the <I>individual, detailed</I> descriptions for the fields, methods
085     * and constructors from an HTML Page generated by the Java-Doc tool. This exception class will
086     * do some <I>simple, basic</I> parameter checking to ensure that the proper parameters are
087     * passed.  The priority is to provide more useable and meaningful error information.
088     *
089     * @param details This is supposed to be the return value from a call to the
090     * {@code HNLIInclusive iter.next()} method.  The iterator should be one returned from the
091     * {@code class Details} iterator' methods.  If it was, then it should a guarantee that the
092     * section is properly formatted, because it would have been retrieved from a JavaDoc HTML
093     * page.
094     *
095     * @throws DetailsException This exception shall throw if any of the requirements of the
096     * section have not been met.
097     * 
098     * @see StrCmpr
099     * @see TagNode
100     */
101    public static void check(Vector<HTMLNode> details)
102    {
103        TagNode first   = null;
104        TagNode last    = null;
105
106        // Ensure that the section is not null.
107        if (details == null) throw new NullPointerException
108            ("The vectorized-HTML section vector-reference was null.");
109
110        // There should quite a number of elements in this vector, besides the beginning and
111        // ending <UL>...</UL> elements.
112        if (details.size() < 3) throw new DetailsException(
113            "The vectorized-HTML section parameter has v.size()=" + details.size() +
114            ".  This is not sufficient.  " + PLEASE_USE
115        );
116
117        // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'>
118        try
119            { first = (TagNode) details.elementAt(0); }
120        catch (ClassCastException e)
121        { 
122            throw new DetailsException(
123                "This vectorized-HTML section does not begin with a TagNode element.  " +
124                "It begins with [" + first.str + "]" + PLEASE_USE
125            );
126        }
127
128        // All  Details Elements end with </ul>
129        try
130            { last = (TagNode) details.elementAt(details.size() - 1); }
131        catch (ClassCastException e)
132        {
133            throw new DetailsException(
134                "This vectorized-HTML section does not end with a TagNode element.  " + 
135                "It ends with [" + last.str + "]" + PLEASE_USE
136            );
137        }
138
139        // All  Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'>
140        if ((! first.tok.equals("ul")) || first.isClosing)
141            throw new DetailsException(
142                "The first node of the vectorized-HTML section is not an Opening <UL> Element.  " + 
143                "It is a [" + first.str + "].  " + PLEASE_USE
144            );
145
146        // All  Details Elements end with </ul>
147        if ((! last.tok.equals("ul")) || (! last.isClosing))
148            throw new DetailsException(
149                "The last node of the vectorized-HTML section is not a Closing </UL> Element.  " +
150                "It is a [" + last.str + "].  " + PLEASE_USE
151            );
152
153        // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'>
154        if (! StrCmpr.containsOR_CI(first.AV("class"), "blockList", "blockListLast"))
155            throw new DetailsException(
156                "The first node of the vectorized-HTML section is not an Opening <UL> Element " +
157                "with 'class' attribute containing string: 'blockList' or 'blockListLast.'  " +
158                "Instead it is: [" + first.str + "]."
159            );
160    }
161
162    /**
163     * This check method is used to ensure that a passed-parameter vectorized-HTML sub-page is
164     * correct.
165     * 
166     * <BR /><BR /><B STYLE='color:red;'>NOTE:</B> The Annotation-Element Details are just ever
167     * so slightly different than they are for the other four types of details (Methods,
168     * Constructors, Fields, and Enumerated-Constants).  The Annotation-Element Iterator returns
169     * HTML {@code <SECTION>} elements instead!
170     *
171     * @param details This is supposed to be the return value from a call to the
172     * {@code HNLIInclusive iter.next()} method.  The iterator should be one returned from the
173     * {@code class Details} methods retreiving an Annotation-Element Iterator.
174     *
175     * @throws DetailsException This exception shall throw if any of the requirements of the
176     * section have not been met.
177     * 
178     * @see StrCmpr
179     * @see TagNode
180     */
181    public static void checkAnnotation(Vector<HTMLNode> details)
182    {
183        TagNode first   = null;
184        TagNode last    = null;
185
186        // Ensure that the section is not null.
187        if (details == null) throw new NullPointerException
188            ("The vectorized-HTML section vector-reference was null.");
189
190        // There should quite a number of elements in this vector, besides the beginning and
191        // ending <UL>...</UL> elements.
192        if (details.size() < 3) throw new DetailsException(
193            "The vectorized-HTML section parameter has v.size()=" + details.size() +
194            ".  This is not sufficient.  " + PLEASE_USE
195        );
196
197        // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'>
198        try
199            { first = (TagNode) details.elementAt(0); }
200        catch (ClassCastException e)
201        { 
202            throw new DetailsException(
203                "This vectorized-HTML section does not begin with a TagNode element.  " +
204                "It begins with [" + first.str + "]" + PLEASE_USE_ANNOT
205            );
206        }
207
208        // All  Details Elements end with </ul>
209        try
210            { last = (TagNode) details.elementAt(details.size() - 1); }
211        catch (ClassCastException e)
212        {
213            throw new DetailsException(
214                "This vectorized-HTML section does not end with a TagNode element.  " + 
215                "It ends with [" + last.str + "]" + PLEASE_USE_ANNOT
216            );
217        }
218
219        // All  Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'>
220        if ((! first.tok.equals("section")) || first.isClosing)
221            throw new DetailsException(
222                "The first node of the vectorized-HTML section is not an Opening <SECTION> " +
223                "Element.  It is a [" + first.str + "].  " + PLEASE_USE_ANNOT
224            );
225
226        // All  Details Elements end with </ul>
227        if ((! last.tok.equals("section")) || (! last.isClosing))
228            throw new DetailsException(
229                "The last node of the vectorized-HTML section is not a Closing </SECTION> " +
230                "Element.  It is a [" + last.str + "].  " + PLEASE_USE_ANNOT
231            );
232
233        // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'>
234        if (! StrCmpr.containsOR_CI(first.AV("role"), "region"))
235            throw new DetailsException(
236                "The first node of the vectorized-HTML section is not an Opening <SECTION> " +
237                "element with 'role' attribute containing string: 'region.'  " +
238                "Instead it is: [" + first.str + "]."
239            );
240    }
241}