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

Last change on this file since 6084 was 6084, checked in by bastiK, 11 years ago

see #8902 - add missing @Override annotations (patch by shinigami)

  • Property svn:eol-style set to native
File size: 9.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.Set;
11import java.util.HashSet;
12import java.util.HashMap;
13import java.util.Map;
14import java.util.Map.Entry;
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<Long, OsmPrimitiveType>();
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<Long, OsmPrimitiveType>();
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 > 0 required.
104 * @param type the primitive type. type != null required
105 * @exception IllegalArgumentException thrown if id <= 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<Long, OsmPrimitiveType>();
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 <= 0
129 * @exception IllegalArgumentException thrown if targetLayer == null
130 *
131 */
132 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId) throws IllegalArgumentException {
133 super("Download referrers", false /* don't ignore exception*/);
134 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
135 if (primitiveId.isNew())
136 throw new IllegalArgumentException(MessageFormat.format("Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
137 canceled = false;
138 this.children = new HashMap<Long, OsmPrimitiveType>();
139 this.children.put(primitiveId.getUniqueId(), primitiveId.getType());
140 this.targetLayer = targetLayer;
141 parents = new DataSet();
142 }
143
144 @Override
145 protected void cancel() {
146 canceled = true;
147 synchronized(this) {
148 if (reader != null) {
149 reader.cancel();
150 }
151 }
152 }
153
154 @Override
155 protected void finish() {
156 if (canceled)
157 return;
158 if (lastException != null) {
159 ExceptionUtil.explainException(lastException);
160 return;
161 }
162
163 DataSetMerger visitor = new DataSetMerger(targetLayer.data, parents);
164 visitor.merge();
165 SwingUtilities.invokeLater(
166 new Runnable() {
167 @Override
168 public void run() {
169 targetLayer.onPostDownloadFromServer();
170 Main.map.mapView.repaint();
171 }
172 }
173 );
174 if (visitor.getConflicts().isEmpty())
175 return;
176 targetLayer.getConflicts().add(visitor.getConflicts());
177 JOptionPane.showMessageDialog(
178 Main.parent,
179 trn("There was {0} conflict during import.",
180 "There were {0} conflicts during import.",
181 visitor.getConflicts().size(),
182 visitor.getConflicts().size()
183 ),
184 trn("Conflict during download", "Conflicts during download", visitor.getConflicts().size()),
185 JOptionPane.WARNING_MESSAGE
186 );
187 Main.map.conflictDialog.unfurlDialog();
188 Main.map.repaint();
189 }
190
191 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException{
192 reader = new OsmServerBackreferenceReader(id, type);
193 DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
194 synchronized(this) { // avoid race condition in cancel()
195 reader = null;
196 }
197 Collection<Way> ways = ds.getWays();
198
199 DataSetMerger merger;
200 if (!ways.isEmpty()) {
201 Set<Node> nodes = new HashSet<Node>();
202 for (Way w: ways) {
203 // Ensure each node is only listed once
204 nodes.addAll(w.getNodes());
205 }
206 // Don't retrieve any nodes we've already grabbed
207 nodes.removeAll(targetLayer.data.getNodes());
208 if (!nodes.isEmpty()) {
209 reader = new MultiFetchServerObjectReader();
210 ((MultiFetchServerObjectReader)reader).append(nodes);
211 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
212 synchronized(this) { // avoid race condition in cancel()
213 reader = null;
214 }
215 merger = new DataSetMerger(ds, wayNodes);
216 merger.merge();
217 }
218 }
219 merger = new DataSetMerger(parents, ds);
220 merger.merge();
221 }
222
223 @Override
224 protected void realRun() throws SAXException, IOException, OsmTransferException {
225 try {
226 progressMonitor.setTicksCount(children.size());
227 int i=1;
228 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
229 if (canceled)
230 return;
231 String msg = "";
232 switch(entry.getValue()) {
233 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1,children.size(), entry.getKey()); break;
234 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1,children.size(), entry.getKey()); break;
235 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1,children.size(), entry.getKey()); break;
236 }
237 progressMonitor.subTask(msg);
238 downloadParents(entry.getKey(), entry.getValue(), progressMonitor);
239 i++;
240 }
241 } catch(Exception e) {
242 if (canceled)
243 return;
244 lastException = e;
245 }
246 }
247}
Note: See TracBrowser for help on using the repository browser.