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

Last change on this file since 10420 was 10212, checked in by Don-vip, 8 years ago

sonar - squid:S2221 - "Exception" should not be caught when not required by called methods

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