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