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

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

fix #13037 - Small fixes for unit tests (patch by michael2402) - gsoc-core

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