source: josm/trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java@ 2077

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

Had to replace DataSet:getPrimitiveById(id) with DataSet:getPrimitiveById(id,type). Primitive ids are not globally unique, only per type of primitive.
Fixed problems in unit test, available unit tests passing again.

File size: 7.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.io.IOException;
9import java.util.Collection;
10import java.util.Collections;
11
12import javax.swing.JOptionPane;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.data.osm.Way;
21import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
22import org.openstreetmap.josm.gui.ExceptionDialogUtil;
23import org.openstreetmap.josm.gui.PleaseWaitRunnable;
24import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
25import org.openstreetmap.josm.gui.progress.ProgressMonitor;
26import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
27import org.openstreetmap.josm.io.OsmTransferException;
28import org.openstreetmap.josm.tools.Shortcut;
29import org.xml.sax.SAXException;
30
31/**
32 * This action synchronizes a set of primitives with their state on the server.
33 *
34 */
35public class UpdateSelectionAction extends JosmAction {
36
37 /**
38 * handle an exception thrown because a primitive was deleted on the server
39 *
40 * @param id the primitive id
41 */
42 protected void handlePrimitiveGoneException(long id, OsmPrimitiveType type) {
43 MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
44 reader.append(getCurrentDataSet(),id, type);
45 DataSet ds = null;
46 try {
47 ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
48 } catch(Exception e) {
49 ExceptionDialogUtil.explainException(e);
50 }
51 Main.map.mapView.getEditLayer().mergeFrom(ds);
52 }
53
54 /**
55 * Updates the data for for the {@see OsmPrimitive}s in <code>selection</code>
56 * with the data currently kept on the server.
57 *
58 * @param selection a collection of {@see OsmPrimitive}s to update
59 *
60 */
61 public void updatePrimitives(final Collection<OsmPrimitive> selection) {
62 UpdatePrimitivesTask task = new UpdatePrimitivesTask(selection);
63 Main.worker.submit(task);
64 }
65
66 /**
67 * Updates the data for for the {@see OsmPrimitive}s with id <code>id</code>
68 * with the data currently kept on the server.
69 *
70 * @param id the id of a primitive in the {@see DataSet} of the current edit layser
71 * @exception IllegalStateException thrown if there is no primitive with <code>id</code> in
72 * the current dataset
73 * @exception IllegalStateException thrown if there is no current dataset
74 *
75 */
76 public void updatePrimitive(OsmPrimitiveType type, long id) throws IllegalStateException{
77 if (getEditLayer() == null)
78 throw new IllegalStateException(tr("No current dataset found"));
79 OsmPrimitive primitive = getEditLayer().data.getPrimitiveById(id, type);
80 if (primitive == null)
81 throw new IllegalStateException(tr("Didn't find a primitive with id {0} in the current dataset", id));
82 updatePrimitives(Collections.singleton(primitive));
83 }
84
85 /**
86 * constructor
87 */
88 public UpdateSelectionAction() {
89 super(tr("Update Selection"),
90 "updateselection",
91 tr("Updates the currently selected primitives from the server"),
92 Shortcut.registerShortcut("file:updateselection",
93 tr("Update Selection"),
94 KeyEvent.VK_U,
95 Shortcut.GROUP_HOTKEY + Shortcut.GROUPS_ALT2),
96 true);
97 }
98
99 /**
100 * Refreshes the enabled state
101 *
102 */
103 @Override
104 protected void updateEnabledState() {
105 setEnabled(getCurrentDataSet() != null
106 && ! getCurrentDataSet().getSelected().isEmpty()
107 );
108 }
109
110 /**
111 * action handler
112 */
113 public void actionPerformed(ActionEvent e) {
114 if (! isEnabled())
115 return;
116 Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
117 if (selection.size() == 0) {
118 JOptionPane.showMessageDialog(
119 Main.parent,
120 tr("There are no selected primitives to update."),
121 tr("Selection empty"),
122 JOptionPane.INFORMATION_MESSAGE
123 );
124 return;
125 }
126 updatePrimitives(selection);
127 }
128
129 /**
130 * The asynchronous task for updating the data using multi fetch.
131 *
132 */
133 class UpdatePrimitivesTask extends PleaseWaitRunnable {
134 private DataSet ds;
135 private boolean canceled;
136 private Exception lastException;
137 private Collection<? extends OsmPrimitive> toUpdate;
138 private MultiFetchServerObjectReader reader;
139
140 public UpdatePrimitivesTask(Collection<? extends OsmPrimitive> toUpdate) {
141 super("Update primitives", false /* don't ignore exception*/);
142 canceled = false;
143 this.toUpdate = toUpdate;
144 }
145
146 @Override
147 protected void cancel() {
148 canceled = true;
149 if (reader != null) {
150 reader.cancel();
151 }
152 }
153
154 @Override
155 protected void finish() {
156 if (canceled)
157 return;
158 if (lastException != null) {
159 ExceptionDialogUtil.explainException(lastException);
160 return;
161 }
162 if (ds != null) {
163 Main.map.mapView.getEditLayer().mergeFrom(ds);
164 }
165 }
166
167 protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) {
168 for (OsmPrimitive primitive : toUpdate) {
169 if (primitive instanceof Node && primitive.getId() > 0) {
170 reader.append((Node)primitive);
171 } else if (primitive instanceof Way) {
172 Way way = (Way)primitive;
173 for (Node node: way.getNodes()) {
174 if (node.getId() > 0) {
175 reader.append(node);
176 }
177 }
178 }
179 }
180 }
181
182 protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) {
183 for (OsmPrimitive primitive : toUpdate) {
184 if (primitive instanceof Way && primitive.getId() > 0) {
185 reader.append((Way)primitive);
186 }
187 }
188 }
189
190 protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) {
191 for (OsmPrimitive primitive : toUpdate) {
192 if (primitive instanceof Relation && primitive.getId() > 0) {
193 reader.append((Relation)primitive);
194 }
195 }
196 }
197
198 @Override
199 protected void realRun() throws SAXException, IOException, OsmTransferException {
200 progressMonitor.indeterminateSubTask("");
201 this.ds = new DataSet();
202 DataSet theirDataSet;
203 try {
204 reader = new MultiFetchServerObjectReader();
205 initMultiFetchReaderWithNodes(reader);
206 initMultiFetchReaderWithWays(reader);
207 initMultiFetchReaderWithRelations(reader);
208 theirDataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
209 MergeVisitor merger = new MergeVisitor(ds, theirDataSet);
210 merger.merge();
211 } catch(Exception e) {
212 if (canceled)
213 return;
214 lastException = e;
215 }
216 }
217 }
218}
Note: See TracBrowser for help on using the repository browser.