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     * @param message The explanation of the problem encountered when parsing an HTML page using
055     * the a user-defined, or factory-created {@code ArticleGet} instance.
056     *
057     * @param cause This may be a "cause" exception.  It can be caused, and facilitates a
058     * programmer catching a problem, and then re-naming it to {@code ArticleGetException}
059     */
060    public ArticleGetException(String message, Throwable cause)
061    { this(message, cause, null, null); }
062
063    /**
064     * When this constructor is used, the {@code URL} and page-{@code Vector} will be preserved
065     * as {@code final} (constant) fields within this class instance for future reference and
066     * debugging.
067     *
068     * @param message The explanation of the problem encountered when parsing an HTML page using
069     * the a user-defined, or factory-created {@code ArticleGet} instance.
070     *
071     * @param url The {@code URL} from which the original HTML page-{@code Vector} was retrieved
072     *
073     * @param page The HTML page (as a {@code Vector}) that could not be resolved by the
074     * {@code ArticleGet} instance which threw this exception.
075     */
076    public ArticleGetException(String message, URL url, Vector<HTMLNode> page)
077    {
078        super(message);
079        this.url = url;
080        this.page = page;
081    }
082
083    /**
084     * When this constructor is used, the {@code URL} and page-{@code Vector} will be preserved
085     * as {@code final} (constant) fields within this class instance for future reference and 
086     * debugging.  If there was an underlying exception that caused the article-body retrieval to
087     * fail, that will be stored in the Java {@code getCause();} method available.
088     *
089     * @param message The explanation of the problem encountered when parsing an HTML page using
090     * the a user-defined, or factory-created {@code ArticleGet} instance.
091     *
092     * @param cause This may be a "cause" exception.  It can be caused, and facilitates a
093     * programmer catching a problem, and then re-naming it to {@code ArticleGetException}
094     *
095     * @param url The {@code URL} from which the original HTML page-{@code Vector} was retrieved
096     *
097     * @param page The HTML page (as a {@code Vector}) that could not be resolved by the
098     * {@code ArticleGet} instance which threw this exception.
099     */
100    public ArticleGetException(String message, Throwable cause, URL url, Vector<HTMLNode> page)
101    {
102        super(message, cause);
103        this.url = url;
104        this.page = page;
105    }
106
107    /**
108     * When this constructor is used, the {@code URL} and page-{@code Vector} will be preserved
109     * as {@code final} (constant) fields within this class instance for future reference and
110     * debugging.
111     *
112     * @param url The {@code URL} from which the original HTML page-{@code Vector} was retrieved
113     *
114     * @param page The HTML page (as a {@code Vector}) that could not be resolved by the
115     * {@code ArticleGet} instance which threw this exception.
116     */
117    public static void check(URL url, Vector<HTMLNode> page) throws ArticleGetException
118    {
119        if (url == null) throw new ArticleGetException
120            ("ArticleGet.apply(...) has been called with a null URL.", url, page);
121
122        if (page == null) throw new ArticleGetException
123            ("ArticleGet.apply(...) has been called with a null page-vector.", url, page);
124
125        if (page.size() == 0) throw new ArticleGetException
126            ("ArticleGet.apply(...) has been called with a zero-length page-vector.", url, page);
127    }
128
129    static final int RET_NULL = 1;
130    static final int RET_EMPTY_VECTOR = 2;
131    static final int GOT_EXCEPTION = 3;
132
133    // Constructor #1
134    ArticleGetException(int FLAG, String functionNameStr, Exception e)
135    { this(MESSAGE(FLAG, functionNameStr), e); }
136
137    // Constructor #2
138    ArticleGetException(int FLAG, String functionNameStr)
139    { this(MESSAGE(FLAG, functionNameStr)); }
140
141    private static String MESSAGE(int FLAG, String functionNameStr)
142    {
143        StringBuilder sb = new StringBuilder
144            ("The article or page whose content-body you have tried to retrieve using your ArticleGet ");
145
146        switch (FLAG)
147        {
148            case RET_NULL:          sb.append("produced null.");
149                                    break;
150
151            case RET_EMPTY_VECTOR:  sb.append("produced a ZERO-LENGTH vector.");
152                                    break;
153
154            case GOT_EXCEPTION:     sb.append("threw an exception while parsing.  (see e.getCause().)");
155                                    break;
156
157            default:                sb.append("failed.  Unknown cause.");
158                                    break;
159        }
160
161        sb.append("\nFactory-generated ArticleGet had called: " + functionNameStr);
162
163        return sb.toString();
164    }
165}