source: josm/trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java@ 8961

Last change on this file since 8961 was 8510, checked in by Don-vip, 9 years ago

checkstyle: enable relevant whitespace checks and fix them

  • Property svn:eol-style set to native
File size: 17.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.io.IOException;
8import java.lang.reflect.InvocationTargetException;
9import java.net.HttpURLConnection;
10import java.net.SocketException;
11import java.net.UnknownHostException;
12import java.util.regex.Matcher;
13import java.util.regex.Pattern;
14
15import javax.swing.JOptionPane;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.io.ChangesetClosedException;
20import org.openstreetmap.josm.io.IllegalDataException;
21import org.openstreetmap.josm.io.MissingOAuthAccessTokenException;
22import org.openstreetmap.josm.io.OfflineAccessException;
23import org.openstreetmap.josm.io.OsmApi;
24import org.openstreetmap.josm.io.OsmApiException;
25import org.openstreetmap.josm.io.OsmApiInitializationException;
26import org.openstreetmap.josm.io.OsmTransferException;
27import org.openstreetmap.josm.tools.BugReportExceptionHandler;
28import org.openstreetmap.josm.tools.ExceptionUtil;
29
30/**
31 * This utility class provides static methods which explain various exceptions to the user.
32 *
33 */
34public final class ExceptionDialogUtil {
35
36 /**
37 * just static utility functions. no constructor
38 */
39 private ExceptionDialogUtil() {
40 }
41
42 /**
43 * handles an exception caught during OSM API initialization
44 *
45 * @param e the exception
46 */
47 public static void explainOsmApiInitializationException(OsmApiInitializationException e) {
48 HelpAwareOptionPane.showOptionDialog(
49 Main.parent,
50 ExceptionUtil.explainOsmApiInitializationException(e),
51 tr("Error"),
52 JOptionPane.ERROR_MESSAGE,
53 ht("/ErrorMessages#OsmApiInitializationException")
54 );
55 }
56
57 /**
58 * handles a ChangesetClosedException
59 *
60 * @param e the exception
61 */
62 public static void explainChangesetClosedException(ChangesetClosedException e) {
63 HelpAwareOptionPane.showOptionDialog(
64 Main.parent,
65 ExceptionUtil.explainChangesetClosedException(e),
66 tr("Error"),
67 JOptionPane.ERROR_MESSAGE,
68 ht("/Action/Upload#ChangesetClosed")
69 );
70 }
71
72 /**
73 * Explains an upload error due to a violated precondition, i.e. a HTTP return code 412
74 *
75 * @param e the exception
76 */
77 public static void explainPreconditionFailed(OsmApiException e) {
78 HelpAwareOptionPane.showOptionDialog(
79 Main.parent,
80 ExceptionUtil.explainPreconditionFailed(e),
81 tr("Precondition violation"),
82 JOptionPane.ERROR_MESSAGE,
83 ht("/ErrorMessages#OsmApiException")
84 );
85 }
86
87 /**
88 * Explains an exception with a generic message dialog
89 *
90 * @param e the exception
91 */
92 public static void explainGeneric(Exception e) {
93 Main.error(e);
94 BugReportExceptionHandler.handleException(e);
95 }
96
97 /**
98 * Explains a {@link SecurityException} which has caused an {@link OsmTransferException}.
99 * This is most likely happening when user tries to access the OSM API from within an
100 * applet which wasn't loaded from the API server.
101 *
102 * @param e the exception
103 */
104
105 public static void explainSecurityException(OsmTransferException e) {
106 HelpAwareOptionPane.showOptionDialog(
107 Main.parent,
108 ExceptionUtil.explainSecurityException(e),
109 tr("Security exception"),
110 JOptionPane.ERROR_MESSAGE,
111 ht("/ErrorMessages#SecurityException")
112 );
113 }
114
115 /**
116 * Explains a {@link SocketException} which has caused an {@link OsmTransferException}.
117 * This is most likely because there's not connection to the Internet or because
118 * the remote server is not reachable.
119 *
120 * @param e the exception
121 */
122
123 public static void explainNestedSocketException(OsmTransferException e) {
124 HelpAwareOptionPane.showOptionDialog(
125 Main.parent,
126 ExceptionUtil.explainNestedSocketException(e),
127 tr("Network exception"),
128 JOptionPane.ERROR_MESSAGE,
129 ht("/ErrorMessages#NestedSocketException")
130 );
131 }
132
133 /**
134 * Explains a {@link IOException} which has caused an {@link OsmTransferException}.
135 * This is most likely happening when the communication with the remote server is
136 * interrupted for any reason.
137 *
138 * @param e the exception
139 */
140
141 public static void explainNestedIOException(OsmTransferException e) {
142 HelpAwareOptionPane.showOptionDialog(
143 Main.parent,
144 ExceptionUtil.explainNestedIOException(e),
145 tr("IO Exception"),
146 JOptionPane.ERROR_MESSAGE,
147 ht("/ErrorMessages#NestedIOException")
148 );
149 }
150
151 /**
152 * Explains a {@link IllegalDataException} which has caused an {@link OsmTransferException}.
153 * This is most likely happening when JOSM tries to load data in an unsupported format.
154 *
155 * @param e the exception
156 */
157 public static void explainNestedIllegalDataException(OsmTransferException e) {
158 HelpAwareOptionPane.showOptionDialog(
159 Main.parent,
160 ExceptionUtil.explainNestedIllegalDataException(e),
161 tr("Illegal Data"),
162 JOptionPane.ERROR_MESSAGE,
163 ht("/ErrorMessages#IllegalDataException")
164 );
165 }
166
167 /**
168 * Explains a {@link OfflineAccessException} which has caused an {@link OsmTransferException}.
169 * This is most likely happening when JOSM tries to access OSM API or JOSM website while in offline mode.
170 *
171 * @param e the exception
172 * @since 7434
173 */
174 public static void explainNestedOfflineAccessException(OsmTransferException e) {
175 HelpAwareOptionPane.showOptionDialog(
176 Main.parent,
177 ExceptionUtil.explainOfflineAccessException(e),
178 tr("Offline mode"),
179 JOptionPane.ERROR_MESSAGE,
180 ht("/ErrorMessages#OfflineAccessException")
181 );
182 }
183
184 /**
185 * Explains a {@link InvocationTargetException }
186 *
187 * @param e the exception
188 */
189 public static void explainNestedInvocationTargetException(Exception e) {
190 InvocationTargetException ex = ExceptionUtil.getNestedException(e, InvocationTargetException.class);
191 if (ex != null) {
192 // Users should be able to submit a bug report for an invocation target exception
193 //
194 BugReportExceptionHandler.handleException(ex);
195 return;
196 }
197 }
198
199 /**
200 * Explains a {@link OsmApiException} which was thrown because of an internal server
201 * error in the OSM API server.
202 *
203 * @param e the exception
204 */
205
206 public static void explainInternalServerError(OsmTransferException e) {
207 HelpAwareOptionPane.showOptionDialog(
208 Main.parent,
209 ExceptionUtil.explainInternalServerError(e),
210 tr("Internal Server Error"),
211 JOptionPane.ERROR_MESSAGE,
212 ht("/ErrorMessages#InternalServerError")
213 );
214 }
215
216 /**
217 * Explains a {@link OsmApiException} which was thrown because of a bad
218 * request
219 *
220 * @param e the exception
221 */
222 public static void explainBadRequest(OsmApiException e) {
223 HelpAwareOptionPane.showOptionDialog(
224 Main.parent,
225 ExceptionUtil.explainBadRequest(e),
226 tr("Bad Request"),
227 JOptionPane.ERROR_MESSAGE,
228 ht("/ErrorMessages#BadRequest")
229 );
230 }
231
232 /**
233 * Explains a {@link OsmApiException} which was thrown because a resource wasn't found
234 * on the server
235 *
236 * @param e the exception
237 */
238 public static void explainNotFound(OsmApiException e) {
239 HelpAwareOptionPane.showOptionDialog(
240 Main.parent,
241 ExceptionUtil.explainNotFound(e),
242 tr("Not Found"),
243 JOptionPane.ERROR_MESSAGE,
244 ht("/ErrorMessages#NotFound")
245 );
246 }
247
248 /**
249 * Explains a {@link OsmApiException} which was thrown because of a conflict
250 *
251 * @param e the exception
252 */
253 public static void explainConflict(OsmApiException e) {
254 HelpAwareOptionPane.showOptionDialog(
255 Main.parent,
256 ExceptionUtil.explainConflict(e),
257 tr("Conflict"),
258 JOptionPane.ERROR_MESSAGE,
259 ht("/ErrorMessages#Conflict")
260 );
261 }
262
263 /**
264 * Explains a {@link OsmApiException} which was thrown because the authentication at
265 * the OSM server failed
266 *
267 * @param e the exception
268 */
269 public static void explainAuthenticationFailed(OsmApiException e) {
270 String msg;
271 if (OsmApi.isUsingOAuth()) {
272 msg = ExceptionUtil.explainFailedOAuthAuthentication(e);
273 } else {
274 msg = ExceptionUtil.explainFailedBasicAuthentication(e);
275 }
276
277 HelpAwareOptionPane.showOptionDialog(
278 Main.parent,
279 msg,
280 tr("Authentication Failed"),
281 JOptionPane.ERROR_MESSAGE,
282 ht("/ErrorMessages#AuthenticationFailed")
283 );
284 }
285
286 /**
287 * Explains a {@link OsmApiException} which was thrown because accessing a protected
288 * resource was forbidden (HTTP 403).
289 *
290 * @param e the exception
291 */
292 public static void explainAuthorizationFailed(OsmApiException e) {
293
294 Matcher m;
295 String msg;
296 String url = e.getAccessedUrl();
297 Pattern p = Pattern.compile("https?://.*/api/0.6/(node|way|relation)/(\\d+)/(\\d+)");
298
299 // Special case for individual access to redacted versions
300 // See http://wiki.openstreetmap.org/wiki/Open_Database_License/Changes_in_the_API
301 if (url != null && (m = p.matcher(url)).matches()) {
302 String type = m.group(1);
303 String id = m.group(2);
304 String version = m.group(3);
305 // {1} is the translation of "node", "way" or "relation"
306 msg = tr("Access to redacted version ''{0}'' of {1} {2} is forbidden.",
307 version, tr(type), id);
308 } else if (OsmApi.isUsingOAuth()) {
309 msg = ExceptionUtil.explainFailedOAuthAuthorisation(e);
310 } else {
311 msg = ExceptionUtil.explainFailedAuthorisation(e);
312 }
313
314 HelpAwareOptionPane.showOptionDialog(
315 Main.parent,
316 msg,
317 tr("Authorisation Failed"),
318 JOptionPane.ERROR_MESSAGE,
319 ht("/ErrorMessages#AuthorizationFailed")
320 );
321 }
322
323 /**
324 * Explains a {@link OsmApiException} which was thrown because of a
325 * client timeout (HTTP 408)
326 *
327 * @param e the exception
328 */
329 public static void explainClientTimeout(OsmApiException e) {
330 HelpAwareOptionPane.showOptionDialog(
331 Main.parent,
332 ExceptionUtil.explainClientTimeout(e),
333 tr("Client Time Out"),
334 JOptionPane.ERROR_MESSAGE,
335 ht("/ErrorMessages#ClientTimeOut")
336 );
337 }
338
339 /**
340 * Explains a {@link OsmApiException} which was thrown because of a
341 * bandwidth limit (HTTP 509)
342 *
343 * @param e the exception
344 */
345 public static void explainBandwidthLimitExceeded(OsmApiException e) {
346 HelpAwareOptionPane.showOptionDialog(
347 Main.parent,
348 ExceptionUtil.explainBandwidthLimitExceeded(e),
349 tr("Bandwidth Limit Exceeded"),
350 JOptionPane.ERROR_MESSAGE,
351 ht("/ErrorMessages#BandwidthLimit")
352 );
353 }
354
355 /**
356 * Explains a {@link OsmApiException} with a generic error
357 * message.
358 *
359 * @param e the exception
360 */
361 public static void explainGenericHttpException(OsmApiException e) {
362 HelpAwareOptionPane.showOptionDialog(
363 Main.parent,
364 ExceptionUtil.explainClientTimeout(e),
365 tr("Communication with OSM server failed"),
366 JOptionPane.ERROR_MESSAGE,
367 ht("/ErrorMessages#GenericCommunicationError")
368 );
369 }
370
371 /**
372 * Explains a {@link OsmApiException} which was thrown because accessing a protected
373 * resource was forbidden.
374 *
375 * @param e the exception
376 */
377 public static void explainMissingOAuthAccessTokenException(MissingOAuthAccessTokenException e) {
378 HelpAwareOptionPane.showOptionDialog(
379 Main.parent,
380 ExceptionUtil.explainMissingOAuthAccessTokenException(e),
381 tr("Authentication failed"),
382 JOptionPane.ERROR_MESSAGE,
383 ht("/ErrorMessages#MissingOAuthAccessToken")
384 );
385 }
386
387 /**
388 * Explains a {@link UnknownHostException} which has caused an {@link OsmTransferException}.
389 * This is most likely happening when there is an error in the API URL or when
390 * local DNS services are not working.
391 *
392 * @param e the exception
393 */
394
395 public static void explainNestedUnkonwnHostException(OsmTransferException e) {
396 HelpAwareOptionPane.showOptionDialog(
397 Main.parent,
398 ExceptionUtil.explainNestedUnknownHostException(e),
399 tr("Unknown host"),
400 JOptionPane.ERROR_MESSAGE,
401 ht("/ErrorMessages#UnknownHost")
402 );
403 }
404
405 /**
406 * Explains an {@link OsmTransferException} to the user.
407 *
408 * @param e the {@link OsmTransferException}
409 */
410 public static void explainOsmTransferException(OsmTransferException e) {
411 if (ExceptionUtil.getNestedException(e, SecurityException.class) != null) {
412 explainSecurityException(e);
413 return;
414 }
415 if (ExceptionUtil.getNestedException(e, SocketException.class) != null) {
416 explainNestedSocketException(e);
417 return;
418 }
419 if (ExceptionUtil.getNestedException(e, UnknownHostException.class) != null) {
420 explainNestedUnkonwnHostException(e);
421 return;
422 }
423 if (ExceptionUtil.getNestedException(e, IOException.class) != null) {
424 explainNestedIOException(e);
425 return;
426 }
427 if (ExceptionUtil.getNestedException(e, IllegalDataException.class) != null) {
428 explainNestedIllegalDataException(e);
429 return;
430 }
431 if (ExceptionUtil.getNestedException(e, OfflineAccessException.class) != null) {
432 explainNestedOfflineAccessException(e);
433 return;
434 }
435 if (e instanceof OsmApiInitializationException) {
436 explainOsmApiInitializationException((OsmApiInitializationException) e);
437 return;
438 }
439
440 if (e instanceof ChangesetClosedException) {
441 explainChangesetClosedException((ChangesetClosedException) e);
442 return;
443 }
444
445 if (e instanceof MissingOAuthAccessTokenException) {
446 explainMissingOAuthAccessTokenException((MissingOAuthAccessTokenException) e);
447 return;
448 }
449
450 if (e instanceof OsmApiException) {
451 OsmApiException oae = (OsmApiException) e;
452 switch(oae.getResponseCode()) {
453 case HttpURLConnection.HTTP_PRECON_FAILED:
454 explainPreconditionFailed(oae);
455 return;
456 case HttpURLConnection.HTTP_GONE:
457 explainGoneForUnknownPrimitive(oae);
458 return;
459 case HttpURLConnection.HTTP_INTERNAL_ERROR:
460 explainInternalServerError(oae);
461 return;
462 case HttpURLConnection.HTTP_BAD_REQUEST:
463 explainBadRequest(oae);
464 return;
465 case HttpURLConnection.HTTP_NOT_FOUND:
466 explainNotFound(oae);
467 return;
468 case HttpURLConnection.HTTP_CONFLICT:
469 explainConflict(oae);
470 return;
471 case HttpURLConnection.HTTP_UNAUTHORIZED:
472 explainAuthenticationFailed(oae);
473 return;
474 case HttpURLConnection.HTTP_FORBIDDEN:
475 explainAuthorizationFailed(oae);
476 return;
477 case HttpURLConnection.HTTP_CLIENT_TIMEOUT:
478 explainClientTimeout(oae);
479 return;
480 case 509:
481 explainBandwidthLimitExceeded(oae);
482 return;
483 default:
484 explainGenericHttpException(oae);
485 return;
486 }
487 }
488 explainGeneric(e);
489 }
490
491 /**
492 * explains the case of an error due to a delete request on an already deleted
493 * {@link OsmPrimitive}, i.e. a HTTP response code 410, where we don't know which
494 * {@link OsmPrimitive} is causing the error.
495 *
496 * @param e the exception
497 */
498 public static void explainGoneForUnknownPrimitive(OsmApiException e) {
499 HelpAwareOptionPane.showOptionDialog(
500 Main.parent,
501 ExceptionUtil.explainGoneForUnknownPrimitive(e),
502 tr("Object deleted"),
503 JOptionPane.ERROR_MESSAGE,
504 ht("/ErrorMessages#GoneForUnknownPrimitive")
505 );
506 }
507
508 /**
509 * Explains an {@link Exception} to the user.
510 *
511 * @param e the {@link Exception}
512 */
513 public static void explainException(Exception e) {
514 if (ExceptionUtil.getNestedException(e, InvocationTargetException.class) != null) {
515 explainNestedInvocationTargetException(e);
516 return;
517 }
518 if (e instanceof OsmTransferException) {
519 explainOsmTransferException((OsmTransferException) e);
520 return;
521 }
522 explainGeneric(e);
523 }
524}
Note: See TracBrowser for help on using the repository browser.