001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions.downloadtasks;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.io.IOException;
007import java.net.URL;
008import java.util.List;
009import java.util.concurrent.Future;
010
011import org.openstreetmap.josm.Main;
012import org.openstreetmap.josm.data.Bounds;
013import org.openstreetmap.josm.data.notes.Note;
014import org.openstreetmap.josm.gui.PleaseWaitRunnable;
015import org.openstreetmap.josm.gui.layer.NoteLayer;
016import org.openstreetmap.josm.gui.progress.ProgressMonitor;
017import org.openstreetmap.josm.io.BoundingBoxDownloader;
018import org.openstreetmap.josm.io.OsmServerLocationReader;
019import org.openstreetmap.josm.io.OsmServerReader;
020import org.openstreetmap.josm.io.OsmTransferException;
021import org.xml.sax.SAXException;
022
023/** Task for downloading notes */
024public class DownloadNotesTask extends AbstractDownloadTask {
025
026    private static final String PATTERN_API_URL = "https?://.*/api/0.6/notes.*";
027    private static final String PATTERN_DUMP_FILE = "https?://.*/(.*\\.osn(.bz2)?)";
028
029    private DownloadTask downloadTask;
030
031    @Override
032    public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
033        downloadTask = new DownloadBoundingBoxTask(new BoundingBoxDownloader(downloadArea), progressMonitor);
034        return Main.worker.submit(downloadTask);
035    }
036
037    @Override
038    public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
039        if (url.endsWith(".bz2")) {
040            downloadTask = new DownloadBzip2RawUrlTask(new OsmServerLocationReader(url), progressMonitor);
041        } else {
042            downloadTask = new DownloadRawUrlTask(new OsmServerLocationReader(url), progressMonitor);
043        }
044        return Main.worker.submit(downloadTask);
045    }
046
047    @Override
048    public void cancel() {
049        if (downloadTask != null) {
050            downloadTask.cancel();
051        }
052    }
053
054    @Override
055    public String getConfirmationMessage(URL url) {
056        return null;
057    }
058
059    @Override
060    public String getTitle() {
061        return "Download OSM Notes";
062    }
063
064    @Override
065    public String[] getPatterns() {
066        return new String[] {PATTERN_API_URL, PATTERN_DUMP_FILE};
067    }
068
069    @Override
070    public boolean isSafeForRemotecontrolRequests() {
071        return true;
072    }
073
074    abstract class DownloadTask extends PleaseWaitRunnable {
075        protected OsmServerReader reader;
076        protected List<Note> notesData;
077
078        public DownloadTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
079            super(tr("Downloading Notes"), progressMonitor, false);
080            this.reader = reader;
081        }
082
083        @Override
084        protected void finish() {
085            Main.debug("finish called in DownloadNotesTask");
086            if (isCanceled() || isFailed()) {
087                Main.debug("was cancelled or failed");
088                return;
089            }
090
091            if (notesData == null) {
092                return;
093            }
094            Main.debug("Notes downloaded: " + notesData.size());
095
096            List<NoteLayer> noteLayers = null;
097            if (Main.map != null) {
098                noteLayers = Main.map.mapView.getLayersOfType(NoteLayer.class);
099            }
100            NoteLayer layer;
101            if (noteLayers != null && noteLayers.size() > 0) {
102                layer = noteLayers.get(0);
103                layer.getNoteData().addNotes(notesData);
104            } else {
105                layer = new NoteLayer(notesData, "Notes");
106                Main.main.addLayer(layer);
107            }
108        }
109
110        @Override
111        protected void cancel() {
112            setCanceled(true);
113            if (reader != null) {
114                reader.cancel();
115            }
116        }
117
118        @Override
119        public abstract void realRun() throws IOException, SAXException, OsmTransferException;
120    }
121
122    class DownloadBoundingBoxTask extends DownloadTask {
123
124        public DownloadBoundingBoxTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
125            super(reader, progressMonitor);
126        }
127
128        @Override
129        public void realRun() throws IOException, SAXException, OsmTransferException {
130            if (isCanceled()) {
131                return;
132            }
133            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
134            try {
135                notesData = reader.parseNotes(null, null, subMonitor);
136            } catch (Exception e) {
137                if (isCanceled())
138                    return;
139                if (e instanceof OsmTransferException) {
140                    rememberException(e);
141                } else {
142                    rememberException(new OsmTransferException(e));
143                }
144            }
145        }
146    }
147
148    class DownloadRawUrlTask extends DownloadTask {
149
150        public DownloadRawUrlTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
151            super(reader, progressMonitor);
152        }
153
154        @Override
155        public void realRun() throws IOException, SAXException, OsmTransferException {
156            if (isCanceled()) {
157                return;
158            }
159            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
160            try {
161                notesData = reader.parseRawNotes(subMonitor);
162            } catch (Exception e) {
163                if (isCanceled())
164                    return;
165                if (e instanceof OsmTransferException) {
166                    rememberException(e);
167                } else {
168                    rememberException(new OsmTransferException(e));
169                }
170            }
171        }
172    }
173
174    class DownloadBzip2RawUrlTask extends DownloadTask {
175
176        public DownloadBzip2RawUrlTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
177            super(reader, progressMonitor);
178        }
179
180        @Override
181        public void realRun() throws IOException, SAXException, OsmTransferException {
182            if (isCanceled()) {
183                return;
184            }
185            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
186            try {
187                notesData = reader.parseRawNotesBzip2(subMonitor);
188            } catch (Exception e) {
189                if (isCanceled())
190                    return;
191                if (e instanceof OsmTransferException) {
192                    rememberException(e);
193                } else {
194                    rememberException(new OsmTransferException(e));
195                }
196            }
197        }
198    }
199
200}