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

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

see #8465 - use diamond operator where applicable

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