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 = responseCode;
039        this.errorHeader = errorHeader;
040        this.errorBody = errorBody;
041    }
042
043    /**
044     * Constructs an {@code OsmApiException} with the specified detail message.
045     * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}.
046     *
047     * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
048     */
049    public OsmApiException(String message) {
050        super(message);
051    }
052
053    /**
054     * Constructs an {@code OsmApiException} with the specified cause and a detail message of
055     * <tt>(cause==null ? null : cause.toString())</tt>
056     * (which typically contains the class and detail message of <tt>cause</tt>).
057     *
058     * @param cause the cause (which is saved for later retrieval by the {@link #getCause} method).
059     *              A <tt>null</tt> value is permitted, and indicates that the cause is nonexistent or unknown.
060     */
061    public OsmApiException(Throwable cause) {
062        super(cause);
063    }
064
065    /**
066     * Constructs an {@code OsmApiException} with the specified detail message and cause.
067     *
068     * <p> Note that the detail message associated with {@code cause} is <i>not</i> automatically incorporated
069     * into this exception's detail message.
070     *
071     * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
072     * @param cause   The cause (which is saved for later retrieval by the {@link #getCause} method).
073     *                A null value is permitted, and indicates that the cause is nonexistent or unknown.
074     *
075     */
076    public OsmApiException(String message, Throwable cause) {
077        super(message, cause);
078    }
079
080    /**
081     * Replies the HTTP response code.
082     * @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.
083     */
084    public int getResponseCode() {
085        return responseCode;
086    }
087
088    /**
089     * Sets the HTTP response code.
090     * @param responseCode The HTTP response code replied by the OSM server. See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
091     */
092    public void setResponseCode(int responseCode) {
093        this.responseCode = responseCode;
094    }
095
096    /**
097     * Replies the error header.
098     * @return the error header, as transmitted in the {@code Error} field of the HTTP response header
099     */
100    public String getErrorHeader() {
101        return errorHeader;
102    }
103
104    /**
105     * Sets the error header.
106     * @param errorHeader the error header, as transmitted in the {@code Error} field of the HTTP response header
107     */
108    public void setErrorHeader(String errorHeader) {
109        this.errorHeader = errorHeader;
110    }
111
112    /**
113     * Replies the error body.
114     * @return The error body, as transmitted in the HTTP response body
115     */
116    public String getErrorBody() {
117        return errorBody;
118    }
119
120    /**
121     * Sets the error body.
122     * @param errorBody The error body, as transmitted in the HTTP response body
123     */
124    public void setErrorBody(String errorBody) {
125        this.errorBody = errorBody;
126    }
127
128    @Override
129    public String getMessage() {
130        StringBuilder sb = new StringBuilder();
131        sb.append("ResponseCode=")
132        .append(responseCode);
133        String eh = "";
134        try
135        {
136            if(errorHeader != null)
137                eh = tr(errorHeader.trim());
138            if (!eh.isEmpty()) {
139                sb.append(", Error Header=<")
140                .append(eh)
141                .append(">");
142            }
143        }
144        catch (Exception e) {
145            // Ignored
146        }
147        try
148        {
149            String eb = errorBody != null ? tr(errorBody.trim()) : "";
150            if (!eb.isEmpty() && !eb.equals(eh)) {
151                sb.append(", Error Body=<")
152                .append(eb)
153                .append(">");
154            }
155        }
156        catch (Exception e) {
157            // Ignored
158        }
159        return sb.toString();
160    }
161
162    /**
163     * Replies a message suitable to be displayed in a message dialog
164     *
165     * @return a message which is suitable to be displayed in a message dialog
166     */
167    public String getDisplayMessage() {
168        StringBuilder sb = new StringBuilder();
169        if (errorHeader != null) {
170            sb.append(tr(errorHeader));
171            sb.append(tr("(Code={0})", responseCode));
172        } else if (errorBody != null && !errorBody.trim().isEmpty()) {
173            errorBody = errorBody.trim();
174            sb.append(tr(errorBody));
175            sb.append(tr("(Code={0})", responseCode));
176        } else {
177            sb.append(tr("The server replied an error with code {0}.", responseCode));
178        }
179        return sb.toString();
180    }
181
182    /**
183     * 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.
184     * @param url the complete URL accessed when this error occured.
185     */
186    public void setAccessedUrl(String url) {
187        this.accessedUrl = url;
188    }
189
190    /**
191     * 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.
192     * @return the complete URL accessed when this error occured.
193     */
194    public String getAccessedUrl() {
195        return accessedUrl;
196    }
197}