source: josm/trunk/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java@ 3128

Last change on this file since 3128 was 3083, checked in by bastiK, 14 years ago

added svn:eol-style=native to source files

  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.io.IOException;
8import java.lang.reflect.InvocationTargetException;
9import java.util.Collection;
10import java.util.Collections;
11import java.util.logging.Logger;
12
13import javax.swing.SwingUtilities;
14
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.DataSetMerger;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
20import org.openstreetmap.josm.data.osm.Relation;
21import org.openstreetmap.josm.data.osm.Way;
22import org.openstreetmap.josm.gui.ExceptionDialogUtil;
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.MultiFetchServerObjectReader;
27import org.openstreetmap.josm.io.OsmServerObjectReader;
28import org.openstreetmap.josm.io.OsmTransferException;
29import org.xml.sax.SAXException;
30
31/**
32 * The asynchronous task for updating a collection of objects using multi fetch.
33 *
34 */
35public class UpdatePrimitivesTask extends PleaseWaitRunnable {
36 @SuppressWarnings("unused")
37 static private final Logger logger = Logger.getLogger(UpdatePrimitivesTask.class.getName());
38
39 private DataSet ds;
40 private boolean canceled;
41 private Exception lastException;
42 private Collection<? extends OsmPrimitive> toUpdate;
43 private OsmDataLayer layer;
44 private MultiFetchServerObjectReader multiObjectReader;
45 private OsmServerObjectReader objectReader;
46
47 /**
48 * Creates the task
49 *
50 * @param layer the layer in which primitives are updated. Must not be null.
51 * @param toUpdate a collection of primitives to update from the server. Set to
52 * the empty collection if null.
53 * @throws IllegalArgumentException thrown if layer is null.
54 */
55 public UpdatePrimitivesTask(OsmDataLayer layer, Collection<? extends OsmPrimitive> toUpdate) throws IllegalArgumentException{
56 super(tr("Update objects"), false /* don't ignore exception */);
57 ensureParameterNotNull(layer, "layer");
58 if (toUpdate == null) {
59 toUpdate = Collections.emptyList();
60 }
61 this.layer = layer;
62 this.toUpdate = toUpdate;
63 }
64
65 @Override
66 protected void cancel() {
67 canceled = true;
68 synchronized(this) {
69 if (multiObjectReader != null) {
70 multiObjectReader.cancel();
71 }
72 if (objectReader != null) {
73 objectReader.cancel();
74 }
75 }
76 }
77
78 @Override
79 protected void finish() {
80 if (canceled)
81 return;
82 if (lastException != null) {
83 ExceptionDialogUtil.explainException(lastException);
84 return;
85 }
86 Runnable r = new Runnable() {
87 public void run() {
88 layer.mergeFrom(ds);
89 layer.onPostDownloadFromServer();
90 }
91 };
92
93 if (SwingUtilities.isEventDispatchThread()) {
94 r.run();
95 } else {
96 try {
97 SwingUtilities.invokeAndWait(r);
98 } catch(InterruptedException e) {
99 e.printStackTrace();
100 } catch(InvocationTargetException e) {
101 e.printStackTrace();
102 }
103 }
104 }
105
106 protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) {
107 getProgressMonitor().indeterminateSubTask(tr("Initializing nodes to update ..."));
108 for (OsmPrimitive primitive : toUpdate) {
109 if (primitive instanceof Node && !primitive.isNew()) {
110 reader.append((Node)primitive);
111 } else if (primitive instanceof Way) {
112 Way way = (Way)primitive;
113 for (Node node: way.getNodes()) {
114 if (!node.isNew()) {
115 reader.append(node);
116 }
117 }
118 }
119 }
120 }
121
122 protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) {
123 getProgressMonitor().indeterminateSubTask(tr("Initializing ways to update ..."));
124 for (OsmPrimitive primitive : toUpdate) {
125 if (primitive instanceof Way && !primitive.isNew()) {
126 reader.append((Way)primitive);
127 }
128 }
129 }
130
131 protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) {
132 getProgressMonitor().indeterminateSubTask(tr("Initializing relations to update ..."));
133 for (OsmPrimitive primitive : toUpdate) {
134 if (primitive instanceof Relation && !primitive.isNew()) {
135 reader.append((Relation)primitive);
136 }
137 }
138 }
139
140 @Override
141 protected void realRun() throws SAXException, IOException, OsmTransferException {
142 this.ds = new DataSet();
143 DataSet theirDataSet;
144 try {
145 synchronized(this) {
146 if (canceled) return;
147 multiObjectReader = new MultiFetchServerObjectReader();
148 }
149 initMultiFetchReaderWithNodes(multiObjectReader);
150 initMultiFetchReaderWithWays(multiObjectReader);
151 initMultiFetchReaderWithRelations(multiObjectReader);
152 theirDataSet = multiObjectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
153 synchronized(this) {
154 multiObjectReader = null;
155 }
156 DataSetMerger merger = new DataSetMerger(ds, theirDataSet);
157 merger.merge();
158 // a way loaded with MultiFetch may have incomplete nodes because at least one of its
159 // nodes isn't present in the local data set. We therefore fully load all
160 // ways with incomplete nodes.
161 //
162 for (Way w : ds.getWays()) {
163 if (canceled) return;
164 if (w.hasIncompleteNodes()) {
165 synchronized(this) {
166 if (canceled) return;
167 objectReader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */);
168 }
169 theirDataSet = objectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
170 synchronized (this) {
171 objectReader = null;
172 }
173 merger = new DataSetMerger(ds, theirDataSet);
174 merger.merge();
175 }
176 }
177 } catch(Exception e) {
178 if (canceled)
179 return;
180 lastException = e;
181 }
182 }
183}
Note: See TracBrowser for help on using the repository browser.