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