Ticket #10503: notesDownload.patch

File notesDownload.patch, 14.1 KB (added by ToeBee, 11 years ago)
  • src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.actions.downloadtasks;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.io.IOException;
     7import java.net.URL;
     8import java.util.List;
     9import java.util.concurrent.Future;
     10
     11import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.data.Bounds;
     13import org.openstreetmap.josm.data.notes.Note;
     14import org.openstreetmap.josm.gui.PleaseWaitRunnable;
     15import org.openstreetmap.josm.gui.layer.NoteLayer;
     16import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     17import org.openstreetmap.josm.io.BoundingBoxDownloader;
     18import org.openstreetmap.josm.io.OsmServerLocationReader;
     19import org.openstreetmap.josm.io.OsmServerReader;
     20import org.openstreetmap.josm.io.OsmTransferException;
     21import org.xml.sax.SAXException;
     22
     23/** Task for downloading notes */
     24public class DownloadNotesTask extends AbstractDownloadTask {
     25
     26    private static final String PATTERN_API_URL = "https?://.*/api/0.6/notes.*";
     27    private static final String PATTERN_DUMP_FILE = "https?://.*/(.*\\.osn(.bz2)?)";
     28
     29    private DownloadTask downloadTask;
     30
     31    @Override
     32    public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
     33        downloadTask = new DownloadBoundingBoxTask(new BoundingBoxDownloader(downloadArea), progressMonitor);
     34        return Main.worker.submit(downloadTask);
     35    }
     36
     37    @Override
     38    public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
     39        if (url.endsWith(".bz2")) {
     40            downloadTask = new DownloadBzip2RawUrlTask(new OsmServerLocationReader(url), progressMonitor);
     41        } else {
     42            downloadTask = new DownloadRawUrlTask(new OsmServerLocationReader(url), progressMonitor);
     43        }
     44        return Main.worker.submit(downloadTask);
     45    }
     46
     47    @Override
     48    public void cancel() {
     49        if (downloadTask != null) {
     50            downloadTask.cancel();
     51        }
     52    }
     53
     54    @Override
     55    public String getConfirmationMessage(URL url) {
     56        return null;
     57    }
     58
     59    @Override
     60    public String getTitle() {
     61        return "Download OSM Notes";
     62    }
     63
     64    @Override
     65    public String[] getPatterns() {
     66        return new String[] {PATTERN_API_URL, PATTERN_DUMP_FILE};
     67    }
     68
     69    abstract class DownloadTask extends PleaseWaitRunnable {
     70        protected OsmServerReader reader;
     71        protected List<Note> notesData;
     72
     73        public DownloadTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
     74            super(tr("Downloading Notes"));
     75            this.reader = reader;
     76        }
     77
     78
     79        @Override
     80        protected void finish() {
     81            Main.debug("finish called in DownloadNotesTask");
     82            if (isCanceled() || isFailed()) {
     83                Main.debug("was cancelled or failed");
     84                return;
     85            }
     86
     87            if (notesData == null) {
     88                return;
     89            }
     90            Main.debug("Notes downloaded: " + notesData.size());
     91
     92            List<NoteLayer> noteLayers = null;
     93            if (Main.map != null) {
     94                noteLayers = Main.map.mapView.getLayersOfType(NoteLayer.class);
     95            }
     96            NoteLayer layer;
     97            if (noteLayers != null && noteLayers.size() > 0) {
     98                layer = noteLayers.get(0);
     99                layer.addNotes(notesData);
     100            } else {
     101                layer = new NoteLayer(notesData, "Notes");
     102                Main.main.addLayer(layer);
     103            }
     104        }
     105
     106        @Override
     107        protected void cancel() {
     108            setCanceled(true);
     109            if (reader != null) {
     110                reader.cancel();
     111            }
     112        }
     113
     114        @Override
     115        public abstract void realRun() throws IOException, SAXException, OsmTransferException;
     116    }
     117
     118    class DownloadBoundingBoxTask extends DownloadTask {
     119
     120        public DownloadBoundingBoxTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
     121            super(reader, progressMonitor);
     122        }
     123
     124        @Override
     125        public void realRun() throws IOException, SAXException, OsmTransferException {
     126            if (isCanceled()) {
     127                return;
     128            }
     129            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
     130            try {
     131                notesData = reader.parseNotes(null, null, subMonitor);
     132            } catch (Exception e) {
     133                if (isCanceled())
     134                    return;
     135                if (e instanceof OsmTransferException) {
     136                    rememberException(e);
     137                } else {
     138                    rememberException(new OsmTransferException(e));
     139                }
     140            }
     141        }
     142    }
     143
     144    class DownloadRawUrlTask extends DownloadTask {
     145
     146        public DownloadRawUrlTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
     147            super(reader, progressMonitor);
     148        }
     149
     150        @Override
     151        public void realRun() throws IOException, SAXException, OsmTransferException {
     152            if (isCanceled()) {
     153                return;
     154            }
     155            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
     156            try {
     157                notesData = reader.parseRawNotes(subMonitor);
     158            } catch (Exception e) {
     159                if (isCanceled())
     160                    return;
     161                if (e instanceof OsmTransferException) {
     162                    rememberException(e);
     163                } else {
     164                    rememberException(new OsmTransferException(e));
     165                }
     166            }
     167        }
     168    }
     169
     170    class DownloadBzip2RawUrlTask extends DownloadTask {
     171
     172        public DownloadBzip2RawUrlTask(OsmServerReader reader, ProgressMonitor progressMonitor) {
     173            super(reader, progressMonitor);
     174        }
     175
     176        @Override
     177        public void realRun() throws IOException, SAXException, OsmTransferException {
     178            if (isCanceled()) {
     179                return;
     180            }
     181            ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
     182            try {
     183                notesData = reader.parseRawNotesBzip2(subMonitor);
     184            } catch (Exception e) {
     185                if (isCanceled())
     186                    return;
     187                if (e instanceof OsmTransferException) {
     188                    rememberException(e);
     189                } else {
     190                    rememberException(new OsmTransferException(e));
     191                }
     192            }
     193        }
     194    }
     195
     196}
  • src/org/openstreetmap/josm/io/BoundingBoxDownloader.java

     
    55
    66import java.io.IOException;
    77import java.io.InputStream;
     8import java.util.List;
    89
     10import org.openstreetmap.josm.Main;
    911import org.openstreetmap.josm.data.Bounds;
    1012import org.openstreetmap.josm.data.gpx.GpxData;
     13import org.openstreetmap.josm.data.notes.Note;
    1114import org.openstreetmap.josm.data.osm.DataSet;
    1215import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1316import org.openstreetmap.josm.tools.CheckParameterUtil;
     
    153156            activeConnection = null;
    154157        }
    155158    }
     159
     160    @Override
     161    public List<Note> parseNotes(Integer noteLimit, Integer daysClosed, ProgressMonitor progressMonitor) throws OsmTransferException {
     162        progressMonitor.beginTask("Downloading notes");
     163        noteLimit = checkNoteLimit(noteLimit);
     164        daysClosed = checkDaysClosed(daysClosed);
     165        String url = new StringBuilder()
     166        .append("notes?limit")
     167        .append(noteLimit)
     168        .append("&closed=")
     169        .append(daysClosed)
     170        .append("&bbox=")
     171        .append(lon1)
     172        .append(",").append(lat1)
     173        .append(",").append(lon2)
     174        .append(",").append(lat2)
     175        .toString();
     176        try {
     177            InputStream is = getInputStream(url, progressMonitor.createSubTaskMonitor(1, false));
     178            NoteReader reader = new NoteReader(is);
     179            return reader.parse();
     180        } catch (IOException e) {
     181            throw new OsmTransferException(e);
     182        } catch (SAXException e) {
     183            throw new OsmTransferException(e);
     184        } finally {
     185            progressMonitor.finishTask();
     186        }
     187    }
     188
     189    private Integer checkNoteLimit(Integer limit) {
     190        if (limit == null) {
     191            limit = Main.pref.getInteger("osm.notes.downloadLimit", 1000);
     192        }
     193        if (limit > 10000) {
     194            Main.error("Requested note limit is over API hard limit of 10000. Reducing to 10000.");
     195            limit = 10000;
     196        }
     197        if (limit < 1) {
     198            Main.error("Requested note limit is less than 1. Setting to 1.");
     199            limit = 1;
     200        }
     201        Main.debug("returning note limit: " + limit);
     202        return limit;
     203    }
     204
     205    private Integer checkDaysClosed(Integer days) {
     206        if (days == null) {
     207            days = Main.pref.getInteger("osm.notes.daysClosed", 1);
     208        }
     209        if (days < -1) {
     210            Main.error("Requested days closed must be greater than -1");
     211            days = -1;
     212        }
     213        Main.debug("returning days closed: " + days);
     214        return days;
     215    }
     216
    156217}
  • src/org/openstreetmap/josm/io/OsmServerLocationReader.java

     
    55
    66import java.io.IOException;
    77import java.io.InputStream;
     8import java.util.ArrayList;
     9import java.util.List;
    810
    911import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
    1012import org.openstreetmap.josm.data.gpx.GpxData;
     13import org.openstreetmap.josm.data.notes.Note;
    1114import org.openstreetmap.josm.data.osm.DataSet;
    1215import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1316import org.openstreetmap.josm.tools.Utils;
     
    105108        return doParse(new GpxParser(progressMonitor, Compression.BZIP2), progressMonitor);
    106109    }
    107110
     111    @Override
     112    public List<Note> parseRawNotes(final ProgressMonitor progressMonitor) throws OsmTransferException {
     113        return doParse(new NoteParser(progressMonitor, Compression.NONE), progressMonitor);
     114    }
     115
     116    @Override
     117    public List<Note> parseRawNotesBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
     118        return doParse(new NoteParser(progressMonitor, Compression.BZIP2), progressMonitor);
     119    }
     120
    108121    protected class OsmParser extends Parser<DataSet> {
    109122        protected OsmParser(ProgressMonitor progressMonitor, Compression compression) {
    110123            super(progressMonitor, compression);
     
    153166            return result;
    154167        }
    155168    }
     169
     170    protected class NoteParser extends Parser<List<Note>> {
     171
     172        public NoteParser(ProgressMonitor progressMonitor, Compression compression) {
     173            super(progressMonitor, compression);
     174        }
     175
     176        @Override
     177        public List<Note> parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
     178            in = getInputStream(url, progressMonitor.createSubTaskMonitor(1, true));
     179            if (in == null) {
     180                return new ArrayList<Note>();
     181            }
     182            progressMonitor.subTask(tr("Downloading OSM notes..."));
     183            NoteReader reader = new NoteReader(compression.getUncompressedInputStream(in));
     184            return reader.parse();
     185        }
     186    }
    156187}
  • src/org/openstreetmap/josm/io/OsmServerReader.java

     
    1919
    2020import org.openstreetmap.josm.Main;
    2121import org.openstreetmap.josm.data.gpx.GpxData;
     22import org.openstreetmap.josm.data.notes.Note;
    2223import org.openstreetmap.josm.data.osm.DataSet;
    2324import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2425import org.openstreetmap.josm.tools.Utils;
     
    348349    public final boolean isGpxParsedProperly() {
    349350        return gpxParsedProperly;
    350351    }
     352
     353    /**
     354     * Downloads notes from the API, given API limit parameters
     355     *
     356     * @param noteLimit How many notes to download. Defaults to 1000 if not specified. API has a hard limit of 10000
     357     * @param daysClosed Return notes closed this many days in the past. -1 means all notes, ever. 0 means only unresolved notes.
     358     * @param progressMonitor Progress monitor for user feedback
     359     * @return List of notes returned by the API
     360     * @throws OsmTransferException if any errors happen
     361     */
     362    public List<Note> parseNotes(Integer noteLimit, Integer daysClosed, ProgressMonitor progressMonitor) throws OsmTransferException {
     363        return null;
     364    }
     365
     366    /**
     367     * Downloads notes from a given raw URL. The URL is assumed to be complete and no API limits are added
     368     *
     369     * @param progressMonitor
     370     * @return A list of notes parsed from the URL
     371     * @throws OsmTransferException
     372     */
     373    public List<Note> parseRawNotes(final ProgressMonitor progressMonitor) throws OsmTransferException {
     374        return null;
     375    }
     376
     377    /**
     378     * Download notes from a URL that contains a bzip2 compressed notes dump file
     379     * @param progressMonitor
     380     * @return A list of notes parsed from the URL
     381     * @throws OsmTransferException
     382     */
     383    public List<Note> parseRawNotesBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
     384        return null;
     385    }
    351386}