source: josm/trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java@ 4081

Last change on this file since 4081 was 4081, checked in by bastiK, 13 years ago

applied #6251 (patch by akks) - Download multiple objects on Ctrl-Shift-O

  • 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.CheckParameterUtil.ensureParameterNotNull;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.io.IOException;
8import java.lang.reflect.InvocationTargetException;
9import java.util.List;
10import java.util.Set;
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.PrimitiveId;
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
31public class DownloadPrimitivesTask extends PleaseWaitRunnable {
32 @SuppressWarnings("unused")
33 static private final Logger logger = Logger.getLogger(UpdatePrimitivesTask.class.getName());
34
35 private DataSet ds;
36 private boolean canceled;
37 private Exception lastException;
38 private List<PrimitiveId> ids;
39
40 private Set<PrimitiveId> missingPrimitives;
41
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 DownloadPrimitivesTask(OsmDataLayer layer, List<PrimitiveId> ids) throws IllegalArgumentException {
55 super(tr("Download objects"), false /* don't ignore exception */);
56 ensureParameterNotNull(layer, "layer");
57 this.ids = ids;
58 this.layer = layer;
59 }
60
61 @Override
62 protected void cancel() {
63 canceled = true;
64 synchronized(this) {
65 if (multiObjectReader != null) {
66 multiObjectReader.cancel();
67 }
68 if (objectReader != null) {
69 objectReader.cancel();
70 }
71 }
72 }
73
74 @Override
75 protected void finish() {
76 if (canceled)
77 return;
78 if (lastException != null) {
79 ExceptionDialogUtil.explainException(lastException);
80 return;
81 }
82 Runnable r = new Runnable() {
83 public void run() {
84 layer.mergeFrom(ds);
85 layer.onPostDownloadFromServer();
86 }
87 };
88
89 if (SwingUtilities.isEventDispatchThread()) {
90 r.run();
91 } else {
92 try {
93 SwingUtilities.invokeAndWait(r);
94 } catch(InterruptedException e) {
95 e.printStackTrace();
96 } catch(InvocationTargetException e) {
97 e.printStackTrace();
98 }
99 }
100 }
101
102 protected void initMultiFetchReader(MultiFetchServerObjectReader reader) {
103 getProgressMonitor().indeterminateSubTask(tr("Initializing nodes to download ..."));
104 for (PrimitiveId id : ids) {
105 OsmPrimitive osm = layer.data.getPrimitiveById(id);
106 if (osm == null) {
107 switch (id.getType()) {
108 case NODE:
109 osm = new Node(id.getUniqueId());
110 break;
111 case WAY:
112 osm = new Node(id.getUniqueId());
113 break;
114 case RELATION:
115 osm = new Node(id.getUniqueId());
116 break;
117 default: throw new AssertionError();
118 }
119 }
120 reader.append(osm);
121 }
122 }
123
124 @Override
125 protected void realRun() throws SAXException, IOException, OsmTransferException {
126 this.ds = new DataSet();
127 DataSet theirDataSet;
128 try {
129 synchronized(this) {
130 if (canceled) return;
131 multiObjectReader = new MultiFetchServerObjectReader();
132 }
133 initMultiFetchReader(multiObjectReader);
134 theirDataSet = multiObjectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
135 missingPrimitives = multiObjectReader.getMissingPrimitives();
136 synchronized(this) {
137 multiObjectReader = null;
138 }
139 DataSetMerger merger = new DataSetMerger(ds, theirDataSet);
140 merger.merge();
141 // a way loaded with MultiFetch may have incomplete nodes because at least one of its
142 // nodes isn't present in the local data set. We therefore fully load all
143 // ways with incomplete nodes.
144 //
145 for (Way w : ds.getWays()) {
146 if (canceled) return;
147 if (w.hasIncompleteNodes()) {
148 synchronized(this) {
149 if (canceled) return;
150 objectReader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */);
151 }
152 theirDataSet = objectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
153 synchronized (this) {
154 objectReader = null;
155 }
156 merger = new DataSetMerger(ds, theirDataSet);
157 merger.merge();
158 }
159 }
160
161 } catch(Exception e) {
162 if (canceled) return;
163 lastException = e;
164 }
165 }
166
167 /**
168 * replies the set of ids of all primitives for which a fetch request to the
169 * server was submitted but which are not available from the server (the server
170 * replied a return code of 404)
171 *
172 * @return the set of ids of missing primitives
173 */
174 public Set<PrimitiveId> getMissingPrimitives() {
175 return missingPrimitives;
176 }
177
178}
Note: See TracBrowser for help on using the repository browser.