source: josm/trunk/src/org/openstreetmap/josm/actions/DownloadReferrersAction.java@ 2323

Last change on this file since 2323 was 2323, checked in by Gubaer, 15 years ago

Added explicit help topics
See also current list of help topics with links to source files and to help pages

File size: 12.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.io.IOException;
10import java.util.Collection;
11import java.util.HashMap;
12import java.util.Map;
13import java.util.Map.Entry;
14
15import javax.swing.JOptionPane;
16import javax.swing.SwingUtilities;
17
18import org.openstreetmap.josm.Main;
19import org.openstreetmap.josm.data.osm.DataSet;
20import org.openstreetmap.josm.data.osm.OsmPrimitive;
21import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
22import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
23import org.openstreetmap.josm.gui.PleaseWaitRunnable;
24import org.openstreetmap.josm.gui.layer.OsmDataLayer;
25import org.openstreetmap.josm.gui.progress.ProgressMonitor;
26import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
27import org.openstreetmap.josm.io.OsmTransferException;
28import org.openstreetmap.josm.tools.ExceptionUtil;
29import org.openstreetmap.josm.tools.Shortcut;
30import org.xml.sax.SAXException;
31
32/**
33 * This action loads the set of primitives referring to the current selection from the OSM
34 * server.
35 *
36 */
37public class DownloadReferrersAction extends JosmAction{
38
39 public DownloadReferrersAction() {
40 super(tr("Download parent ways/relations..."), "downloadreferrers", tr("Download primitives referring to one of the selected primitives"),
41 Shortcut.registerShortcut("file:downloadreferrers", tr("File: {0}", tr("Download parent ways/relations...")), KeyEvent.VK_D, Shortcut.GROUPS_ALT2+Shortcut.GROUP_HOTKEY), true);
42 putValue("help", ht("/Action/Downloadreferrers"));
43 }
44
45 /**
46 * Downloads the primitives referring to the primitives in <code>primitives</code>
47 * into the target layer <code>targetLayer</code>.
48 * Does nothing if primitives is null or empty.
49 *
50 * @param targetLayer the target layer. Must not be null.
51 * @param children the collection of child primitives.
52 * @exception IllegalArgumentException thrown if targetLayer is null
53 */
54 static public void downloadReferrers(OsmDataLayer targetLayer, Collection<OsmPrimitive> children) throws IllegalArgumentException {
55 if (children == null || children.isEmpty()) return;
56 Main.worker.submit(new DownloadReferrersTask(targetLayer, children));
57 }
58
59 /**
60 * Downloads the primitives referring to the primitives in <code>primitives</code>
61 * into the target layer <code>targetLayer</code>.
62 * Does nothing if primitives is null or empty.
63 *
64 * @param targetLayer the target layer. Must not be null.
65 * @param children the collection of primitives, given as map of ids and types
66 * @exception IllegalArgumentException thrown if targetLayer is null
67 */
68 static public void downloadReferrers(OsmDataLayer targetLayer, Map<Long, OsmPrimitiveType> children) throws IllegalArgumentException {
69 if (children == null || children.isEmpty()) return;
70 Main.worker.submit(new DownloadReferrersTask(targetLayer, children));
71 }
72
73 /**
74 * Downloads the primitives referring to the primitive given by <code>id</code> and
75 * <code>type</code>.
76 *
77 *
78 * @param targetLayer the target layer. Must not be null.
79 * @param id the primitive id. id > 0 required.
80 * @param type the primitive type. type != null required
81 * @exception IllegalArgumentException thrown if targetLayer is null
82 * @exception IllegalArgumentException thrown if id <= 0
83 * @exception IllegalArgumentException thrown if type == null
84 */
85 static public void downloadReferrers(OsmDataLayer targetLayer, long id, OsmPrimitiveType type) throws IllegalArgumentException {
86 if (id <= 0)
87 throw new IllegalArgumentException(tr("Id > 0 required, got {0}", id));
88 if (type == null)
89 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type"));
90 Main.worker.submit(new DownloadReferrersTask(targetLayer, id, type));
91 }
92
93 public void actionPerformed(ActionEvent e) {
94 if (!isEnabled() || Main.map == null || Main.map.mapView == null)
95 return;
96 OsmDataLayer layer = Main.map.mapView.getEditLayer();
97 if (layer == null)
98 return;
99 Collection<OsmPrimitive> primitives = layer.data.getSelected();
100 downloadReferrers(layer,primitives);
101 }
102
103 /**
104 * The asynchronous task for downloading referring primitives
105 *
106 */
107 public static class DownloadReferrersTask extends PleaseWaitRunnable {
108 private boolean cancelled;
109 private Exception lastException;
110 private OsmServerBackreferenceReader reader;
111 /** the target layer */
112 private OsmDataLayer targetLayer;
113 /** the collection of child primitives */
114 private Map<Long, OsmPrimitiveType> children;
115 /** the parents */
116 private DataSet parents;
117
118 /**
119 * constructor
120 *
121 * @param targetLayer the target layer for the downloaded primitives. Must not be null.
122 * @param children the collection of child primitives for which parents are to be downloaded
123 *
124 */
125 public DownloadReferrersTask(OsmDataLayer targetLayer, Collection<OsmPrimitive> children) {
126 super("Download referrers", false /* don't ignore exception*/);
127 if (targetLayer == null)
128 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "targetLayer"));
129 cancelled = false;
130 this.children = new HashMap<Long, OsmPrimitiveType>();
131 if (children != null) {
132 for (OsmPrimitive p: children) {
133 if (! p.isNew()) {
134 this.children.put(p.getId(), OsmPrimitiveType.from(p));
135 }
136 }
137 }
138 this.targetLayer = targetLayer;
139 parents = new DataSet();
140 }
141
142 /**
143 * constructor
144 *
145 * @param targetLayer the target layer for the downloaded primitives. Must not be null.
146 * @param primitives the collection of children for which parents are to be downloaded. Children
147 * are specified by their id and their type.
148 *
149 */
150 public DownloadReferrersTask(OsmDataLayer targetLayer, Map<Long, OsmPrimitiveType> children) {
151 super("Download referrers", false /* don't ignore exception*/);
152 if (targetLayer == null)
153 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "targetLayer"));
154 cancelled = false;
155 this.children = new HashMap<Long, OsmPrimitiveType>();
156 if (children != null) {
157 for (Entry<Long, OsmPrimitiveType> entry : children.entrySet()) {
158 if (entry.getKey() > 0 && entry.getValue() != null) {
159 children.put(entry.getKey(), entry.getValue());
160 }
161 }
162 }
163 this.targetLayer = targetLayer;
164 parents = new DataSet();
165 }
166
167 /**
168 * constructor
169 *
170 * @param targetLayer the target layer. Must not be null.
171 * @param id the primitive id. id > 0 required.
172 * @param type the primitive type. type != null required
173 * @exception IllegalArgumentException thrown if id <= 0
174 * @exception IllegalArgumentException thrown if type == null
175 * @exception IllegalArgumentException thrown if targetLayer == null
176 *
177 */
178 public DownloadReferrersTask(OsmDataLayer targetLayer, long id, OsmPrimitiveType type) throws IllegalArgumentException {
179 super("Download referrers", false /* don't ignore exception*/);
180 if (targetLayer == null)
181 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "targetLayer"));
182 if (id <= 0)
183 throw new IllegalArgumentException(tr("Id > 0 required, got {0}", id));
184 if (type == null)
185 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type"));
186 cancelled = false;
187 this.children = new HashMap<Long, OsmPrimitiveType>();
188 this.children.put(id, type);
189 this.targetLayer = targetLayer;
190 parents = new DataSet();
191 }
192
193 @Override
194 protected void cancel() {
195 cancelled = true;
196 synchronized(this) {
197 if (reader != null) {
198 reader.cancel();
199 }
200 }
201 }
202
203 @Override
204 protected void finish() {
205 if (cancelled)
206 return;
207 if (lastException != null) {
208 ExceptionUtil.explainException(lastException);
209 return;
210 }
211
212 MergeVisitor visitor = new MergeVisitor(targetLayer.data, parents);
213 visitor.merge();
214 SwingUtilities.invokeLater(
215 new Runnable() {
216 public void run() {
217 targetLayer.fireDataChange();
218 Main.map.mapView.repaint();
219 }
220 }
221 );
222 if (visitor.getConflicts().isEmpty())
223 return;
224 targetLayer.getConflicts().add(visitor.getConflicts());
225 JOptionPane.showMessageDialog(
226 Main.parent,
227 tr("There were {0} conflicts during import.",
228 visitor.getConflicts().size()
229 ),
230 tr("Conflicts during download"),
231 JOptionPane.WARNING_MESSAGE
232 );
233 }
234
235 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException{
236 reader = new OsmServerBackreferenceReader(id, type);
237 DataSet ds = reader.parseOsm(progressMonitor);
238 synchronized(this) { // avoid race condition in cancel()
239 reader = null;
240 }
241 MergeVisitor visitor = new MergeVisitor(parents, ds);
242 visitor.merge();
243 }
244
245 @Override
246 protected void realRun() throws SAXException, IOException, OsmTransferException {
247 try {
248 progressMonitor.setTicksCount(children.size());
249 int i=1;
250 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
251 if (cancelled)
252 return;
253 String msg = "";
254 switch(entry.getValue()) {
255 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1,children.size(), entry.getKey()); break;
256 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1,children.size(), entry.getKey()); break;
257 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1,children.size(), entry.getKey()); break;
258 }
259 progressMonitor.subTask(msg);
260 downloadParents(entry.getKey(), entry.getValue(), progressMonitor.createSubTaskMonitor(1, false));
261 i++;
262 }
263 } catch(Exception e) {
264 if (cancelled)
265 return;
266 lastException = e;
267 }
268 }
269 }
270
271 @Override
272 protected void updateEnabledState() {
273 if (getCurrentDataSet() == null) {
274 setEnabled(false);
275 } else {
276 updateEnabledState(getCurrentDataSet().getSelected());
277 }
278 }
279
280 @Override
281 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
282 setEnabled(selection != null && !selection.isEmpty());
283 }
284}
Note: See TracBrowser for help on using the repository browser.