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

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

Improved exception handling

  • Property svn:eol-style set to native
File size: 8.2 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.getAllLayers();
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 (dataSet.allPrimitives().isEmpty()) {
116 progressMonitor.setErrorMessage(tr("No data imported."));
117 // need to synthesize a download bounds lest the visual indication of downloaded
118 // area doesn't work
119 dataSet.dataSources.add(new DataSource(currentBounds, "OpenStreetMap server"));
120 }
121 rememberDownloadedData(dataSet);
122 int numDataLayers = getNumDataLayers();
123 if (newLayer || numDataLayers == 0 || (numDataLayers > 1 && getEditLayer() == null)) {
124 // the user explicitly wants a new layer, we don't have any layer at all
125 // or it is not clear which layer to merge to
126 //
127 OsmDataLayer layer = new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
128 Main.main.addLayer(layer);
129 } else {
130 OsmDataLayer target;
131 target = getEditLayer();
132 if (target == null) {
133 target = getFirstDataLayer();
134 }
135 target.mergeFrom(dataSet);
136 }
137 }
138
139 @Override protected void cancel() {
140 this.canceled = true;
141 if (reader != null) {
142 reader.cancel();
143 }
144 DownloadOsmTask.this.setCanceled(true);
145 }
146 }
147 private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"), true);
148
149 private void rememberDownloadedData(DataSet ds) {
150 this.downloadedData = ds;
151 }
152
153 public boolean isCanceled() {
154 return canceled;
155 }
156
157 public void setCanceled(boolean canceled) {
158 this.canceled = canceled;
159 }
160
161 public boolean isFailed() {
162 return failed;
163 }
164
165 public void setFailed(boolean failed) {
166 this.failed = failed;
167 }
168
169 public DataSet getDownloadedData() {
170 return downloadedData;
171 }
172
173 public void download(DownloadAction action, double minlat, double minlon,
174 double maxlat, double maxlon, ProgressMonitor progressMonitor) {
175 // Swap min and max if user has specified them the wrong way round
176 // (easy to do if you are crossing 0, for example)
177 // FIXME should perhaps be done in download dialog?
178 if (minlat > maxlat) {
179 double t = minlat; minlat = maxlat; maxlat = t;
180 }
181 if (minlon > maxlon) {
182 double t = minlon; minlon = maxlon; maxlon = t;
183 }
184
185 boolean newLayer = action != null
186 && (action.dialog == null || action.dialog.newLayer.isSelected());
187
188 Task t = new Task(newLayer,
189 new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
190 currentBounds = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
191 // We need submit instead of execute so we can wait for it to finish and get the error
192 // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
193 task = Main.worker.submit(t, t);
194 }
195
196 /**
197 * Loads a given URL from the OSM Server
198 * @param True if the data should be saved to a new layer
199 * @param The URL as String
200 */
201 public void loadUrl(boolean new_layer, String url) {
202 Task t = new Task(new_layer,
203 new OsmServerLocationReader(url),
204 NullProgressMonitor.INSTANCE);
205 task = Main.worker.submit(t, t);
206 }
207
208 public JCheckBox getCheckBox() {
209 return checkBox;
210 }
211
212 public String getPreferencesSuffix() {
213 return "osm";
214 }
215
216 /*
217 * (non-Javadoc)
218 * @see org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask#getErrorMessage()
219 */
220 public String getErrorMessage() {
221 if(task == null)
222 return "";
223
224 try {
225 Task t = task.get();
226 return t.getProgressMonitor().getErrorMessage() == null
227 ? ""
228 : t.getProgressMonitor().getErrorMessage();
229 } catch (Exception e) {
230 return "";
231 }
232 }
233}
Note: See TracBrowser for help on using the repository browser.