Changeset 2198 in josm for trunk/src/org/openstreetmap/josm/actions/UploadAction.java
- Timestamp:
- 2009-09-27T16:29:21+02:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/UploadAction.java
r2189 r2198 11 11 import java.util.Collection; 12 12 import java.util.Date; 13 import java.util.HashSet; 13 14 import java.util.LinkedList; 14 15 import java.util.logging.Logger; … … 29 30 import org.openstreetmap.josm.data.osm.OsmPrimitive; 30 31 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 32 import org.openstreetmap.josm.gui.DefaultNameFormatter; 31 33 import org.openstreetmap.josm.gui.ExceptionDialogUtil; 32 34 import org.openstreetmap.josm.gui.PleaseWaitRunnable; … … 37 39 import org.openstreetmap.josm.io.OsmApiException; 38 40 import org.openstreetmap.josm.io.OsmApiInitializationException; 41 import org.openstreetmap.josm.io.OsmApiPrimitiveGoneException; 39 42 import org.openstreetmap.josm.io.OsmChangesetCloseException; 40 43 import org.openstreetmap.josm.io.OsmServerWriter; 44 import org.openstreetmap.josm.io.OsmTransferException; 41 45 import org.openstreetmap.josm.tools.DateUtils; 42 46 import org.openstreetmap.josm.tools.Shortcut; … … 350 354 * @see UpdateSelectionAction#handlePrimitiveGoneException(long) 351 355 */ 352 protected void handleGoneForKnownPrimitive(OsmPrimitiveType primitiveType, String id) {356 protected void handleGoneForKnownPrimitive(OsmPrimitiveType primitiveType, long id) { 353 357 UpdateSelectionAction act = new UpdateSelectionAction(); 354 act.handlePrimitiveGoneException( Long.parseLong(id),primitiveType);358 act.handlePrimitiveGoneException(id,primitiveType); 355 359 } 356 360 … … 363 367 * @param e the exception 364 368 */ 365 protected void handleGone(OsmApiException e) { 366 String pattern = "The (\\S+) with the id (\\d+) has already been deleted"; 367 Pattern p = Pattern.compile(pattern); 368 Matcher m = p.matcher(e.getErrorHeader()); 369 if (m.matches()) { 370 handleGoneForKnownPrimitive(OsmPrimitiveType.from(m.group(1)), m.group(2)); 369 protected void handleGone(OsmApiPrimitiveGoneException e) { 370 if (e.isKnownPrimitive()) { 371 handleGoneForKnownPrimitive(e.getPrimitiveType(), e.getPrimitiveId()); 371 372 } else { 372 logger.warning(tr("Error header \"{0}\" does not match expected pattern \"{1}\"",e.getErrorHeader(), pattern));373 373 ExceptionDialogUtil.explainGoneForUnknownPrimitive(e); 374 374 } … … 391 391 if (e instanceof OsmChangesetCloseException) { 392 392 ExceptionDialogUtil.explainOsmChangesetCloseException((OsmChangesetCloseException)e); 393 return; 394 } 395 if (e instanceof OsmApiPrimitiveGoneException) { 396 handleGone((OsmApiPrimitiveGoneException)e); 393 397 return; 394 398 } … … 406 410 else if (ex.getResponseCode() == HttpURLConnection.HTTP_PRECON_FAILED) { 407 411 ExceptionDialogUtil.explainPreconditionFailed(ex); 408 return;409 }410 // Tried to delete an already deleted primitive? Let the user411 // decide whether and how to resolve this conflict.412 //413 else if (ex.getResponseCode() == HttpURLConnection.HTTP_GONE) {414 handleGone(ex);415 412 return; 416 413 } … … 489 486 } 490 487 491 public Upload DiffTask createUploadTask(OsmDataLayer layer, Collection<OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) {492 return new Upload DiffTask(layer, toUpload, changeset, closeChangesetAfterUpload);488 public UploadPrimitivesTask createUploadTask(OsmDataLayer layer, Collection<OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) { 489 return new UploadPrimitivesTask(layer, toUpload, changeset, closeChangesetAfterUpload); 493 490 } 494 491 … … 497 494 * 498 495 */ 499 public class Upload DiffTask extends PleaseWaitRunnable {496 public class UploadPrimitivesTask extends PleaseWaitRunnable { 500 497 private boolean uploadCancelled = false; 501 498 private Exception lastException = null; … … 505 502 private Changeset changeset; 506 503 private boolean closeChangesetAfterUpload; 504 private HashSet<OsmPrimitive> processedPrimitives; 507 505 508 506 /** … … 513 511 * @param closeChangesetAfterUpload true, if the changeset is to be closed after uploading 514 512 */ 515 private Upload DiffTask(OsmDataLayer layer, Collection <OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) {513 private UploadPrimitivesTask(OsmDataLayer layer, Collection <OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) { 516 514 super(tr("Uploading data for layer ''{0}''", layer.getName()),false /* don't ignore exceptions */); 517 515 this.toUpload = toUpload; … … 519 517 this.changeset = changeset; 520 518 this.closeChangesetAfterUpload = closeChangesetAfterUpload; 519 this.processedPrimitives = new HashSet<OsmPrimitive>(); 520 } 521 522 protected OsmPrimitive getPrimitive(OsmPrimitiveType type, long id) { 523 for (OsmPrimitive p: toUpload) { 524 if (OsmPrimitiveType.from(p).equals(type) && p.getId() == id) 525 return p; 526 } 527 return null; 528 } 529 530 /** 531 * Retries to recover the upload operation from an exception which was thrown because 532 * an uploaded primitive was already deleted on the server. 533 * 534 * @param e the exception throw by the API 535 * @param monitor a progress monitor 536 * @throws OsmTransferException thrown if we can't recover from the exception 537 */ 538 protected void recoverFromGoneOnServer(OsmApiPrimitiveGoneException e, ProgressMonitor monitor) throws OsmTransferException{ 539 if (!e.isKnownPrimitive()) throw e; 540 OsmPrimitive p = getPrimitive(e.getPrimitiveType(), e.getPrimitiveId()); 541 if (p == null) throw e; 542 if (p.isDeleted()) { 543 // we tried to delete an already deleted primitive. 544 // 545 System.out.println(tr("Warning: primitive ''{0}'' is already deleted on the server. Skipping this primitive and retrying to upload.", p.getDisplayName(DefaultNameFormatter.getInstance()))); 546 processedPrimitives.addAll(writer.getProcessedPrimitives()); 547 processedPrimitives.add(p); 548 toUpload.removeAll(processedPrimitives); 549 return; 550 } 551 // exception was thrown because we tried to *update* an already deleted 552 // primitive. We can't resolve this automatically. Re-throw exception, 553 // a conflict is going to be created later. 554 throw e; 521 555 } 522 556 … … 524 558 writer = new OsmServerWriter(); 525 559 try { 526 ProgressMonitor monitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false); 527 writer.uploadOsm(layer.data.version, toUpload, changeset,closeChangesetAfterUpload, monitor); 528 } catch (Exception sxe) { 560 // 561 while(true) { 562 try { 563 ProgressMonitor monitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false); 564 writer.uploadOsm(layer.data.version, toUpload, changeset, monitor); 565 processedPrimitives.addAll(writer.getProcessedPrimitives()); 566 // if we get here we've successfully uploaded the data. We 567 // can exit the loop. 568 // 569 break; 570 } catch(OsmApiPrimitiveGoneException e) { 571 // try to recover from the 410 Gone 572 recoverFromGoneOnServer(e, getProgressMonitor()); 573 } 574 } 575 // if required close the changeset 576 // 577 if (closeChangesetAfterUpload) { 578 if (changeset != null && changeset.getId() > 0) { 579 OsmApi.getOsmApi().closeChangeset(changeset, progressMonitor.createSubTaskMonitor(0,false)); 580 } 581 } 582 } catch (Exception e) { 529 583 if (uploadCancelled) { 530 System.out.println("Ignoring exception caught because upload is cancelled. Exception is: " + sxe.toString());584 System.out.println("Ignoring exception caught because upload is cancelled. Exception is: " + e.toString()); 531 585 return; 532 586 } 533 lastException = sxe;587 lastException = e; 534 588 } 535 589 } … … 539 593 return; 540 594 541 // we always clean the data, even in case of errors. It's possible the data was595 // we always clean up the data, even in case of errors. It's possible the data was 542 596 // partially uploaded 543 597 // 544 layer.cleanupAfterUpload( writer.getProcessedPrimitives());598 layer.cleanupAfterUpload(processedPrimitives); 545 599 DataSet.fireSelectionChanged(layer.data.getSelected()); 546 600 layer.fireDataChange(); 547 601 if (lastException != null) { 548 602 handleFailedUpload(lastException); 549 } else { 550 // run post upload action on the layer 551 // 552 layer.onPostUploadToServer(); 553 // refresh changeset dialog with the updated changeset 554 // 555 UploadDialog.getUploadDialog().setOrUpdateChangeset(changeset); 556 } 603 } 604 layer.onPostUploadToServer(); 605 UploadDialog.getUploadDialog().setOrUpdateChangeset(changeset); 557 606 } 558 607 … … 563 612 } 564 613 } 565 566 public boolean isSuccessful() {567 return !isCancelled() && !isFailed();568 }569 570 public boolean isCancelled() {571 return uploadCancelled;572 }573 574 public boolean isFailed() {575 return lastException != null;576 }577 614 } 578 615 }
Note:
See TracChangeset
for help on using the changeset viewer.