source: josm/trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java@ 12620

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

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

  • Property svn:eol-style set to native
File size: 6.2 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.util.Collection;
7import java.util.HashSet;
8import java.util.Optional;
9import java.util.Set;
10
11import org.openstreetmap.josm.actions.upload.CyclicUploadDependencyException;
12import org.openstreetmap.josm.data.APIDataSet;
13import org.openstreetmap.josm.data.osm.Changeset;
14import org.openstreetmap.josm.data.osm.IPrimitive;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
17import org.openstreetmap.josm.gui.DefaultNameFormatter;
18import org.openstreetmap.josm.gui.layer.OsmDataLayer;
19import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
20import org.openstreetmap.josm.gui.progress.ProgressMonitor;
21import org.openstreetmap.josm.io.OsmApi;
22import org.openstreetmap.josm.io.OsmApiPrimitiveGoneException;
23import org.openstreetmap.josm.io.OsmServerWriter;
24import org.openstreetmap.josm.io.OsmTransferException;
25import org.openstreetmap.josm.tools.CheckParameterUtil;
26import org.openstreetmap.josm.tools.Logging;
27
28/**
29 * UploadLayerTask uploads the data managed by an {@link OsmDataLayer} asynchronously.
30 *
31 * <pre>
32 * ExecutorService executorService = ...
33 * UploadLayerTask task = new UploadLayerTask(layer, monitor);
34 * Future&lt;?&gt; taskFuture = executorService.submit(task)
35 * try {
36 * // wait for the task to complete
37 * taskFuture.get();
38 * } catch (Exception e) {
39 * e.printStackTrace();
40 * }
41 * </pre>
42 */
43public class UploadLayerTask extends AbstractIOTask {
44 private OsmServerWriter writer;
45 private final OsmDataLayer layer;
46 private final ProgressMonitor monitor;
47 private final Changeset changeset;
48 private Collection<OsmPrimitive> toUpload;
49 private final Set<IPrimitive> processedPrimitives;
50 private final UploadStrategySpecification strategy;
51
52 /**
53 * Creates the upload task
54 *
55 * @param strategy the upload strategy specification
56 * @param layer the layer. Must not be null.
57 * @param monitor a progress monitor. If monitor is null, uses {@link NullProgressMonitor#INSTANCE}
58 * @param changeset the changeset to be used
59 * @throws IllegalArgumentException if layer is null
60 * @throws IllegalArgumentException if strategy is null
61 */
62 public UploadLayerTask(UploadStrategySpecification strategy, OsmDataLayer layer, ProgressMonitor monitor, Changeset changeset) {
63 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
64 CheckParameterUtil.ensureParameterNotNull(strategy, "strategy");
65 this.layer = layer;
66 this.monitor = Optional.ofNullable(monitor).orElse(NullProgressMonitor.INSTANCE);
67 this.changeset = changeset;
68 this.strategy = strategy;
69 processedPrimitives = new HashSet<>();
70 }
71
72 protected OsmPrimitive getPrimitive(OsmPrimitiveType type, long id) {
73 for (OsmPrimitive p: toUpload) {
74 if (OsmPrimitiveType.from(p).equals(type) && p.getId() == id)
75 return p;
76 }
77 return null;
78 }
79
80 /**
81 * Retries to recover the upload operation from an exception which was thrown because
82 * an uploaded primitive was already deleted on the server.
83 *
84 * @param e the exception throw by the API
85 * @throws OsmTransferException if we can't recover from the exception
86 */
87 protected void recoverFromGoneOnServer(OsmApiPrimitiveGoneException e) throws OsmTransferException {
88 if (!e.isKnownPrimitive()) throw e;
89 OsmPrimitive p = getPrimitive(e.getPrimitiveType(), e.getPrimitiveId());
90 if (p == null) throw e;
91 if (p.isDeleted()) {
92 // we tried to delete an already deleted primitive.
93 Logging.warn(tr("Object ''{0}'' is already deleted on the server. Skipping this object and retrying to upload.",
94 p.getDisplayName(DefaultNameFormatter.getInstance())));
95 processedPrimitives.addAll(writer.getProcessedPrimitives());
96 processedPrimitives.add(p);
97 toUpload.removeAll(processedPrimitives);
98 return;
99 }
100 // exception was thrown because we tried to *update* an already deleted primitive. We can't resolve this automatically.
101 // Re-throw exception, a conflict is going to be created later.
102 throw e;
103 }
104
105 @Override
106 public void run() {
107 monitor.indeterminateSubTask(tr("Preparing objects to upload ..."));
108 APIDataSet ds = new APIDataSet(layer.data);
109 try {
110 ds.adjustRelationUploadOrder();
111 } catch (CyclicUploadDependencyException e) {
112 setLastException(e);
113 return;
114 }
115 toUpload = ds.getPrimitives();
116 if (toUpload.isEmpty())
117 return;
118 writer = new OsmServerWriter();
119 try {
120 while (true) {
121 try {
122 ProgressMonitor m = monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
123 if (isCanceled()) return;
124 writer.uploadOsm(strategy, toUpload, changeset, m);
125 processedPrimitives.addAll(writer.getProcessedPrimitives()); // OsmPrimitive in => OsmPrimitive out
126 break;
127 } catch (OsmApiPrimitiveGoneException e) {
128 recoverFromGoneOnServer(e);
129 }
130 }
131 if (strategy.isCloseChangesetAfterUpload() && changeset != null && changeset.getId() > 0) {
132 OsmApi.getOsmApi().closeChangeset(changeset, monitor.createSubTaskMonitor(0, false));
133 }
134 } catch (OsmTransferException sxe) {
135 if (isCanceled()) {
136 Logging.info("Ignoring exception caught because upload is canceled. Exception is: " + sxe);
137 return;
138 }
139 setLastException(sxe);
140 }
141
142 if (isCanceled())
143 return;
144 layer.cleanupAfterUpload(processedPrimitives);
145 layer.onPostUploadToServer();
146
147 // don't process exceptions remembered with setLastException().
148 // Caller is supposed to deal with them.
149 }
150
151 @Override
152 public void cancel() {
153 setCanceled(true);
154 if (writer != null) {
155 writer.cancel();
156 }
157 }
158}
Note: See TracBrowser for help on using the repository browser.