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.tools.Logging;
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 contentType;
015    private String errorHeader;
016    private String errorBody;
017    private String accessedUrl;
018    private String login;
019
020    /**
021     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
022     * @param responseCode The HTTP response code replied by the OSM server.
023     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
024     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
025     * @param errorBody The error body, as transmitted in the HTTP response body
026     * @param accessedUrl The complete URL accessed when this error occured
027     * @param login the login used to connect to OSM API (can be null)
028     * @param contentType the response content-type
029     * @since 13499
030     */
031    public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl, String login, String contentType) {
032        this.responseCode = responseCode;
033        this.errorHeader = errorHeader;
034        this.errorBody = errorBody;
035        this.accessedUrl = accessedUrl;
036        this.login = login;
037        this.contentType = contentType;
038    }
039
040    /**
041     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
042     * @param responseCode The HTTP response code replied by the OSM server.
043     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
044     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
045     * @param errorBody The error body, as transmitted in the HTTP response body
046     * @param accessedUrl The complete URL accessed when this error occured
047     * @param login the login used to connect to OSM API (can be null)
048     * @since 12992
049     */
050    public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl, String login) {
051        this(responseCode, errorHeader, errorBody, accessedUrl, login, null);
052    }
053
054    /**
055     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
056     * @param responseCode The HTTP response code replied by the OSM server.
057     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
058     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
059     * @param errorBody The error body, as transmitted in the HTTP response body
060     * @param accessedUrl The complete URL accessed when this error occured
061     * @since 5584
062     */
063    public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl) {
064        this(responseCode, errorHeader, errorBody, accessedUrl, null);
065    }
066
067    /**
068     * Constructs an {@code OsmApiException} with the specified response code, error header and error body
069     * @param responseCode The HTTP response code replied by the OSM server.
070     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
071     * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
072     * @param errorBody The error body, as transmitted in the HTTP response body
073     */
074    public OsmApiException(int responseCode, String errorHeader, String errorBody) {
075        this(responseCode, errorHeader, errorBody, null);
076    }
077
078    /**
079     * Constructs an {@code OsmApiException} with the specified detail message.
080     * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}.
081     *
082     * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
083     */
084    public OsmApiException(String message) {
085        super(message);
086    }
087
088    /**
089     * Constructs an {@code OsmApiException} with the specified cause and a detail message of
090     * <code>(cause==null ? null : cause.toString())</code>
091     * (which typically contains the class and detail message of <code>cause</code>).
092     *
093     * @param cause the cause (which is saved for later retrieval by the {@link #getCause} method).
094     *              A <code>null</code> value is permitted, and indicates that the cause is nonexistent or unknown.
095     */
096    public OsmApiException(Throwable cause) {
097        super(cause);
098    }
099
100    /**
101     * Constructs an {@code OsmApiException} with the specified detail message and cause.
102     *
103     * <p> Note that the detail message associated with {@code cause} is <i>not</i> automatically incorporated
104     * into this exception's detail message.
105     *
106     * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
107     * @param cause   The cause (which is saved for later retrieval by the {@link #getCause} method).
108     *                A null value is permitted, and indicates that the cause is nonexistent or unknown.
109     *
110     */
111    public OsmApiException(String message, Throwable cause) {
112        super(message, cause);
113    }
114
115    /**
116     * Replies the HTTP response code.
117     * @return The HTTP response code replied by the OSM server. Refer to
118     * <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.
119     */
120    public int getResponseCode() {
121        return responseCode;
122    }
123
124    /**
125     * Sets the HTTP response code.
126     * @param responseCode The HTTP response code replied by the OSM server.
127     * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
128     */
129    public void setResponseCode(int responseCode) {
130        this.responseCode = responseCode;
131    }
132
133    /**
134     * Replies the error header.
135     * @return the error header, as transmitted in the {@code Error} field of the HTTP response header
136     */
137    public String getErrorHeader() {
138        return errorHeader;
139    }
140
141    /**
142     * Sets the error header.
143     * @param errorHeader the error header, as transmitted in the {@code Error} field of the HTTP response header
144     */
145    public void setErrorHeader(String errorHeader) {
146        this.errorHeader = errorHeader;
147    }
148
149    /**
150     * Replies the error body.
151     * @return The error body, as transmitted in the HTTP response body
152     */
153    public String getErrorBody() {
154        return errorBody;
155    }
156
157    /**
158     * Sets the error body.
159     * @param errorBody The error body, as transmitted in the HTTP response body
160     */
161    public void setErrorBody(String errorBody) {
162        this.errorBody = errorBody;
163    }
164
165    @Override
166    public String getMessage() {
167        StringBuilder sb = new StringBuilder();
168        sb.append("ResponseCode=")
169        .append(responseCode);
170        String eh = "";
171        try {
172            if (errorHeader != null)
173                eh = tr(errorHeader.trim());
174            if (!eh.isEmpty()) {
175                sb.append(", Error Header=<")
176                .append(eh)
177                .append('>');
178            }
179        } catch (IllegalArgumentException e) {
180            // Ignored
181            Logging.trace(e);
182        }
183        try {
184            String eb = errorBody != null ? tr(errorBody.trim()) : "";
185            if (!eb.isEmpty() && !eb.equals(eh)) {
186                sb.append(", Error Body=<")
187                .append(eb)
188                .append('>');
189            }
190        } catch (IllegalArgumentException e) {
191            // Ignored
192            Logging.trace(e);
193        }
194        return sb.toString();
195    }
196
197    /**
198     * Replies a message suitable to be displayed in a message dialog
199     *
200     * @return a message which is suitable to be displayed in a message dialog
201     */
202    public String getDisplayMessage() {
203        StringBuilder sb = new StringBuilder();
204        if (errorHeader != null) {
205            sb.append(tr(errorHeader));
206            sb.append(tr("(Code={0})", responseCode));
207        } else if (errorBody != null && !errorBody.trim().isEmpty()) {
208            errorBody = errorBody.trim();
209            sb.append(tr(errorBody));
210            sb.append(tr("(Code={0})", responseCode));
211        } else {
212            sb.append(tr("The server replied an error with code {0}.", responseCode));
213        }
214        return sb.toString();
215    }
216
217    /**
218     * Sets the complete URL accessed when this error occured.
219     * This is distinct from the one set with {@link #setUrl}, which is generally only the base URL of the server.
220     * @param url the complete URL accessed when this error occured.
221     */
222    public void setAccessedUrl(String url) {
223        this.accessedUrl = url;
224    }
225
226    /**
227     * Replies the complete URL accessed when this error occured.
228     * This is distinct from the one returned by {@link #getUrl}, which is generally only the base URL of the server.
229     * @return the complete URL accessed when this error occured.
230     */
231    public String getAccessedUrl() {
232        return accessedUrl;
233    }
234
235    /**
236     * Sets the login used to connect to OSM API.
237     * @param login the login used to connect to OSM API
238     * @since 12992
239     */
240    public void setLogin(String login) {
241        this.login = login;
242    }
243
244    /**
245     * Replies the login used to connect to OSM API.
246     * @return the login used to connect to OSM API, or {@code null}
247     * @since 12992
248     */
249    public String getLogin() {
250        return login;
251    }
252
253    /**
254     * Sets the response content-type.
255     * @param contentType the response content-type.
256     * @since 13499
257     */
258    public final void setContentType(String contentType) {
259        this.contentType = contentType;
260    }
261
262    /**
263     * Replies the response content-type.
264     * @return the response content-type
265     * @since 13499
266     */
267    public final String getContentType() {
268        return contentType;
269    }
270}