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    abstract class DownloadTask extends PleaseWaitRunnable {
070        protected OsmServerReader reader;
071        protected List<Note> notesData;
072
073        public DownloadTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
074            super(tr("Downloading Notes"), progressMonitor, false);
075            this.reader = reader;
076        }
077
078        @Override
079        protected void finish() {
080            Main.debug("finish called in DownloadNotesTask");
081            if (isCanceled() || isFailed()) {
082                Main.debug("was cancelled or failed");
083                return;
084            }
085
086            if (notesData == null) {
087                return;
088            }
089            Main.debug("Notes downloaded: " + notesData.size());
090
091            List<NoteLayer> noteLayers = null;
092            if (Main.map != null) {
093                noteLayers = Main.map.mapView.getLayersOfType(NoteLayer.class);
094            }
095            NoteLayer layer;
096            if (noteLayers != null && noteLayers.size() > 0) {
097                layer = noteLayers.get(0);
098                layer.getNoteData().addNotes(notesData);
099            } else {
100                layer = new NoteLayer(notesData, "Notes");
101                Main.main.addLayer(layer);
102            }
103        }
104
105        @Override
106        protected void cancel() {
107            setCanceled(true);
108            if (reader != null) {
109                reader.cancel();
110            }
111        }
112
113        @Override
114        public abstract void realRun() throws IOException, SAXException, OsmTransferException;
115    }
116
117    class DownloadBoundingBoxTask extends DownloadTask {
118
119        public DownloadBoundingBoxTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
120            super(reader, progressMonitor);
121        }
122
123        @Override
124        public void realRun() throws IOException, SAXException, OsmTransferException {
125            if (isCanceled()) {
126                return;
127            }
128            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
129            try {
130                notesData = reader.parseNotes(null, null, subMonitor);
131            } catch (Exception e) {
132                if (isCanceled())
133                    return;
134                if (e instanceof OsmTransferException) {
135                    rememberException(e);
136                } else {
137                    rememberException(new OsmTransferException(e));
138                }
139            }
140        }
141    }
142
143    class DownloadRawUrlTask extends DownloadTask {
144
145        public DownloadRawUrlTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
146            super(reader, progressMonitor);
147        }
148
149        @Override
150        public void realRun() throws IOException, SAXException, OsmTransferException {
151            if (isCanceled()) {
152                return;
153            }
154            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
155            try {
156                notesData = reader.parseRawNotes(subMonitor);
157            } catch (Exception e) {
158                if (isCanceled())
159                    return;
160                if (e instanceof OsmTransferException) {
161                    rememberException(e);
162                } else {
163                    rememberException(new OsmTransferException(e));
164                }
165            }
166        }
167    }
168
169    class DownloadBzip2RawUrlTask extends DownloadTask {
170
171        public DownloadBzip2RawUrlTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
172            super(reader, progressMonitor);
173        }
174
175        @Override
176        public void realRun() throws IOException, SAXException, OsmTransferException {
177            if (isCanceled()) {
178                return;
179            }
180            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
181            try {
182                notesData = reader.parseRawNotesBzip2(subMonitor);
183            } catch (Exception e) {
184                if (isCanceled())
185                    return;
186                if (e instanceof OsmTransferException) {
187                    rememberException(e);
188                } else {
189                    rememberException(new OsmTransferException(e));
190                }
191            }
192        }
193    }
194
195}