source: josm/trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java@ 2013

Last change on this file since 2013 was 2013, checked in by stoecker, 15 years ago

fix #3341 - NPE

  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions.downloadtasks;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.util.Collection;
8import java.util.concurrent.Future;
9import java.util.logging.Logger;
10
11import javax.swing.JCheckBox;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.actions.DownloadAction;
15import org.openstreetmap.josm.data.Bounds;
16import org.openstreetmap.josm.data.coor.LatLon;
17import org.openstreetmap.josm.data.osm.DataSet;
18import org.openstreetmap.josm.data.osm.DataSource;
19import org.openstreetmap.josm.gui.ExceptionDialogUtil;
20import org.openstreetmap.josm.gui.PleaseWaitRunnable;
21import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
22import org.openstreetmap.josm.gui.layer.Layer;
23import org.openstreetmap.josm.gui.layer.OsmDataLayer;
24import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
25import org.openstreetmap.josm.gui.progress.ProgressMonitor;
26import org.openstreetmap.josm.io.BoundingBoxDownloader;
27import org.openstreetmap.josm.io.OsmServerLocationReader;
28import org.openstreetmap.josm.io.OsmServerReader;
29import org.openstreetmap.josm.io.OsmTransferException;
30import org.xml.sax.SAXException;
31
32
33/**
34 * Open the download dialog and download the data.
35 * Run in the worker thread.
36 */
37public class DownloadOsmTask implements DownloadTask {
38 private static final Logger logger = Logger.getLogger(DownloadOsmTask.class.getName());
39
40 private static Bounds currentBounds;
41 private Future<Task> task = null;
42 private DataSet downloadedData;
43 private boolean canceled = false;
44 private boolean failed = false;
45
46 private class Task extends PleaseWaitRunnable {
47 private OsmServerReader reader;
48 private DataSet dataSet;
49 private boolean newLayer;
50 private boolean canceled;
51 private Exception lastException;
52
53 public Task(boolean newLayer, OsmServerReader reader, ProgressMonitor progressMonitor) {
54 super(tr("Downloading data"), progressMonitor, false);
55 this.reader = reader;
56 this.newLayer = newLayer;
57 }
58
59 @Override public void realRun() throws IOException, SAXException, OsmTransferException {
60 try {
61 dataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
62 } catch(Exception e) {
63 if (canceled) {
64 logger.warning(tr("Ignoring exception because download has been cancelled. Exception was: {0}" + e.toString()));
65 return;
66 }
67 if (e instanceof OsmTransferException) {
68 lastException = e;
69 } else {
70 lastException = new OsmTransferException(e);
71 }
72 }
73 }
74
75 protected OsmDataLayer getEditLayer() {
76 if (Main.map == null) return null;
77 if (Main.map.mapView == null) return null;
78 return Main.map.mapView.getEditLayer();
79 }
80
81 protected int getNumDataLayers() {
82 int count = 0;
83 if (Main.map == null) return 0;
84 if (Main.map.mapView == null) return 0;
85 Collection<Layer> layers = Main.map.mapView.getAllLayers();
86 for (Layer layer : layers) {
87 if (layer instanceof OsmDataLayer) {
88 count++;
89 }
90 }
91 return count;
92 }
93
94 protected OsmDataLayer getFirstDataLayer() {
95 if (Main.map == null) return null;
96 if (Main.map.mapView == null) return null;
97 Collection<Layer> layers = Main.map.mapView.getAllLayersAsList();
98 for (Layer layer : layers) {
99 if (layer instanceof OsmDataLayer)
100 return (OsmDataLayer) layer;
101 }
102 return null;
103 }
104
105 @Override protected void finish() {
106 if (canceled)
107 return;
108 if (lastException != null) {
109 ExceptionDialogUtil.explainException(lastException);
110 DownloadOsmTask.this.setFailed(true);
111 return;
112 }
113 if (dataSet == null)
114 return; // user canceled download or error occurred
115 if (currentBounds == null) {
116 return; // no data retrieved
117 }
118 if (dataSet.allPrimitives().isEmpty()) {
119 progressMonitor.setErrorMessage(tr("No data imported."));
120 // need to synthesize a download bounds lest the visual indication of downloaded
121 // area doesn't work
122 dataSet.dataSources.add(new DataSource(currentBounds, "OpenStreetMap server"));
123 }
124 rememberDownloadedData(dataSet);
125 int numDataLayers = getNumDataLayers();
126 if (newLayer || numDataLayers == 0 || (numDataLayers > 1 && getEditLayer() == null)) {
127 // the user explicitly wants a new layer, we don't have any layer at all
128 // or it is not clear which layer to merge to
129 //
130 OsmDataLayer layer = new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
131 Main.main.addLayer(layer);
132 } else {
133 OsmDataLayer target;
134 target = getEditLayer();
135 if (target == null) {
136 target = getFirstDataLayer();
137 }
138 target.mergeFrom(dataSet);
139 }
140 }
141
142 @Override protected void cancel() {
143 this.canceled = true;
144 if (reader != null) {
145 reader.cancel();
146 }
147 DownloadOsmTask.this.setCanceled(true);
148 }
149 }
150 private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"), true);
151
152 private void rememberDownloadedData(DataSet ds) {
153 this.downloadedData = ds;
154 }
155
156 public boolean isCanceled() {
157 return canceled;
158 }
159
160 public void setCanceled(boolean canceled) {
161 this.canceled = canceled;
162 }
163
164 public boolean isFailed() {
165 return failed;
166 }
167
168 public void setFailed(boolean failed) {
169 this.failed = failed;
170 }
171
172 public DataSet getDownloadedData() {
173 return downloadedData;
174 }
175
176 public void download(DownloadAction action, double minlat, double minlon,
177 double maxlat, double maxlon, ProgressMonitor progressMonitor) {
178 // Swap min and max if user has specified them the wrong way round
179 // (easy to do if you are crossing 0, for example)
180 // FIXME should perhaps be done in download dialog?
181 if (minlat > maxlat) {
182 double t = minlat; minlat = maxlat; maxlat = t;
183 }
184 if (minlon > maxlon) {
185 double t = minlon; minlon = maxlon; maxlon = t;
186 }
187
188 boolean newLayer = action != null
189 && (action.dialog == null || action.dialog.newLayer.isSelected());
190
191 Task t = new Task(newLayer,
192 new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
193 currentBounds = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
194 // We need submit instead of execute so we can wait for it to finish and get the error
195 // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
196 task = Main.worker.submit(t, t);
197 }
198
199 /**
200 * Loads a given URL from the OSM Server
201 * @param True if the data should be saved to a new layer
202 * @param The URL as String
203 */
204 public void loadUrl(boolean new_layer, String url) {
205 Task t = new Task(new_layer,
206 new OsmServerLocationReader(url),
207 NullProgressMonitor.INSTANCE);
208 task = Main.worker.submit(t, t);
209 }
210
211 public JCheckBox getCheckBox() {
212 return checkBox;
213 }
214
215 public String getPreferencesSuffix() {
216 return "osm";
217 }
218
219 /*
220 * (non-Javadoc)
221 * @see org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask#getErrorMessage()
222 */
223 public String getErrorMessage() {
224 if(task == null)
225 return "";
226
227 try {
228 Task t = task.get();
229 return t.getProgressMonitor().getErrorMessage() == null
230 ? ""
231 : t.getProgressMonitor().getErrorMessage();
232 } catch (Exception e) {
233 return "";
234 }
235 }
236}
Note: See TracBrowser for help on using the repository browser.