source: josm/trunk/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java@ 2599

Last change on this file since 2599 was 2599, checked in by Gubaer, 14 years ago

fixed #4130: Chunked upload mode counter is wrong
fixed #4118: Upload dialog too complicated
fixed #4129: Hide the new "Upload data in one request/chunks/individually" behind an expanding "Upload method" box
fixed #2075: API 0.6: don't upload more than 50K edits at once
fixed #4044: Huge uploads never end [should be solved with chunked upload mode]
fixed #4110: Upload dialog spacing wrong
fixed #3386: Upload dialog has empty areas when the changeset doesn't include all of add/modify/delete operations
see #3369: bulk import helper [JOSM now supports multi changesets uploads]

See online help for more details.

Completes r2598

File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.io.IOException;
8import java.lang.reflect.InvocationTargetException;
9import java.util.Collection;
10import java.util.Collections;
11import java.util.logging.Logger;
12
13import javax.swing.SwingUtilities;
14
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.DataSetMerger;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
20import org.openstreetmap.josm.data.osm.Relation;
21import org.openstreetmap.josm.data.osm.Way;
22import org.openstreetmap.josm.gui.ExceptionDialogUtil;
23import org.openstreetmap.josm.gui.PleaseWaitRunnable;
24import org.openstreetmap.josm.gui.layer.OsmDataLayer;
25import org.openstreetmap.josm.gui.progress.ProgressMonitor;
26import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
27import org.openstreetmap.josm.io.OsmServerObjectReader;
28import org.openstreetmap.josm.io.OsmTransferException;
29import org.xml.sax.SAXException;
30
31/**
32 * The asynchronous task for updating a collection of objects using multi fetch.
33 *
34 */
35public class UpdatePrimitivesTask extends PleaseWaitRunnable {
36 static private final Logger logger = Logger.getLogger(UpdatePrimitivesTask.class.getName());
37
38 private DataSet ds;
39 private boolean canceled;
40 private Exception lastException;
41 private Collection<? extends OsmPrimitive> toUpdate;
42 private OsmDataLayer layer;
43 private MultiFetchServerObjectReader multiObjectReader;
44 private OsmServerObjectReader objectReader;
45
46 /**
47 * Creates the task
48 *
49 * @param layer the layer in which primitives are updated. Must not be null.
50 * @param toUpdate a collection of primitives to update from the server. Set to
51 * the empty collection if null.
52 * @throws IllegalArgumentException thrown if layer is null.
53 */
54 public UpdatePrimitivesTask(OsmDataLayer layer, Collection<? extends OsmPrimitive> toUpdate) throws IllegalArgumentException{
55 super(tr("Update objects"), false /* don't ignore exception */);
56 ensureParameterNotNull(layer, "layer");
57 if (toUpdate == null) {
58 toUpdate = Collections.emptyList();
59 }
60 this.layer = layer;
61 this.toUpdate = toUpdate;
62 }
63
64 @Override
65 protected void cancel() {
66 canceled = true;
67 synchronized(this) {
68 if (multiObjectReader != null) {
69 multiObjectReader.cancel();
70 }
71 if (objectReader != null) {
72 objectReader.cancel();
73 }
74 }
75 }
76
77 @Override
78 protected void finish() {
79 if (canceled)
80 return;
81 if (lastException != null) {
82 ExceptionDialogUtil.explainException(lastException);
83 return;
84 }
85 Runnable r = new Runnable() {
86 public void run() {
87 layer.mergeFrom(ds);
88 layer.onPostDownloadFromServer();
89 }
90 };
91
92 if (SwingUtilities.isEventDispatchThread()) {
93 r.run();
94 } else {
95 try {
96 SwingUtilities.invokeAndWait(r);
97 } catch(InterruptedException e) {
98 e.printStackTrace();
99 } catch(InvocationTargetException e) {
100 e.printStackTrace();
101 }
102 }
103 }
104
105 protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) {
106 getProgressMonitor().indeterminateSubTask(tr("Initializing nodes to update ..."));
107 for (OsmPrimitive primitive : toUpdate) {
108 if (primitive instanceof Node && !primitive.isNew()) {
109 reader.append((Node)primitive);
110 } else if (primitive instanceof Way) {
111 Way way = (Way)primitive;
112 for (Node node: way.getNodes()) {
113 if (!node.isNew()) {
114 reader.append(node);
115 }
116 }
117 }
118 }
119 }
120
121 protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) {
122 getProgressMonitor().indeterminateSubTask(tr("Initializing ways to update ..."));
123 for (OsmPrimitive primitive : toUpdate) {
124 if (primitive instanceof Way && !primitive.isNew()) {
125 reader.append((Way)primitive);
126 }
127 }
128 }
129
130 protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) {
131 getProgressMonitor().indeterminateSubTask(tr("Initializing relations to update ..."));
132 for (OsmPrimitive primitive : toUpdate) {
133 if (primitive instanceof Relation && !primitive.isNew()) {
134 reader.append((Relation)primitive);
135 }
136 }
137 }
138
139 @Override
140 protected void realRun() throws SAXException, IOException, OsmTransferException {
141 this.ds = new DataSet();
142 DataSet theirDataSet;
143 try {
144 synchronized(this) {
145 if (canceled) return;
146 multiObjectReader = new MultiFetchServerObjectReader();
147 }
148 initMultiFetchReaderWithNodes(multiObjectReader);
149 initMultiFetchReaderWithWays(multiObjectReader);
150 initMultiFetchReaderWithRelations(multiObjectReader);
151 theirDataSet = multiObjectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
152 synchronized(this) {
153 multiObjectReader = null;
154 }
155 DataSetMerger merger = new DataSetMerger(ds, theirDataSet);
156 merger.merge();
157 // a way loaded with MultiFetch may be incomplete because at least one of its
158 // nodes isn't present in the local data set. We therefore fully load all
159 // incomplete ways.
160 //
161 for (Way w : ds.getWays()) {
162 if (canceled) return;
163 if (w.isIncomplete()) {
164 synchronized(this) {
165 if (canceled) return;
166 objectReader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */);
167 }
168 theirDataSet = objectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
169 synchronized (this) {
170 objectReader = null;
171 }
172 merger = new DataSetMerger(ds, theirDataSet);
173 merger.merge();
174 }
175 }
176 } catch(Exception e) {
177 if (canceled)
178 return;
179 lastException = e;
180 }
181 }
182}
Note: See TracBrowser for help on using the repository browser.