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

Last change on this file since 2950 was 2950, checked in by mjulius, 14 years ago

when downloading referrers also download way nodes for referring ways
see #4467

File size: 9.4 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.Map;
12import java.util.Map.Entry;
13
14import javax.swing.JOptionPane;
15import javax.swing.SwingUtilities;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.data.osm.DataSet;
19import org.openstreetmap.josm.data.osm.DataSetMerger;
20import org.openstreetmap.josm.data.osm.OsmPrimitive;
21import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
22import org.openstreetmap.josm.data.osm.PrimitiveId;
23import org.openstreetmap.josm.data.osm.Way;
24import org.openstreetmap.josm.gui.PleaseWaitRunnable;
25import org.openstreetmap.josm.gui.layer.OsmDataLayer;
26import org.openstreetmap.josm.gui.progress.ProgressMonitor;
27import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
28import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
29import org.openstreetmap.josm.io.OsmServerReader;
30import org.openstreetmap.josm.io.OsmTransferException;
31import org.openstreetmap.josm.tools.CheckParameterUtil;
32import org.openstreetmap.josm.tools.ExceptionUtil;
33import org.xml.sax.SAXException;
34
35/**
36 * The asynchronous task for downloading referring primitives
37 *
38 */
39public class DownloadReferrersTask extends PleaseWaitRunnable {
40 private boolean cancelled;
41 private Exception lastException;
42 private OsmServerReader reader;
43 /** the target layer */
44 private OsmDataLayer targetLayer;
45 /** the collection of child primitives */
46 private Map<Long, OsmPrimitiveType> children;
47 /** the parents */
48 private DataSet parents;
49
50 /**
51 * constructor
52 *
53 * @param targetLayer the target layer for the downloaded primitives. Must not be null.
54 * @param children the collection of child primitives for which parents are to be downloaded
55 *
56 */
57 public DownloadReferrersTask(OsmDataLayer targetLayer, Collection<OsmPrimitive> children) {
58 super("Download referrers", false /* don't ignore exception*/);
59 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
60 cancelled = false;
61 this.children = new HashMap<Long, OsmPrimitiveType>();
62 if (children != null) {
63 for (OsmPrimitive p: children) {
64 if (! p.isNew()) {
65 this.children.put(p.getId(), OsmPrimitiveType.from(p));
66 }
67 }
68 }
69 this.targetLayer = targetLayer;
70 parents = new DataSet();
71 }
72
73 /**
74 * constructor
75 *
76 * @param targetLayer the target layer for the downloaded primitives. Must not be null.
77 * @param primitives the collection of children for which parents are to be downloaded. Children
78 * are specified by their id and their type.
79 *
80 */
81 public DownloadReferrersTask(OsmDataLayer targetLayer, Map<Long, OsmPrimitiveType> children) {
82 super("Download referrers", false /* don't ignore exception*/);
83 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
84 cancelled = false;
85 this.children = new HashMap<Long, OsmPrimitiveType>();
86 if (children != null) {
87 for (Entry<Long, OsmPrimitiveType> entry : children.entrySet()) {
88 if (entry.getKey() > 0 && entry.getValue() != null) {
89 children.put(entry.getKey(), entry.getValue());
90 }
91 }
92 }
93 this.targetLayer = targetLayer;
94 parents = new DataSet();
95 }
96
97 /**
98 * constructor
99 *
100 * @param targetLayer the target layer. Must not be null.
101 * @param id the primitive id. id > 0 required.
102 * @param type the primitive type. type != null required
103 * @exception IllegalArgumentException thrown if id <= 0
104 * @exception IllegalArgumentException thrown if type == null
105 * @exception IllegalArgumentException thrown if targetLayer == null
106 *
107 */
108 public DownloadReferrersTask(OsmDataLayer targetLayer, long id, OsmPrimitiveType type) throws IllegalArgumentException {
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 cancelled = false;
115 this.children = new HashMap<Long, OsmPrimitiveType>();
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 * @exception IllegalArgumentException thrown if id <= 0
127 * @exception IllegalArgumentException thrown if targetLayer == null
128 *
129 */
130 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId) throws IllegalArgumentException {
131 super("Download referrers", false /* don't ignore exception*/);
132 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
133 if (primitiveId.isNew())
134 throw new IllegalArgumentException(MessageFormat.format("Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
135 cancelled = false;
136 this.children = new HashMap<Long, OsmPrimitiveType>();
137 this.children.put(primitiveId.getUniqueId(), primitiveId.getType());
138 this.targetLayer = targetLayer;
139 parents = new DataSet();
140 }
141
142 @Override
143 protected void cancel() {
144 cancelled = true;
145 synchronized(this) {
146 if (reader != null) {
147 reader.cancel();
148 }
149 }
150 }
151
152 @Override
153 protected void finish() {
154 if (cancelled)
155 return;
156 if (lastException != null) {
157 ExceptionUtil.explainException(lastException);
158 return;
159 }
160
161 DataSetMerger visitor = new DataSetMerger(targetLayer.data, parents);
162 visitor.merge();
163 SwingUtilities.invokeLater(
164 new Runnable() {
165 public void run() {
166 targetLayer.fireDataChange();
167 targetLayer.onPostDownloadFromServer();
168 Main.map.mapView.repaint();
169 }
170 }
171 );
172 if (visitor.getConflicts().isEmpty())
173 return;
174 targetLayer.getConflicts().add(visitor.getConflicts());
175 JOptionPane.showMessageDialog(
176 Main.parent,
177 trn("There was {0} conflict during import.",
178 "There were {0} conflicts during import.",
179 visitor.getConflicts().size(),
180 visitor.getConflicts().size()
181 ),
182 trn("Conflict during download", "Conflicts during download", visitor.getConflicts().size()),
183 JOptionPane.WARNING_MESSAGE
184 );
185 }
186
187 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException{
188 reader = new OsmServerBackreferenceReader(id, type);
189 DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
190 synchronized(this) { // avoid race condition in cancel()
191 reader = null;
192 }
193 Collection<Way> ways = ds.getWays();
194 DataSetMerger merger;
195 if (!ways.isEmpty()) {
196 reader = new MultiFetchServerObjectReader();
197 for (Way w: ways) {
198 ((MultiFetchServerObjectReader)reader).append(w.getNodes());
199 }
200 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
201 synchronized(this) { // avoid race condition in cancel()
202 reader = null;
203 }
204 merger = new DataSetMerger(ds, wayNodes);
205 merger.merge();
206 }
207 merger = new DataSetMerger(parents, ds);
208 merger.merge();
209 }
210
211 @Override
212 protected void realRun() throws SAXException, IOException, OsmTransferException {
213 try {
214 progressMonitor.setTicksCount(children.size());
215 int i=1;
216 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
217 if (cancelled)
218 return;
219 String msg = "";
220 switch(entry.getValue()) {
221 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1,children.size(), entry.getKey()); break;
222 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1,children.size(), entry.getKey()); break;
223 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1,children.size(), entry.getKey()); break;
224 }
225 progressMonitor.subTask(msg);
226 downloadParents(entry.getKey(), entry.getValue(), progressMonitor);
227 i++;
228 }
229 } catch(Exception e) {
230 if (cancelled)
231 return;
232 lastException = e;
233 }
234 }
235}
Note: See TracBrowser for help on using the repository browser.