source: josm/trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java@ 13632

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

use OsmDataLayer.getDataSet() in download tasks

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.downloadtasks;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.io.IOException;
8import java.text.MessageFormat;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.Map;
13import java.util.Map.Entry;
14import java.util.Set;
15
16import javax.swing.JOptionPane;
17import javax.swing.SwingUtilities;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.data.osm.DataSet;
21import org.openstreetmap.josm.data.osm.DataSetMerger;
22import org.openstreetmap.josm.data.osm.Node;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
25import org.openstreetmap.josm.data.osm.PrimitiveId;
26import org.openstreetmap.josm.data.osm.Way;
27import org.openstreetmap.josm.gui.MainApplication;
28import org.openstreetmap.josm.gui.MapFrame;
29import org.openstreetmap.josm.gui.PleaseWaitRunnable;
30import org.openstreetmap.josm.gui.layer.OsmDataLayer;
31import org.openstreetmap.josm.gui.progress.ProgressMonitor;
32import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
33import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
34import org.openstreetmap.josm.io.OsmServerReader;
35import org.openstreetmap.josm.io.OsmTransferException;
36import org.openstreetmap.josm.tools.CheckParameterUtil;
37import org.openstreetmap.josm.tools.ExceptionUtil;
38import org.xml.sax.SAXException;
39
40/**
41 * The asynchronous task for downloading referring primitives
42 * @since 2923
43 */
44public class DownloadReferrersTask extends PleaseWaitRunnable {
45 private boolean canceled;
46 private Exception lastException;
47 private OsmServerReader reader;
48 /** the target layer */
49 private final OsmDataLayer targetLayer;
50 /** the collection of child primitives */
51 private final Map<Long, OsmPrimitiveType> children;
52 /** the parents */
53 private final DataSet parents;
54
55 /**
56 * constructor
57 *
58 * @param targetLayer the target layer for the downloaded primitives. Must not be null.
59 * @param children the collection of child primitives for which parents are to be downloaded
60 */
61 public DownloadReferrersTask(OsmDataLayer targetLayer, Collection<OsmPrimitive> children) {
62 super("Download referrers", false /* don't ignore exception*/);
63 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
64 if (!targetLayer.isDownloadable()) {
65 throw new IllegalArgumentException("Non-downloadable layer: " + targetLayer);
66 }
67 canceled = false;
68 this.children = new HashMap<>();
69 if (children != null) {
70 for (OsmPrimitive p: children) {
71 if (!p.isNew()) {
72 this.children.put(p.getId(), OsmPrimitiveType.from(p));
73 }
74 }
75 }
76 this.targetLayer = targetLayer;
77 parents = new DataSet();
78 }
79
80 /**
81 * constructor
82 *
83 * @param targetLayer the target layer. Must not be null.
84 * @param primitiveId a PrimitiveId object.
85 * @param progressMonitor ProgressMonitor to use or null to create a new one.
86 * @throws IllegalArgumentException if id &lt;= 0
87 * @throws IllegalArgumentException if targetLayer == null
88 */
89 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId,
90 ProgressMonitor progressMonitor) {
91 super("Download referrers", progressMonitor, false /* don't ignore exception*/);
92 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
93 if (primitiveId.isNew())
94 throw new IllegalArgumentException(MessageFormat.format(
95 "Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
96 canceled = false;
97 this.children = new HashMap<>();
98 this.children.put(primitiveId.getUniqueId(), primitiveId.getType());
99 this.targetLayer = targetLayer;
100 parents = new DataSet();
101 }
102
103 @Override
104 protected void cancel() {
105 canceled = true;
106 synchronized (this) {
107 if (reader != null) {
108 reader.cancel();
109 }
110 }
111 }
112
113 @Override
114 protected void finish() {
115 if (canceled)
116 return;
117 if (lastException != null) {
118 ExceptionUtil.explainException(lastException);
119 return;
120 }
121
122 DataSetMerger visitor = new DataSetMerger(targetLayer.getDataSet(), parents);
123 visitor.merge();
124 SwingUtilities.invokeLater(targetLayer::onPostDownloadFromServer);
125 if (visitor.getConflicts().isEmpty())
126 return;
127 targetLayer.getConflicts().add(visitor.getConflicts());
128 JOptionPane.showMessageDialog(
129 Main.parent,
130 trn("There was {0} conflict during import.",
131 "There were {0} conflicts during import.",
132 visitor.getConflicts().size(),
133 visitor.getConflicts().size()
134 ),
135 trn("Conflict during download", "Conflicts during download", visitor.getConflicts().size()),
136 JOptionPane.WARNING_MESSAGE
137 );
138 MapFrame map = MainApplication.getMap();
139 map.conflictDialog.unfurlDialog();
140 map.repaint();
141 }
142
143 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException {
144 reader = new OsmServerBackreferenceReader(id, type);
145 DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
146 synchronized (this) { // avoid race condition in cancel()
147 reader = null;
148 }
149 Collection<Way> ways = ds.getWays();
150
151 DataSetMerger merger;
152 if (!ways.isEmpty()) {
153 Set<Node> nodes = new HashSet<>();
154 for (Way w: ways) {
155 // Ensure each node is only listed once
156 nodes.addAll(w.getNodes());
157 }
158 // Don't retrieve any nodes we've already grabbed
159 nodes.removeAll(targetLayer.data.getNodes());
160 if (!nodes.isEmpty()) {
161 reader = MultiFetchServerObjectReader.create();
162 ((MultiFetchServerObjectReader) reader).append(nodes);
163 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
164 synchronized (this) { // avoid race condition in cancel()
165 reader = null;
166 }
167 merger = new DataSetMerger(ds, wayNodes);
168 merger.merge();
169 }
170 }
171 merger = new DataSetMerger(parents, ds);
172 merger.merge();
173 }
174
175 @Override
176 protected void realRun() throws SAXException, IOException, OsmTransferException {
177 try {
178 progressMonitor.setTicksCount(children.size());
179 int i = 1;
180 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
181 if (canceled)
182 return;
183 String msg;
184 switch(entry.getValue()) {
185 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1, children.size(), entry.getKey()); break;
186 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1, children.size(), entry.getKey()); break;
187 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1, children.size(), entry.getKey()); break;
188 default: throw new AssertionError();
189 }
190 progressMonitor.subTask(msg);
191 downloadParents(entry.getKey(), entry.getValue(), progressMonitor);
192 i++;
193 }
194 } catch (OsmTransferException e) {
195 if (canceled)
196 return;
197 lastException = e;
198 }
199 }
200}
Note: See TracBrowser for help on using the repository browser.