[2512] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.io;
|
---|
| 3 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 4 |
|
---|
[12620] | 5 | import org.openstreetmap.josm.tools.Logging;
|
---|
[14810] | 6 | import org.openstreetmap.josm.tools.Utils;
|
---|
[8513] | 7 |
|
---|
[5386] | 8 | /**
|
---|
| 9 | * Exception thrown when a communication error occurs when accessing the <a href="http://wiki.openstreetmap.org/wiki/API_v0.6">OSM API</a>.
|
---|
| 10 | * @see OsmApi
|
---|
| 11 | */
|
---|
[2512] | 12 | public class OsmApiException extends OsmTransferException {
|
---|
| 13 |
|
---|
| 14 | private int responseCode;
|
---|
[13499] | 15 | private String contentType;
|
---|
[2512] | 16 | private String errorHeader;
|
---|
| 17 | private String errorBody;
|
---|
[2748] | 18 | private String accessedUrl;
|
---|
[12992] | 19 | private String login;
|
---|
[2512] | 20 |
|
---|
[5386] | 21 | /**
|
---|
| 22 | * Constructs an {@code OsmApiException} with the specified response code, error header and error body
|
---|
[8509] | 23 | * @param responseCode The HTTP response code replied by the OSM server.
|
---|
| 24 | * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
|
---|
[5386] | 25 | * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
|
---|
| 26 | * @param errorBody The error body, as transmitted in the HTTP response body
|
---|
[14273] | 27 | * @param accessedUrl The complete URL accessed when this error occurred
|
---|
[12992] | 28 | * @param login the login used to connect to OSM API (can be null)
|
---|
[13499] | 29 | * @param contentType the response content-type
|
---|
| 30 | * @since 13499
|
---|
[5386] | 31 | */
|
---|
[13499] | 32 | public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl, String login, String contentType) {
|
---|
[5584] | 33 | this.responseCode = responseCode;
|
---|
| 34 | this.errorHeader = errorHeader;
|
---|
[14810] | 35 | this.errorBody = Utils.strip(errorBody);
|
---|
[5584] | 36 | this.accessedUrl = accessedUrl;
|
---|
[12992] | 37 | this.login = login;
|
---|
[13499] | 38 | this.contentType = contentType;
|
---|
[14810] | 39 | checkHtmlBody();
|
---|
[5584] | 40 | }
|
---|
[6070] | 41 |
|
---|
[5584] | 42 | /**
|
---|
| 43 | * Constructs an {@code OsmApiException} with the specified response code, error header and error body
|
---|
[8509] | 44 | * @param responseCode The HTTP response code replied by the OSM server.
|
---|
| 45 | * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
|
---|
[5584] | 46 | * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
|
---|
| 47 | * @param errorBody The error body, as transmitted in the HTTP response body
|
---|
[14273] | 48 | * @param accessedUrl The complete URL accessed when this error occurred
|
---|
[13499] | 49 | * @param login the login used to connect to OSM API (can be null)
|
---|
| 50 | * @since 12992
|
---|
| 51 | */
|
---|
| 52 | public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl, String login) {
|
---|
| 53 | this(responseCode, errorHeader, errorBody, accessedUrl, login, null);
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | /**
|
---|
| 57 | * Constructs an {@code OsmApiException} with the specified response code, error header and error body
|
---|
| 58 | * @param responseCode The HTTP response code replied by the OSM server.
|
---|
| 59 | * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
|
---|
| 60 | * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
|
---|
| 61 | * @param errorBody The error body, as transmitted in the HTTP response body
|
---|
[14273] | 62 | * @param accessedUrl The complete URL accessed when this error occurred
|
---|
[12992] | 63 | * @since 5584
|
---|
[5584] | 64 | */
|
---|
[12992] | 65 | public OsmApiException(int responseCode, String errorHeader, String errorBody, String accessedUrl) {
|
---|
| 66 | this(responseCode, errorHeader, errorBody, accessedUrl, null);
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | /**
|
---|
| 70 | * Constructs an {@code OsmApiException} with the specified response code, error header and error body
|
---|
| 71 | * @param responseCode The HTTP response code replied by the OSM server.
|
---|
| 72 | * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
|
---|
| 73 | * @param errorHeader The error header, as transmitted in the {@code Error} field of the HTTP response header
|
---|
| 74 | * @param errorBody The error body, as transmitted in the HTTP response body
|
---|
| 75 | */
|
---|
[2512] | 76 | public OsmApiException(int responseCode, String errorHeader, String errorBody) {
|
---|
[7205] | 77 | this(responseCode, errorHeader, errorBody, null);
|
---|
[2512] | 78 | }
|
---|
| 79 |
|
---|
[5386] | 80 | /**
|
---|
| 81 | * Constructs an {@code OsmApiException} with the specified detail message.
|
---|
| 82 | * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}.
|
---|
| 83 | *
|
---|
| 84 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
|
---|
| 85 | */
|
---|
[2512] | 86 | public OsmApiException(String message) {
|
---|
| 87 | super(message);
|
---|
| 88 | }
|
---|
| 89 |
|
---|
[5386] | 90 | /**
|
---|
[6070] | 91 | * Constructs an {@code OsmApiException} with the specified cause and a detail message of
|
---|
[13493] | 92 | * <code>(cause==null ? null : cause.toString())</code>
|
---|
| 93 | * (which typically contains the class and detail message of <code>cause</code>).
|
---|
[5386] | 94 | *
|
---|
[6070] | 95 | * @param cause the cause (which is saved for later retrieval by the {@link #getCause} method).
|
---|
[13493] | 96 | * A <code>null</code> value is permitted, and indicates that the cause is nonexistent or unknown.
|
---|
[5386] | 97 | */
|
---|
[2512] | 98 | public OsmApiException(Throwable cause) {
|
---|
| 99 | super(cause);
|
---|
| 100 | }
|
---|
| 101 |
|
---|
[5386] | 102 | /**
|
---|
| 103 | * Constructs an {@code OsmApiException} with the specified detail message and cause.
|
---|
| 104 | *
|
---|
[6070] | 105 | * <p> Note that the detail message associated with {@code cause} is <i>not</i> automatically incorporated
|
---|
[5386] | 106 | * into this exception's detail message.
|
---|
| 107 | *
|
---|
| 108 | * @param message The detail message (which is saved for later retrieval by the {@link #getMessage} method)
|
---|
| 109 | * @param cause The cause (which is saved for later retrieval by the {@link #getCause} method).
|
---|
| 110 | * A null value is permitted, and indicates that the cause is nonexistent or unknown.
|
---|
| 111 | *
|
---|
| 112 | */
|
---|
| 113 | public OsmApiException(String message, Throwable cause) {
|
---|
| 114 | super(message, cause);
|
---|
| 115 | }
|
---|
| 116 |
|
---|
[14810] | 117 | private void checkHtmlBody() {
|
---|
| 118 | if (errorBody != null && errorBody.matches("^<.*>.*<.*>$")) {
|
---|
| 119 | setContentType("text/html");
|
---|
| 120 | if (!errorBody.contains("<html>")) {
|
---|
| 121 | errorBody = "<html>" + errorBody + "</html>";
|
---|
| 122 | }
|
---|
| 123 | }
|
---|
| 124 | }
|
---|
| 125 |
|
---|
[5386] | 126 | /**
|
---|
| 127 | * Replies the HTTP response code.
|
---|
[8509] | 128 | * @return The HTTP response code replied by the OSM server. Refer to
|
---|
| 129 | * <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.
|
---|
[5386] | 130 | */
|
---|
[2512] | 131 | public int getResponseCode() {
|
---|
| 132 | return responseCode;
|
---|
| 133 | }
|
---|
| 134 |
|
---|
[5386] | 135 | /**
|
---|
| 136 | * Sets the HTTP response code.
|
---|
[8509] | 137 | * @param responseCode The HTTP response code replied by the OSM server.
|
---|
| 138 | * See {@link java.net.HttpURLConnection HttpURLConnection} for predefined HTTP response code values
|
---|
[5386] | 139 | */
|
---|
[2512] | 140 | public void setResponseCode(int responseCode) {
|
---|
| 141 | this.responseCode = responseCode;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
[5386] | 144 | /**
|
---|
| 145 | * Replies the error header.
|
---|
| 146 | * @return the error header, as transmitted in the {@code Error} field of the HTTP response header
|
---|
| 147 | */
|
---|
[2512] | 148 | public String getErrorHeader() {
|
---|
| 149 | return errorHeader;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
[5386] | 152 | /**
|
---|
| 153 | * Sets the error header.
|
---|
| 154 | * @param errorHeader the error header, as transmitted in the {@code Error} field of the HTTP response header
|
---|
| 155 | */
|
---|
[2512] | 156 | public void setErrorHeader(String errorHeader) {
|
---|
| 157 | this.errorHeader = errorHeader;
|
---|
| 158 | }
|
---|
| 159 |
|
---|
[5386] | 160 | /**
|
---|
| 161 | * Replies the error body.
|
---|
| 162 | * @return The error body, as transmitted in the HTTP response body
|
---|
| 163 | */
|
---|
[2512] | 164 | public String getErrorBody() {
|
---|
| 165 | return errorBody;
|
---|
| 166 | }
|
---|
| 167 |
|
---|
[5386] | 168 | /**
|
---|
| 169 | * Sets the error body.
|
---|
| 170 | * @param errorBody The error body, as transmitted in the HTTP response body
|
---|
| 171 | */
|
---|
[2512] | 172 | public void setErrorBody(String errorBody) {
|
---|
| 173 | this.errorBody = errorBody;
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | @Override
|
---|
| 177 | public String getMessage() {
|
---|
| 178 | StringBuilder sb = new StringBuilder();
|
---|
| 179 | sb.append("ResponseCode=")
|
---|
| 180 | .append(responseCode);
|
---|
[3511] | 181 | String eh = "";
|
---|
[8342] | 182 | try {
|
---|
[8510] | 183 | if (errorHeader != null)
|
---|
[3511] | 184 | eh = tr(errorHeader.trim());
|
---|
| 185 | if (!eh.isEmpty()) {
|
---|
| 186 | sb.append(", Error Header=<")
|
---|
| 187 | .append(eh)
|
---|
[8390] | 188 | .append('>');
|
---|
[3511] | 189 | }
|
---|
[10212] | 190 | } catch (IllegalArgumentException e) {
|
---|
[5386] | 191 | // Ignored
|
---|
[12620] | 192 | Logging.trace(e);
|
---|
[3511] | 193 | }
|
---|
[8342] | 194 | try {
|
---|
[3511] | 195 | String eb = errorBody != null ? tr(errorBody.trim()) : "";
|
---|
| 196 | if (!eb.isEmpty() && !eb.equals(eh)) {
|
---|
[2512] | 197 | sb.append(", Error Body=<")
|
---|
[3511] | 198 | .append(eb)
|
---|
[8390] | 199 | .append('>');
|
---|
[2512] | 200 | }
|
---|
[10212] | 201 | } catch (IllegalArgumentException e) {
|
---|
[5386] | 202 | // Ignored
|
---|
[12620] | 203 | Logging.trace(e);
|
---|
[3511] | 204 | }
|
---|
[2512] | 205 | return sb.toString();
|
---|
| 206 | }
|
---|
| 207 |
|
---|
| 208 | /**
|
---|
| 209 | * Replies a message suitable to be displayed in a message dialog
|
---|
| 210 | *
|
---|
| 211 | * @return a message which is suitable to be displayed in a message dialog
|
---|
| 212 | */
|
---|
| 213 | public String getDisplayMessage() {
|
---|
| 214 | StringBuilder sb = new StringBuilder();
|
---|
[15084] | 215 | String header = Utils.strip(errorHeader);
|
---|
| 216 | String body = Utils.strip(errorBody);
|
---|
| 217 | if ((header == null || header.isEmpty()) && (body == null || body.isEmpty())) {
|
---|
| 218 | sb.append(tr("The server replied an error with code {0}.", responseCode));
|
---|
[2512] | 219 | } else {
|
---|
[15084] | 220 | if (header != null && !header.isEmpty()) {
|
---|
| 221 | sb.append(tr(header));
|
---|
| 222 | }
|
---|
[15085] | 223 | if (body != null && !body.isEmpty() && !body.equals(header)) {
|
---|
[15084] | 224 | if (sb.length() > 0) {
|
---|
| 225 | sb.append(". ");
|
---|
| 226 | }
|
---|
| 227 | sb.append(tr(body));
|
---|
| 228 | }
|
---|
| 229 | sb.append(' ').append(tr("(Code={0})", responseCode));
|
---|
[2512] | 230 | }
|
---|
| 231 | return sb.toString();
|
---|
| 232 | }
|
---|
[2748] | 233 |
|
---|
[5386] | 234 | /**
|
---|
[14273] | 235 | * Sets the complete URL accessed when this error occurred.
|
---|
[8509] | 236 | * This is distinct from the one set with {@link #setUrl}, which is generally only the base URL of the server.
|
---|
[14273] | 237 | * @param url the complete URL accessed when this error occurred.
|
---|
[5386] | 238 | */
|
---|
[2748] | 239 | public void setAccessedUrl(String url) {
|
---|
| 240 | this.accessedUrl = url;
|
---|
| 241 | }
|
---|
| 242 |
|
---|
[5386] | 243 | /**
|
---|
[14273] | 244 | * Replies the complete URL accessed when this error occurred.
|
---|
[8509] | 245 | * This is distinct from the one returned by {@link #getUrl}, which is generally only the base URL of the server.
|
---|
[14273] | 246 | * @return the complete URL accessed when this error occurred.
|
---|
[5386] | 247 | */
|
---|
[2748] | 248 | public String getAccessedUrl() {
|
---|
| 249 | return accessedUrl;
|
---|
| 250 | }
|
---|
[12992] | 251 |
|
---|
| 252 | /**
|
---|
| 253 | * Sets the login used to connect to OSM API.
|
---|
| 254 | * @param login the login used to connect to OSM API
|
---|
| 255 | * @since 12992
|
---|
| 256 | */
|
---|
| 257 | public void setLogin(String login) {
|
---|
| 258 | this.login = login;
|
---|
| 259 | }
|
---|
| 260 |
|
---|
| 261 | /**
|
---|
| 262 | * Replies the login used to connect to OSM API.
|
---|
| 263 | * @return the login used to connect to OSM API, or {@code null}
|
---|
| 264 | * @since 12992
|
---|
| 265 | */
|
---|
| 266 | public String getLogin() {
|
---|
| 267 | return login;
|
---|
| 268 | }
|
---|
[13499] | 269 |
|
---|
| 270 | /**
|
---|
| 271 | * Sets the response content-type.
|
---|
| 272 | * @param contentType the response content-type.
|
---|
| 273 | * @since 13499
|
---|
| 274 | */
|
---|
| 275 | public final void setContentType(String contentType) {
|
---|
| 276 | this.contentType = contentType;
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | /**
|
---|
| 280 | * Replies the response content-type.
|
---|
| 281 | * @return the response content-type
|
---|
| 282 | * @since 13499
|
---|
| 283 | */
|
---|
| 284 | public final String getContentType() {
|
---|
| 285 | return contentType;
|
---|
| 286 | }
|
---|
[14810] | 287 |
|
---|
| 288 | /**
|
---|
| 289 | * Determines if the exception has {@code text/html} as content type.
|
---|
| 290 | * @return {@code true} if the exception has {@code text/html} as content type.
|
---|
[15077] | 291 | * @since 14810
|
---|
[14810] | 292 | */
|
---|
| 293 | public final boolean isHtml() {
|
---|
| 294 | return "text/html".equals(contentType);
|
---|
| 295 | }
|
---|
[2512] | 296 | }
|
---|