source: josm/trunk/src/org/openstreetmap/josm/gui/io/AsynchronousUploadPrimitivesTask.java@ 13654

Last change on this file since 13654 was 13654, checked in by Don-vip, 6 years ago

More uses of OsmDataLayer.getDataSet()

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GraphicsEnvironment;
7import java.util.Optional;
8
9import javax.swing.JOptionPane;
10
11import org.openstreetmap.josm.data.APIDataSet;
12import org.openstreetmap.josm.data.osm.Changeset;
13import org.openstreetmap.josm.gui.MainApplication;
14import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
15import org.openstreetmap.josm.gui.layer.OsmDataLayer;
16import org.openstreetmap.josm.gui.progress.ProgressTaskId;
17import org.openstreetmap.josm.gui.util.GuiHelper;
18import org.openstreetmap.josm.io.UploadStrategySpecification;
19
20/**
21 * Task for uploading primitives using background worker threads. The actual upload is delegated to the
22 * {@link UploadPrimitivesTask}. This class is a wrapper over that to make the background upload process safe. There
23 * can only be one instance of this class, hence background uploads are limited to one at a time. This class also
24 * changes the editLayer of {@link org.openstreetmap.josm.gui.layer.MainLayerManager} to null during upload so that
25 * any changes to the uploading layer are prohibited.
26 *
27 * @author udit
28 * @since 13133
29 */
30public final class AsynchronousUploadPrimitivesTask extends UploadPrimitivesTask {
31
32 /**
33 * Static instance
34 */
35 private static AsynchronousUploadPrimitivesTask asynchronousUploadPrimitivesTask;
36
37 /**
38 * Member fields
39 */
40 private final ProgressTaskId taskId;
41 private final OsmDataLayer uploadDataLayer;
42
43 /**
44 * Private constructor to restrict creating more Asynchronous upload tasks
45 *
46 * @param uploadStrategySpecification UploadStrategySpecification for the DataLayer
47 * @param osmDataLayer Datalayer to be uploaded
48 * @param apiDataSet ApiDataSet that contains the primitives to be uploaded
49 * @param changeset Changeset for the datalayer
50 *
51 * @throws IllegalArgumentException if layer is null
52 * @throws IllegalArgumentException if toUpload is null
53 * @throws IllegalArgumentException if strategy is null
54 * @throws IllegalArgumentException if changeset is null
55 */
56 private AsynchronousUploadPrimitivesTask(UploadStrategySpecification uploadStrategySpecification,
57 OsmDataLayer osmDataLayer, APIDataSet apiDataSet, Changeset changeset) {
58 super(uploadStrategySpecification,
59 osmDataLayer,
60 apiDataSet,
61 changeset);
62
63 uploadDataLayer = osmDataLayer;
64 // Create a ProgressTaskId for background upload
65 taskId = new ProgressTaskId("core", "async-upload");
66 }
67
68 /**
69 * Creates an instance of AsynchronousUploadPrimitiveTask
70 *
71 * @param uploadStrategySpecification UploadStrategySpecification for the DataLayer
72 * @param dataLayer Datalayer to be uploaded
73 * @param apiDataSet ApiDataSet that contains the primitives to be uploaded
74 * @param changeset Changeset for the datalayer
75 * @return Returns an {@literal Optional<AsynchronousUploadPrimitivesTask> } if there is no
76 * background upload in progress. Otherwise returns an {@literal Optional.empty()}
77 *
78 * @throws IllegalArgumentException if layer is null
79 * @throws IllegalArgumentException if toUpload is null
80 * @throws IllegalArgumentException if strategy is null
81 * @throws IllegalArgumentException if changeset is null
82 */
83 public static Optional<AsynchronousUploadPrimitivesTask> createAsynchronousUploadTask(
84 UploadStrategySpecification uploadStrategySpecification,
85 OsmDataLayer dataLayer, APIDataSet apiDataSet, Changeset changeset) {
86 synchronized (AsynchronousUploadPrimitivesTask.class) {
87 if (asynchronousUploadPrimitivesTask != null) {
88 if (!GraphicsEnvironment.isHeadless()) {
89 GuiHelper.runInEDTAndWait(() ->
90 JOptionPane.showMessageDialog(MainApplication.parent,
91 tr("A background upload is already in progress. " +
92 "Kindly wait for it to finish before uploading new changes")));
93 }
94 return Optional.empty();
95 } else {
96 // Create an asynchronous upload task
97 asynchronousUploadPrimitivesTask = new AsynchronousUploadPrimitivesTask(
98 uploadStrategySpecification,
99 dataLayer,
100 apiDataSet,
101 changeset);
102 return Optional.ofNullable(asynchronousUploadPrimitivesTask);
103 }
104 }
105 }
106
107 /**
108 * Get the current upload task
109 * @return {@literal Optional<AsynchronousUploadPrimitivesTask> }
110 */
111 public static Optional<AsynchronousUploadPrimitivesTask> getCurrentAsynchronousUploadTask() {
112 return Optional.ofNullable(asynchronousUploadPrimitivesTask);
113 }
114
115 @Override
116 public ProgressTaskId canRunInBackground() {
117 return taskId;
118 }
119
120 @Override
121 protected void realRun() {
122 // Lock the data layer before upload in EDT
123 GuiHelper.runInEDTAndWait(() -> {
124 // Remove the commands from the undo stack
125 MainApplication.undoRedo.clean(uploadDataLayer.getDataSet());
126 MainApplication.getLayerManager().prepareLayerForUpload(uploadDataLayer);
127
128 // Repainting the Layer List dialog to update the icon of the active layer
129 LayerListDialog.getInstance().repaint();
130 });
131 super.realRun();
132 }
133
134 @Override
135 protected void cancel() {
136 super.cancel();
137 asynchronousUploadPrimitivesTask = null;
138 }
139
140 @Override
141 protected void finish() {
142 try {
143 // Unlock the data layer in EDT
144 GuiHelper.runInEDTAndWait(() -> {
145 MainApplication.getLayerManager().processLayerAfterUpload(uploadDataLayer);
146 LayerListDialog.getInstance().repaint();
147 });
148 super.finish();
149 } finally {
150 asynchronousUploadPrimitivesTask = null;
151 }
152 }
153}
Note: See TracBrowser for help on using the repository browser.