001package Torello.HTML.Tools.NewsSite;
002
003import java.util.Vector;
004import java.net.URL;
005
006import Torello.HTML.HTMLNode;
007
008/**
009 * An exception that is thrown from inside the <CODE><B>lambda-methods</B></CODE> created by the 
010 * class <CODE><B>ArticleGet</B></CODE> methods - <I>if an error occurs while retrieving a news
011 * article body from inside a news web-page</I>.
012 * 
013 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=ARTICLE_GET_EX>
014 */
015public class ArticleGetException extends Exception
016{
017    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUIDEX>  */
018    public static final long serialVersionUID = 1;
019
020    /**
021     * If the code that has generated this exception has decided to pass the HTML 
022     * page-{@code Vector} as a parameter to the constructor it has used, when this exception is
023     * thrown, that page will be retained in this {@code public, final} parameter.  Not all four
024     * of the provided constructor's for this exception require the {@code page} and {@code url}
025     * be preserved.  <I>If the throwing code has declined to provide this reference to the
026     * constructor, then the value of this {@code 'page'} field will be null.</I>
027     */
028    public final Vector<HTMLNode> page;
029
030    /**
031     * If the code that has generated this exception has decided to pass the HTML page-{@code URL}
032     * as a parameter to the constructor it has used, when this exception is thrown, that page will
033     * be retained in this {@code public, final} parameter. Not all four of the provided
034     * constructor's for this exception require the {@code 'page'} and {@code 'URL'} be preserved.
035     * <I>If the throwing code has declined to provide this reference to the constructor, then the
036     * value of this {@code 'URL'} field will be null.</I>
037     */
038    public final URL url;
039
040    /**
041     * Creates a new {@code ArticleGetException} that may be thrown.
042     *
043     * @param message An explanation of the problem encountered when using the {@code ArticleGet}
044     * consumer.
045     */
046    public ArticleGetException(String message)
047    { this(message, null, null); }
048
049    /**
050     * Creates a new {@code ArticleGetException} that may be thrown, having the given message,
051     * and a "previously thrown exception" (cause) - either from another thread, or caught and
052     * re-branded into an {@code ArticleGetException}
053     *
054     * <BR /><BR /><DIV CLASS=JDHint>
055     * <B STYLE='color:red;'>Note:</B> The detail message associated with cause is not
056     * automatically incorporated into this exception's detail message.
057     * </DIV>
058     * 
059     * @param message The explanation of the problem encountered when parsing an HTML page using
060     * the a user-defined, or factory-created {@code ArticleGet} instance.
061     *
062     * @param cause This may be a "cause" exception.  It can be caused, and facilitates a
063     * programmer catching a problem, and then re-naming it to {@code ArticleGetException}
064     */
065    public ArticleGetException(String message, Throwable cause)
066    { this(message, cause, null, null); }
067
068    /**
069     * When this constructor is used, the {@code URL} and page-{@code Vector} will be preserved
070     * as {@code final} (constant) fields within this class instance for future reference and
071     * debugging.
072     *
073     * @param message The explanation of the problem encountered when parsing an HTML page using
074     * the a user-defined, or factory-created {@code ArticleGet} instance.
075     *
076     * @param url The {@code URL} from which the original HTML page-{@code Vector} was retrieved
077     *
078     * @param page The HTML page (as a {@code Vector}) that could not be resolved by the
079     * {@code ArticleGet} instance which threw this exception.
080     */
081    public ArticleGetException(String message, URL url, Vector<HTMLNode> page)
082    {
083        super(message);
084        this.url = url;
085        this.page = page;
086    }
087
088    /**
089     * When this constructor is used, the {@code URL} and page-{@code Vector} will be preserved
090     * as {@code final} (constant) fields within this class instance for future reference and 
091     * debugging.  If there was an underlying exception that caused the article-body retrieval to
092     * fail, that will be stored in the Java {@code getCause();} method available.
093     *
094     * @param message The explanation of the problem encountered when parsing an HTML page using
095     * the a user-defined, or factory-created {@code ArticleGet} instance.
096     *
097     * @param cause This may be a "cause" exception.  It can be caused, and facilitates a
098     * programmer catching a problem, and then re-naming it to {@code ArticleGetException}
099     *
100     * @param url The {@code URL} from which the original HTML page-{@code Vector} was retrieved
101     *
102     * @param page The HTML page (as a {@code Vector}) that could not be resolved by the
103     * {@code ArticleGet} instance which threw this exception.
104     */
105    public ArticleGetException(String message, Throwable cause, URL url, Vector<HTMLNode> page)
106    {
107        super(message, cause);
108        this.url = url;
109        this.page = page;
110    }
111
112    /**
113     * When this constructor is used, the {@code URL} and page-{@code Vector} will be preserved
114     * as {@code final} (constant) fields within this class instance for future reference and
115     * debugging.
116     *
117     * @param url The {@code URL} from which the original HTML page-{@code Vector} was retrieved
118     *
119     * @param page The HTML page (as a {@code Vector}) that could not be resolved by the
120     * {@code ArticleGet} instance which threw this exception.
121     */
122    public static void check(URL url, Vector<HTMLNode> page) throws ArticleGetException
123    {
124        if (url == null) throw new ArticleGetException
125            ("ArticleGet.apply(...) has been called with a null URL.", url, page);
126
127        if (page == null) throw new ArticleGetException
128            ("ArticleGet.apply(...) has been called with a null page-vector.", url, page);
129
130        if (page.size() == 0) throw new ArticleGetException
131            ("ArticleGet.apply(...) has been called with a zero-length page-vector.", url, page);
132    }
133
134    static final int RET_NULL = 1;
135    static final int RET_EMPTY_VECTOR = 2;
136    static final int GOT_EXCEPTION = 3;
137
138    // Constructor #1
139    ArticleGetException(int FLAG, String functionNameStr, Exception e)
140    { this(MESSAGE(FLAG, functionNameStr), e); }
141
142    // Constructor #2
143    ArticleGetException(int FLAG, String functionNameStr)
144    { this(MESSAGE(FLAG, functionNameStr)); }
145
146    private static String MESSAGE(int FLAG, String functionNameStr)
147    {
148        StringBuilder sb = new StringBuilder
149            ("The article or page whose content-body you have tried to retrieve using your ArticleGet ");
150
151        switch (FLAG)
152        {
153            case RET_NULL:          sb.append("produced null.");
154                                    break;
155
156            case RET_EMPTY_VECTOR:  sb.append("produced a ZERO-LENGTH vector.");
157                                    break;
158
159            case GOT_EXCEPTION:     sb.append("threw an exception while parsing.  (see e.getCause().)");
160                                    break;
161
162            default:                sb.append("failed.  Unknown cause.");
163                                    break;
164        }
165
166        sb.append("\nFactory-generated ArticleGet had called: " + functionNameStr);
167
168        return sb.toString();
169    }
170}