Ticket #2429: cancel-upload.patch

File cancel-upload.patch, 7.8 KB (added by Gubaer, 17 years ago)

Patch

  • OsmApi.java

     
    2222import java.util.Collection;
    2323import java.util.Properties;
    2424import java.util.StringTokenizer;
     25import java.util.concurrent.FutureTask;
    2526
    2627import javax.xml.parsers.SAXParserFactory;
    2728
     
    3233import org.openstreetmap.josm.data.osm.Relation;
    3334import org.openstreetmap.josm.data.osm.Way;
    3435import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor;
     36import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    3537import org.xml.sax.Attributes;
    3638import org.xml.sax.InputSource;
    3739import org.xml.sax.SAXException;
     
    285287    }
    286288
    287289    /**
    288      * Uploads a list of changes in "diff" form the the server.
     290     * Uploads a list of changes in "diff" form to he the server.
     291     * 
    289292     * @param list the list of changed OSM Primitives
    290293     * @return list of processed primitives
    291      * @throws OsmTransferException if something is wrong.
     294     * @throws OsmTransferException if something is wrong
     295     * @throws OsmTransferCancelledException  if the upload was cancelled by the user
    292296     */
    293     public Collection<OsmPrimitive> uploadDiff(Collection<OsmPrimitive> list) throws OsmTransferException {
     297    public Collection<OsmPrimitive> uploadDiff(final Collection<OsmPrimitive> list) throws OsmTransferException {
    294298   
    295299        if (changeset == null) {
    296300            throw new OsmTransferException(tr("No changeset present for diff upload"));
    297301        }
    298302       
    299         CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, this);
    300303       
    301         ArrayList<OsmPrimitive> processed = new ArrayList<OsmPrimitive>();
    302    
    303         for (OsmPrimitive osm : list) {
    304             int progress = Main.pleaseWaitDlg.progress.getValue();
    305             Main.pleaseWaitDlg.currentAction.setText(tr("Preparing..."));
    306             if (cancel) throw new OsmTransferCancelledException();
    307             osm.visit(duv);
    308             Main.pleaseWaitDlg.progress.setValue(progress+1);
     304        final ArrayList<OsmPrimitive> processed = new ArrayList<OsmPrimitive>();
     305       
     306        // this is the asynchronous update task
     307        //
     308        class UploadDiffTask extends  PleaseWaitRunnable {
     309           
     310            private boolean uploadCancelled = false;
     311            private boolean uploadFailed = false;
     312            private Throwable lastThrowable = null;
     313           
     314            public UploadDiffTask(String title) {
     315                super(title,false /* don't ignore exceptions */);
     316            }
     317           
     318            @Override protected void realRun() throws SAXException, IOException {
     319                CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, OsmApi.this);
     320           
     321                for (OsmPrimitive osm : list) {
     322                    int progress = Main.pleaseWaitDlg.progress.getValue();
     323                    Main.pleaseWaitDlg.currentAction.setText(tr("Preparing..."));
     324                    osm.visit(duv);
     325                    Main.pleaseWaitDlg.progress.setValue(progress+1);
     326                }
     327           
     328                Main.pleaseWaitDlg.currentAction.setText(tr("Uploading..."));
     329           
     330                String diff = duv.getDocument();
     331                try {
     332                    String diffresult = sendRequest("POST", "changeset/" + changeset.id + "/upload", diff); 
     333                    DiffResultReader.parseDiffResult(diffresult, list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg);
     334                } catch (Exception sxe) {
     335                    if (isUploadCancelled()) {
     336                        // ignore exceptions thrown because the connection is aborted,
     337                        // i.e. IOExceptions or SocketExceptions
     338                        //
     339                        System.out.println("Ignoring exception caught because upload is cancelled. Exception is: " + sxe.toString());
     340                        return;
     341                    }
     342                    uploadFailed = true;
     343                    // remember last exception and don't throw it. If it was thrown again it would
     344                    // have to be encapsulated in a RuntimeException which would be nested in yet
     345                    // another RuntimeException by parent classes.
     346                    // Rather check isUploadFailed() and retrieve getLastThrowable() after the task
     347                    // is completed
     348                    //
     349                    lastThrowable = sxe;
     350                }
     351            }
     352           
     353            @Override protected void finish() {
     354                // do nothing
     355            }
     356           
     357            @Override protected void cancel() {
     358                activeConnection.disconnect();
     359                uploadCancelled = true;
     360            }
     361           
     362            public boolean isUploadCancelled() {
     363                return uploadCancelled;
     364            }
     365           
     366            public boolean isUploadFailed() {
     367                return uploadFailed;
     368            }
     369           
     370            public Throwable getLastThrowable() {
     371                return lastThrowable;               
     372            }
    309373        }
    310    
    311         Main.pleaseWaitDlg.currentAction.setText(tr("Uploading..."));
    312         if (cancel) throw new OsmTransferCancelledException();
    313    
    314         String diff = duv.getDocument();
    315         String diffresult = sendRequest("POST", "changeset/" + changeset.id + "/upload", diff); 
    316         try {
    317             DiffResultReader.parseDiffResult(diffresult, list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg);
    318         } catch (Exception sxe) {
    319             throw new OsmTransferException(tr("Error processing changeset upload response"), sxe);
     374       
     375        UploadDiffTask uploadTask = new UploadDiffTask(tr("Uploading data"));
     376       
     377        // run  data upload as asynchronous task
     378        //
     379        try {           
     380            Void result = null;
     381            FutureTask<Void> task = new FutureTask<Void>(uploadTask, result);
     382            task.run();
     383            task.get(); // wait for the task to complete, no return value expected, though           
     384        }  catch(Throwable e) {
     385            if (uploadTask.isUploadCancelled()) {
     386                throw new OsmTransferCancelledException();
     387            }
     388            throw new OsmTransferException(e);
     389        }
     390       
     391        // handle failed upload
     392        //
     393        if (uploadTask.isUploadFailed()) {
     394            if (uploadTask.getLastThrowable() != null && uploadTask.getLastThrowable() instanceof OsmTransferException) {
     395                OsmTransferException e = (OsmTransferException)uploadTask.getLastThrowable();
     396                throw e;
     397            }
     398            // shouldn't happen, but just in case
     399            //
     400            throw new OsmTransferException("Data upload failed for an unknown reason");
    320401        }
     402       
     403        // handle cancelled upload
     404        //
     405        if (uploadTask.isUploadCancelled()) {
     406            throw new OsmTransferCancelledException();
     407        }
     408       
    321409        return processed;
    322410    }
     411   
     412   
    323413
    324414    private void sleepAndListen() throws OsmTransferCancelledException {
    325415        // System.out.print("backing off for 10 seconds...");
  • OsmServerWriter.java

     
    137137    }
    138138
    139139    private void dealWithTransferException (OsmTransferException e) {
     140        if (e instanceof OsmTransferCancelledException) {
     141            // ignore - don't bother the user with yet another message that he
     142            // has successfully cancelled the data upload
     143            //
     144            return;
     145        }
     146       
    140147        JOptionPane.showMessageDialog(Main.parent,
    141148            /* tr("Error during upload: ") + */ e.getMessage());
    142149    }