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

Last change on this file since 2575 was 2512, checked in by stoecker, 14 years ago

i18n updated, fixed files to reduce problems when applying patches, fix #4017

File size: 11.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
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.DataSetMerger;
21import org.openstreetmap.josm.data.osm.OsmPrimitive;
22import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
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.isDisplayingMapView())
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 DataSetMerger visitor = new DataSetMerger(targetLayer.data, parents);
213 visitor.merge();
214 SwingUtilities.invokeLater(
215 new Runnable() {
216 public void run() {
217 targetLayer.fireDataChange();
218 targetLayer.onPostDownloadFromServer();
219 Main.map.mapView.repaint();
220 }
221 }
222 );
223 if (visitor.getConflicts().isEmpty())
224 return;
225 targetLayer.getConflicts().add(visitor.getConflicts());
226 JOptionPane.showMessageDialog(
227 Main.parent,
228 tr("There were {0} conflicts during import.",
229 visitor.getConflicts().size()
230 ),
231 tr("Conflicts during download"),
232 JOptionPane.WARNING_MESSAGE
233 );
234 }
235
236 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException{
237 reader = new OsmServerBackreferenceReader(id, type);
238 DataSet ds = reader.parseOsm(progressMonitor);
239 synchronized(this) { // avoid race condition in cancel()
240 reader = null;
241 }
242 DataSetMerger visitor = new DataSetMerger(parents, ds);
243 visitor.merge();
244 }
245
246 @Override
247 protected void realRun() throws SAXException, IOException, OsmTransferException {
248 try {
249 progressMonitor.setTicksCount(children.size());
250 int i=1;
251 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
252 if (cancelled)
253 return;
254 String msg = "";
255 switch(entry.getValue()) {
256 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1,children.size(), entry.getKey()); break;
257 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1,children.size(), entry.getKey()); break;
258 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1,children.size(), entry.getKey()); break;
259 }
260 progressMonitor.subTask(msg);
261 downloadParents(entry.getKey(), entry.getValue(), progressMonitor.createSubTaskMonitor(1, false));
262 i++;
263 }
264 } catch(Exception e) {
265 if (cancelled)
266 return;
267 lastException = e;
268 }
269 }
270 }
271
272 @Override
273 protected void updateEnabledState() {
274 if (getCurrentDataSet() == null) {
275 setEnabled(false);
276 } else {
277 updateEnabledState(getCurrentDataSet().getSelected());
278 }
279 }
280
281 @Override
282 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
283 setEnabled(selection != null && !selection.isEmpty());
284 }
285}
Note: See TracBrowser for help on using the repository browser.