001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io;
003import static org.openstreetmap.josm.tools.I18n.tr;
004
005import org.openstreetmap.josm.Main;
006
007/**
008 * Exception thrown when a communication error occurs when accessing the <a href="http://wiki.openstreetmap.org/wiki/API_v0.6">OSM API</a>.
009 * @see OsmApi
010 */
011public class OsmApiException extends OsmTransferException {
012
013    private int responseCode;
014    private String errorHeader;
015    private String errorBody;
016    private String accessedUrl;
017
018    /**
019     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
020     * @param responseCode The HTTP response code replied by the OSM server.
021     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
022     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
023     * @param errorBody The error body, as transmitted in the HTTP response body
024     * @param accessedUrl The complete URL accessed when this error occured
025     * @since 5584
026     */
027    public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl) {
028        this.responseCode = responseCode;
029        this.errorHeader = errorHeader;
030        this.errorBody = errorBody;
031        this.accessedUrl = accessedUrl;
032    }
033
034    /**
035     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
036     * @param responseCode The HTTP response code replied by the OSM server.
037     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
038     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
039     * @param errorBody The error body, as transmitted in the HTTP response body
040     */
041    public OsmApiException(int responseCode, String errorHeader, String errorBody) {
042        this(responseCode, errorHeader, errorBody, null);
043    }
044
045    /**
046     * Constructs an {@code OsmApiException} with the specified detail message.
047     * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}.
048     *
049     * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
050     */
051    public OsmApiException(String message) {
052        super(message);
053    }
054
055    /**
056     * Constructs an {@code OsmApiException} with the specified cause and a detail message of
057     * <tt>(cause==null ? null : cause.toString())</tt>
058     * (which typically contains the class and detail message of <tt>cause</tt>).
059     *
060     * @param cause the cause (which is saved for later retrieval by the {@link #getCause} method).
061     *              A <tt>null</tt> value is permitted, and indicates that the cause is nonexistent or unknown.
062     */
063    public OsmApiException(Throwable cause) {
064        super(cause);
065    }
066
067    /**
068     * Constructs an {@code OsmApiException} with the specified detail message and cause.
069     *
070     * <p> Note that the detail message associated with {@code cause} is <i>not</i> automatically incorporated
071     * into this exception's detail message.
072     *
073     * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
074     * @param cause   The cause (which is saved for later retrieval by the {@link #getCause} method).
075     *                A null value is permitted, and indicates that the cause is nonexistent or unknown.
076     *
077     */
078    public OsmApiException(String message, Throwable cause) {
079        super(message, cause);
080    }
081
082    /**
083     * Replies the HTTP response code.
084     * @return The HTTP response code replied by the OSM server. Refer to
085     * <a href="http://wiki.openstreetmap.org/wiki/API_v0.6">OSM API</a> to see the list of response codes returned by the API for each call.
086     */
087    public int getResponseCode() {
088        return responseCode;
089    }
090
091    /**
092     * Sets the HTTP response code.
093     * @param responseCode The HTTP response code replied by the OSM server.
094     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
095     */
096    public void setResponseCode(int responseCode) {
097        this.responseCode = responseCode;
098    }
099
100    /**
101     * Replies the error header.
102     * @return the error header, as transmitted in the {@code Error} field of the HTTP response header
103     */
104    public String getErrorHeader() {
105        return errorHeader;
106    }
107
108    /**
109     * Sets the error header.
110     * @param errorHeader the error header, as transmitted in the {@code Error} field of the HTTP response header
111     */
112    public void setErrorHeader(String errorHeader) {
113        this.errorHeader = errorHeader;
114    }
115
116    /**
117     * Replies the error body.
118     * @return The error body, as transmitted in the HTTP response body
119     */
120    public String getErrorBody() {
121        return errorBody;
122    }
123
124    /**
125     * Sets the error body.
126     * @param errorBody The error body, as transmitted in the HTTP response body
127     */
128    public void setErrorBody(String errorBody) {
129        this.errorBody = errorBody;
130    }
131
132    @Override
133    public String getMessage() {
134        StringBuilder sb = new StringBuilder();
135        sb.append("ResponseCode=")
136        .append(responseCode);
137        String eh = "";
138        try {
139            if (errorHeader != null)
140                eh = tr(errorHeader.trim());
141            if (!eh.isEmpty()) {
142                sb.append(", Error Header=<")
143                .append(eh)
144                .append('>');
145            }
146        } catch (IllegalArgumentException e) {
147            // Ignored
148            Main.trace(e);
149        }
150        try {
151            String eb = errorBody != null ? tr(errorBody.trim()) : "";
152            if (!eb.isEmpty() && !eb.equals(eh)) {
153                sb.append(", Error Body=<")
154                .append(eb)
155                .append('>');
156            }
157        } catch (IllegalArgumentException e) {
158            // Ignored
159            Main.trace(e);
160        }
161        return sb.toString();
162    }
163
164    /**
165     * Replies a message suitable to be displayed in a message dialog
166     *
167     * @return a message which is suitable to be displayed in a message dialog
168     */
169    public String getDisplayMessage() {
170        StringBuilder sb = new StringBuilder();
171        if (errorHeader != null) {
172            sb.append(tr(errorHeader));
173            sb.append(tr("(Code={0})", responseCode));
174        } else if (errorBody != null && !errorBody.trim().isEmpty()) {
175            errorBody = errorBody.trim();
176            sb.append(tr(errorBody));
177            sb.append(tr("(Code={0})", responseCode));
178        } else {
179            sb.append(tr("The server replied an error with code {0}.", responseCode));
180        }
181        return sb.toString();
182    }
183
184    /**
185     * Sets the complete URL accessed when this error occured.
186     * This is distinct from the one set with {@link #setUrl}, which is generally only the base URL of the server.
187     * @param url the complete URL accessed when this error occured.
188     */
189    public void setAccessedUrl(String url) {
190        this.accessedUrl = url;
191    }
192
193    /**
194     * Replies the complete URL accessed when this error occured.
195     * This is distinct from the one returned by {@link #getUrl}, which is generally only the base URL of the server.
196     * @return the complete URL accessed when this error occured.
197     */
198    public String getAccessedUrl() {
199        return accessedUrl;
200    }
201}