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

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

checkstyle: enable relevant whitespace checks and fix them

  • Property svn:eol-style set to native
File size: 10.0 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 OsmDataLayer targetLayer;
48 /** the collection of child primitives */
49 private Map<Long, OsmPrimitiveType> children;
50 /** the parents */
51 private 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 for the downloaded primitives. Must not be null.
79 * @param children the collection of children for which parents are to be downloaded. Children
80 * are specified by their id and their type.
81 */
82 public DownloadReferrersTask(OsmDataLayer targetLayer, Map<Long, OsmPrimitiveType> children) {
83 super("Download referrers", false /* don't ignore exception*/);
84 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
85 canceled = false;
86 this.children = new HashMap<>();
87 if (children != null) {
88 for (Entry<Long, OsmPrimitiveType> entry : children.entrySet()) {
89 if (entry.getKey() > 0 && entry.getValue() != null) {
90 children.put(entry.getKey(), entry.getValue());
91 }
92 }
93 }
94 this.targetLayer = targetLayer;
95 parents = new DataSet();
96 }
97
98 /**
99 * constructor
100 *
101 * @param targetLayer the target layer. Must not be null.
102 * @param id the primitive id. id &gt; 0 required.
103 * @param type the primitive type. type != null required
104 * @throws IllegalArgumentException if id &lt;= 0
105 * @throws IllegalArgumentException if type == null
106 * @throws IllegalArgumentException if targetLayer == null
107 */
108 public DownloadReferrersTask(OsmDataLayer targetLayer, long id, OsmPrimitiveType type) {
109 super("Download referrers", false /* don't ignore exception*/);
110 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
111 if (id <= 0)
112 throw new IllegalArgumentException(MessageFormat.format("Id > 0 required, got {0}", id));
113 CheckParameterUtil.ensureParameterNotNull(type, "type");
114 canceled = false;
115 this.children = new HashMap<>();
116 this.children.put(id, type);
117 this.targetLayer = targetLayer;
118 parents = new DataSet();
119 }
120
121 /**
122 * constructor
123 *
124 * @param targetLayer the target layer. Must not be null.
125 * @param primitiveId a PrimitiveId object.
126 * @throws IllegalArgumentException if id &lt;= 0
127 * @throws IllegalArgumentException if targetLayer == null
128 */
129 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId) {
130 this(targetLayer, primitiveId, null);
131 }
132
133 /**
134 * constructor
135 *
136 * @param targetLayer the target layer. Must not be null.
137 * @param primitiveId a PrimitiveId object.
138 * @param progressMonitor ProgressMonitor to use or null to create a new one.
139 * @throws IllegalArgumentException if id &lt;= 0
140 * @throws IllegalArgumentException if targetLayer == null
141 */
142 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId,
143 ProgressMonitor progressMonitor) {
144 super("Download referrers", progressMonitor, false /* don't ignore exception*/);
145 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
146 if (primitiveId.isNew())
147 throw new IllegalArgumentException(MessageFormat.format(
148 "Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
149 canceled = false;
150 this.children = new HashMap<>();
151 this.children.put(primitiveId.getUniqueId(), primitiveId.getType());
152 this.targetLayer = targetLayer;
153 parents = new DataSet();
154 }
155
156 @Override
157 protected void cancel() {
158 canceled = true;
159 synchronized (this) {
160 if (reader != null) {
161 reader.cancel();
162 }
163 }
164 }
165
166 @Override
167 protected void finish() {
168 if (canceled)
169 return;
170 if (lastException != null) {
171 ExceptionUtil.explainException(lastException);
172 return;
173 }
174
175 DataSetMerger visitor = new DataSetMerger(targetLayer.data, parents);
176 visitor.merge();
177 SwingUtilities.invokeLater(
178 new Runnable() {
179 @Override
180 public void run() {
181 targetLayer.onPostDownloadFromServer();
182 if (Main.map != null)
183 Main.map.mapView.repaint();
184 }
185 }
186 );
187 if (visitor.getConflicts().isEmpty())
188 return;
189 targetLayer.getConflicts().add(visitor.getConflicts());
190 JOptionPane.showMessageDialog(
191 Main.parent,
192 trn("There was {0} conflict during import.",
193 "There were {0} conflicts during import.",
194 visitor.getConflicts().size(),
195 visitor.getConflicts().size()
196 ),
197 trn("Conflict during download", "Conflicts during download", visitor.getConflicts().size()),
198 JOptionPane.WARNING_MESSAGE
199 );
200 Main.map.conflictDialog.unfurlDialog();
201 Main.map.repaint();
202 }
203
204 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException {
205 reader = new OsmServerBackreferenceReader(id, type);
206 DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
207 synchronized (this) { // avoid race condition in cancel()
208 reader = null;
209 }
210 Collection<Way> ways = ds.getWays();
211
212 DataSetMerger merger;
213 if (!ways.isEmpty()) {
214 Set<Node> nodes = new HashSet<>();
215 for (Way w: ways) {
216 // Ensure each node is only listed once
217 nodes.addAll(w.getNodes());
218 }
219 // Don't retrieve any nodes we've already grabbed
220 nodes.removeAll(targetLayer.data.getNodes());
221 if (!nodes.isEmpty()) {
222 reader = new MultiFetchServerObjectReader();
223 ((MultiFetchServerObjectReader) reader).append(nodes);
224 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
225 synchronized (this) { // avoid race condition in cancel()
226 reader = null;
227 }
228 merger = new DataSetMerger(ds, wayNodes);
229 merger.merge();
230 }
231 }
232 merger = new DataSetMerger(parents, ds);
233 merger.merge();
234 }
235
236 @Override
237 protected void realRun() throws SAXException, IOException, OsmTransferException {
238 try {
239 progressMonitor.setTicksCount(children.size());
240 int i = 1;
241 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
242 if (canceled)
243 return;
244 String msg = "";
245 switch(entry.getValue()) {
246 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1, children.size(), entry.getKey()); break;
247 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1, children.size(), entry.getKey()); break;
248 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1, children.size(), entry.getKey()); break;
249 }
250 progressMonitor.subTask(msg);
251 downloadParents(entry.getKey(), entry.getValue(), progressMonitor);
252 i++;
253 }
254 } catch (Exception e) {
255 if (canceled)
256 return;
257 lastException = e;
258 }
259 }
260}
Note: See TracBrowser for help on using the repository browser.