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