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

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

see #15182 - deprecate Main.map and Main.isDisplayingMapView(). Replacements: gui.MainApplication.getMap() / gui.MainApplication.isDisplayingMapView()

  • Property svn:eol-style set to native
File size: 7.6 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 canceled = false;
65 this.children = new HashMap<>();
66 if (children != null) {
67 for (OsmPrimitive p: children) {
68 if (!p.isNew()) {
69 this.children.put(p.getId(), OsmPrimitiveType.from(p));
70 }
71 }
72 }
73 this.targetLayer = targetLayer;
74 parents = new DataSet();
75 }
76
77 /**
78 * constructor
79 *
80 * @param targetLayer the target layer. Must not be null.
81 * @param primitiveId a PrimitiveId object.
82 * @param progressMonitor ProgressMonitor to use or null to create a new one.
83 * @throws IllegalArgumentException if id &lt;= 0
84 * @throws IllegalArgumentException if targetLayer == null
85 */
86 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId,
87 ProgressMonitor progressMonitor) {
88 super("Download referrers", progressMonitor, false /* don't ignore exception*/);
89 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
90 if (primitiveId.isNew())
91 throw new IllegalArgumentException(MessageFormat.format(
92 "Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
93 canceled = false;
94 this.children = new HashMap<>();
95 this.children.put(primitiveId.getUniqueId(), primitiveId.getType());
96 this.targetLayer = targetLayer;
97 parents = new DataSet();
98 }
99
100 @Override
101 protected void cancel() {
102 canceled = true;
103 synchronized (this) {
104 if (reader != null) {
105 reader.cancel();
106 }
107 }
108 }
109
110 @Override
111 protected void finish() {
112 if (canceled)
113 return;
114 if (lastException != null) {
115 ExceptionUtil.explainException(lastException);
116 return;
117 }
118
119 DataSetMerger visitor = new DataSetMerger(targetLayer.data, parents);
120 visitor.merge();
121 SwingUtilities.invokeLater(targetLayer::onPostDownloadFromServer);
122 if (visitor.getConflicts().isEmpty())
123 return;
124 targetLayer.getConflicts().add(visitor.getConflicts());
125 JOptionPane.showMessageDialog(
126 Main.parent,
127 trn("There was {0} conflict during import.",
128 "There were {0} conflicts during import.",
129 visitor.getConflicts().size(),
130 visitor.getConflicts().size()
131 ),
132 trn("Conflict during download", "Conflicts during download", visitor.getConflicts().size()),
133 JOptionPane.WARNING_MESSAGE
134 );
135 MapFrame map = MainApplication.getMap();
136 map.conflictDialog.unfurlDialog();
137 map.repaint();
138 }
139
140 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException {
141 reader = new OsmServerBackreferenceReader(id, type);
142 DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
143 synchronized (this) { // avoid race condition in cancel()
144 reader = null;
145 }
146 Collection<Way> ways = ds.getWays();
147
148 DataSetMerger merger;
149 if (!ways.isEmpty()) {
150 Set<Node> nodes = new HashSet<>();
151 for (Way w: ways) {
152 // Ensure each node is only listed once
153 nodes.addAll(w.getNodes());
154 }
155 // Don't retrieve any nodes we've already grabbed
156 nodes.removeAll(targetLayer.data.getNodes());
157 if (!nodes.isEmpty()) {
158 reader = MultiFetchServerObjectReader.create();
159 ((MultiFetchServerObjectReader) reader).append(nodes);
160 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
161 synchronized (this) { // avoid race condition in cancel()
162 reader = null;
163 }
164 merger = new DataSetMerger(ds, wayNodes);
165 merger.merge();
166 }
167 }
168 merger = new DataSetMerger(parents, ds);
169 merger.merge();
170 }
171
172 @Override
173 protected void realRun() throws SAXException, IOException, OsmTransferException {
174 try {
175 progressMonitor.setTicksCount(children.size());
176 int i = 1;
177 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
178 if (canceled)
179 return;
180 String msg;
181 switch(entry.getValue()) {
182 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1, children.size(), entry.getKey()); break;
183 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1, children.size(), entry.getKey()); break;
184 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1, children.size(), entry.getKey()); break;
185 default: throw new AssertionError();
186 }
187 progressMonitor.subTask(msg);
188 downloadParents(entry.getKey(), entry.getValue(), progressMonitor);
189 i++;
190 }
191 } catch (OsmTransferException e) {
192 if (canceled)
193 return;
194 lastException = e;
195 }
196 }
197}
Note: See TracBrowser for help on using the repository browser.