Ticket #8509: asyn_v0.patch

File asyn_v0.patch, 9.7 KB (added by udit, 6 years ago)

Patch for Asynchronous uploads in JOSM. This is a version_0

  • src/org/openstreetmap/josm/actions/UploadAction.java

     
    99import java.util.LinkedList;
    1010import java.util.List;
    1111import java.util.Map;
     12import java.util.Optional;
    1213
    1314import javax.swing.JOptionPane;
    1415
     
    2425import org.openstreetmap.josm.data.osm.Changeset;
    2526import org.openstreetmap.josm.gui.HelpAwareOptionPane;
    2627import org.openstreetmap.josm.gui.MainApplication;
     28import org.openstreetmap.josm.gui.io.AsynchronousUploadPrimitivesTask;
    2729import org.openstreetmap.josm.gui.io.UploadDialog;
    28 import org.openstreetmap.josm.gui.io.UploadPrimitivesTask;
    2930import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
    3031import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3132import org.openstreetmap.josm.gui.util.GuiHelper;
     
    257258            hook.modifyChangesetTags(changesetTags);
    258259        }
    259260
    260         MainApplication.worker.execute(
    261                 new UploadPrimitivesTask(
    262                         UploadDialog.getUploadDialog().getUploadStrategySpecification(),
    263                         layer,
    264                         apiData,
    265                         cs
    266                 )
    267         );
     261        Optional<AsynchronousUploadPrimitivesTask> optionTask = AsynchronousUploadPrimitivesTask.createAsynchronousUploadTask(
     262                UploadDialog.getUploadDialog().getUploadStrategySpecification(),
     263                layer,
     264                apiData,
     265                cs);
     266        if (optionTask.isPresent()) {
     267            MainApplication.worker.execute(optionTask.get());
     268        }
    268269    }
    269270
    270271    @Override
  • src/org/openstreetmap/josm/gui/io/AsynchronousUploadPrimitivesTask.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.io;
     3
     4import org.openstreetmap.josm.data.APIDataSet;
     5import org.openstreetmap.josm.data.osm.Changeset;
     6import org.openstreetmap.josm.data.osm.DataSet;
     7import org.openstreetmap.josm.data.osm.OsmPrimitive;
     8import org.openstreetmap.josm.gui.MainApplication;
     9import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     10import org.openstreetmap.josm.gui.progress.ProgressTaskId;
     11import org.openstreetmap.josm.gui.util.GuiHelper;
     12import org.openstreetmap.josm.io.UploadStrategySpecification;
     13import org.openstreetmap.josm.tools.I18n;
     14
     15import javax.swing.*;
     16import java.awt.*;
     17import java.util.List;
     18import java.util.Optional;
     19
     20/**
     21 * Allows to upload the primitives in background
     22 */
     23public class AsynchronousUploadPrimitivesTask extends UploadPrimitivesTask {
     24
     25    // Static instance
     26    private static AsynchronousUploadPrimitivesTask asynchronousUploadPrimitivesTask = null;
     27
     28    // flag to hide primitives to be uploaded.
     29    private static final boolean hideUploadingPrimitives = false;
     30
     31    private final ProgressTaskId taskId;
     32    private final DataSet dataSet;
     33    private final List<OsmPrimitive> osmPrimitiveList;
     34
     35    // Restrict creating more Asynchronous upload tasks
     36    private AsynchronousUploadPrimitivesTask(UploadStrategySpecification uploadStrategySpecification, OsmDataLayer osmDataLayer, APIDataSet apiDataSet, Changeset changeset) {
     37        super(uploadStrategySpecification,
     38                osmDataLayer,
     39                apiDataSet,
     40                changeset);
     41        dataSet = osmDataLayer.data;
     42        osmPrimitiveList = apiDataSet.getPrimitives();
     43        disablePrimitives(osmPrimitiveList);
     44        taskId = new ProgressTaskId("core", "async-upload");
     45    }
     46
     47    private static void disablePrimitives(List <OsmPrimitive> osmPrimitiveList) {
     48        for (OsmPrimitive p : osmPrimitiveList) {
     49
     50            // Disable primitives to be uploaded.
     51            p.setDisabledState(hideUploadingPrimitives);
     52
     53            // Disable the referrers of the primitives to be uploaded.
     54            for (OsmPrimitive referrer : p.getReferrers()) {
     55                referrer.setDisabledState(hideUploadingPrimitives);
     56            }
     57        }
     58    }
     59
     60    private static void enablePrimitives(List <OsmPrimitive> osmPrimitiveList) {
     61        for (OsmPrimitive p : osmPrimitiveList) {
     62
     63            // Disable primitives to be uploaded.
     64            p.unsetDisabledState();
     65
     66            // Disable the referrers of the primitives to be uploaded.
     67            for (OsmPrimitive referrer : p.getReferrers()) {
     68                referrer.unsetDisabledState();
     69            }
     70        }
     71    }
     72
     73    public static Optional<AsynchronousUploadPrimitivesTask> createAsynchronousUploadTask
     74            (UploadStrategySpecification uploadStrategySpecification,
     75             OsmDataLayer dataLayer, APIDataSet toUpload, Changeset changeset) {
     76        synchronized (AsynchronousUploadPrimitivesTask.class) {
     77            if (asynchronousUploadPrimitivesTask != null) {
     78                if (!GraphicsEnvironment.isHeadless()) {
     79                    GuiHelper.runInEDTAndWait(() ->
     80                            JOptionPane.showMessageDialog(MainApplication.parent,
     81                                    I18n.tr("A background upload is already in progress. Kindly wait for it to finish before uploading new changes")));
     82                }
     83                return Optional.empty();
     84            } else {
     85                DataSet safeCopy = new DataSet(dataLayer.data);
     86                asynchronousUploadPrimitivesTask = new AsynchronousUploadPrimitivesTask(
     87                        uploadStrategySpecification,
     88                        dataLayer,
     89                        toUpload,
     90                        changeset);
     91                return Optional.ofNullable(asynchronousUploadPrimitivesTask);
     92            }
     93        }
     94    }
     95
     96    public static Optional<AsynchronousUploadPrimitivesTask> getCurrentAsynchronousUploadTask () {
     97        return Optional.ofNullable(asynchronousUploadPrimitivesTask);
     98    }
     99
     100    @Override
     101    public ProgressTaskId canRunInBackground() {
     102        return taskId;
     103    }
     104
     105    @Override
     106    protected void realRun() {
     107        super.realRun();
     108    }
     109
     110    @Override
     111    protected void cancel() {
     112        super.cancel();
     113        // Free up the async uploader
     114        enablePrimitives(osmPrimitiveList);
     115        asynchronousUploadPrimitivesTask = null;
     116    }
     117
     118    @Override
     119    protected void finish() {
     120        super.finish();
     121        // Free up the async uploader
     122        enablePrimitives(osmPrimitiveList);
     123        asynchronousUploadPrimitivesTask = null;
     124    }
     125}
  • test/unit/org/openstreetmap/josm/gui/io/AsynchronousUploadPrimitivesTaskTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.io;
     3
     4import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     5import org.junit.*;
     6import org.openstreetmap.josm.data.APIDataSet;
     7import org.openstreetmap.josm.data.coor.LatLon;
     8import org.openstreetmap.josm.data.osm.*;
     9import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     10import org.openstreetmap.josm.io.UploadStrategySpecification;
     11import org.openstreetmap.josm.testutils.JOSMTestRules;
     12
     13import java.util.*;
     14
     15public class AsynchronousUploadPrimitivesTaskTest {
     16
     17    private UploadStrategySpecification strategy;
     18    private OsmDataLayer layer;
     19    private APIDataSet toUpload;
     20    private Changeset changeset;
     21    private AsynchronousUploadPrimitivesTask uploadPrimitivesTask;
     22
     23    /**
     24     * Setup tests
     25     */
     26    @Rule
     27    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     28    public JOSMTestRules test = new JOSMTestRules();
     29
     30    @Before
     31    public void bootStrap() {
     32        DataSet dataSet = new DataSet();
     33        Node node1 = new Node();
     34        Node node2 = new Node();
     35        node1.setCoor(new LatLon(0, 0));
     36        node2.setCoor(new LatLon(30, 30));
     37        Way way = new Way();
     38        way.addNode(node1);
     39        way.addNode(node2);
     40        dataSet.addPrimitive(node1);
     41        dataSet.addPrimitive(node2);
     42        dataSet.addPrimitive(way);
     43
     44        toUpload = new APIDataSet(dataSet);
     45        layer = new OsmDataLayer(dataSet, "uploadTest", null);
     46        strategy = new UploadStrategySpecification();
     47        changeset = new Changeset();
     48        if (AsynchronousUploadPrimitivesTask.getCurrentAsynchronousUploadTask().isPresent()) {
     49            uploadPrimitivesTask = AsynchronousUploadPrimitivesTask.getCurrentAsynchronousUploadTask().get();
     50        } else {
     51            uploadPrimitivesTask = AsynchronousUploadPrimitivesTask.createAsynchronousUploadTask(strategy, layer, toUpload, changeset).get();
     52        }
     53    }
     54
     55    @After
     56    public void tearDown () {
     57        toUpload = null;
     58        layer = null;
     59        strategy = null;
     60        changeset = null;
     61        uploadPrimitivesTask = null;
     62    }
     63
     64    @Test
     65    public void testSingleUploadInstance () {
     66        Optional<AsynchronousUploadPrimitivesTask> task = AsynchronousUploadPrimitivesTask.createAsynchronousUploadTask(strategy, layer, toUpload, changeset);
     67        Assert.assertFalse(task.isPresent());
     68    }
     69
     70    @Test
     71    public void testPrimitivesToUploadAreDisabled () {
     72        for (OsmPrimitive p : layer.data.allPrimitives()) {
     73            Assert.assertTrue(p.isDisabled());
     74        }
     75    }
     76}