001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.io.IOException;
007import java.io.InputStream;
008import java.util.ArrayList;
009import java.util.List;
010
011import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
012import org.openstreetmap.josm.data.gpx.GpxData;
013import org.openstreetmap.josm.data.notes.Note;
014import org.openstreetmap.josm.data.osm.DataSet;
015import org.openstreetmap.josm.gui.progress.ProgressMonitor;
016import org.openstreetmap.josm.tools.Utils;
017import org.xml.sax.SAXException;
018
019/**
020 * Read content from OSM server for a given URL
021 * @since 1146
022 */
023public class OsmServerLocationReader extends OsmServerReader {
024
025    protected final String url;
026
027    /**
028     * Constructs a new {@code OsmServerLocationReader}.
029     * @param url The URL to fetch
030     */
031    public OsmServerLocationReader(String url) {
032        this.url = url;
033    }
034
035    protected abstract class Parser<T> {
036        protected final ProgressMonitor progressMonitor;
037        protected final Compression compression;
038        protected InputStream in;
039
040        public Parser(ProgressMonitor progressMonitor, Compression compression) {
041            this.progressMonitor = progressMonitor;
042            this.compression = compression;
043        }
044
045        public abstract T parse() throws OsmTransferException, IllegalDataException, IOException, SAXException;
046    }
047
048    protected final <T> T doParse(Parser<T> parser, final ProgressMonitor progressMonitor) throws OsmTransferException {
049        progressMonitor.beginTask(tr("Contacting Server...", 10));
050        try {
051            return parser.parse();
052        } catch (OsmTransferException e) {
053            throw e;
054        } catch (Exception e) {
055            if (cancel)
056                return null;
057            throw new OsmTransferException(e);
058        } finally {
059            progressMonitor.finishTask();
060            activeConnection = null;
061            Utils.close(parser.in);
062            parser.in = null;
063        }
064    }
065
066    @Override
067    public DataSet parseOsm(final ProgressMonitor progressMonitor) throws OsmTransferException {
068        return doParse(new OsmParser(progressMonitor, Compression.NONE), progressMonitor);
069    }
070
071    @Override
072    public DataSet parseOsmBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
073        return doParse(new OsmParser(progressMonitor, Compression.BZIP2), progressMonitor);
074    }
075
076    @Override
077    public DataSet parseOsmGzip(final ProgressMonitor progressMonitor) throws OsmTransferException {
078        return doParse(new OsmParser(progressMonitor, Compression.GZIP), progressMonitor);
079    }
080
081    @Override
082    public DataSet parseOsmZip(final ProgressMonitor progressMonitor) throws OsmTransferException {
083        return doParse(new OsmParser(progressMonitor, Compression.ZIP), progressMonitor);
084    }
085
086    @Override
087    public DataSet parseOsmChange(final ProgressMonitor progressMonitor) throws OsmTransferException {
088        return doParse(new OsmChangeParser(progressMonitor, Compression.NONE), progressMonitor);
089    }
090
091    @Override
092    public DataSet parseOsmChangeBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
093        return doParse(new OsmChangeParser(progressMonitor, Compression.BZIP2), progressMonitor);
094    }
095
096    @Override
097    public DataSet parseOsmChangeGzip(final ProgressMonitor progressMonitor) throws OsmTransferException {
098        return doParse(new OsmChangeParser(progressMonitor, Compression.GZIP), progressMonitor);
099    }
100
101    @Override
102    public GpxData parseRawGps(final ProgressMonitor progressMonitor) throws OsmTransferException {
103        return doParse(new GpxParser(progressMonitor, Compression.NONE), progressMonitor);
104    }
105
106    @Override
107    public GpxData parseRawGpsBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
108        return doParse(new GpxParser(progressMonitor, Compression.BZIP2), progressMonitor);
109    }
110
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
121    protected class OsmParser extends Parser<DataSet> {
122        protected OsmParser(ProgressMonitor progressMonitor, Compression compression) {
123            super(progressMonitor, compression);
124        }
125
126        @Override
127        public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
128            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
129            if (in == null)
130                return null;
131            progressMonitor.subTask(tr("Downloading OSM data..."));
132            return OsmReader.parseDataSet(compression.getUncompressedInputStream(in), progressMonitor.createSubTaskMonitor(1, false));
133        }
134    }
135
136    protected class OsmChangeParser extends Parser<DataSet> {
137        protected OsmChangeParser(ProgressMonitor progressMonitor, Compression compression) {
138            super(progressMonitor, compression);
139        }
140
141        @Override
142        public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
143            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
144            if (in == null)
145                return null;
146            progressMonitor.subTask(tr("Downloading OSM data..."));
147            return OsmChangeReader.parseDataSet(compression.getUncompressedInputStream(in), progressMonitor.createSubTaskMonitor(1, false));
148        }
149    }
150
151    protected class GpxParser extends Parser<GpxData> {
152        protected GpxParser(ProgressMonitor progressMonitor, Compression compression) {
153            super(progressMonitor, compression);
154        }
155
156        @Override
157        public GpxData parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
158            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(1, true), null, true);
159            if (in == null)
160                return null;
161            progressMonitor.subTask(tr("Downloading OSM data..."));
162            GpxReader reader = new GpxReader(compression.getUncompressedInputStream(in));
163            gpxParsedProperly = reader.parse(false);
164            GpxData result = reader.getGpxData();
165            result.fromServer = DownloadGpsTask.isFromServer(url);
166            return result;
167        }
168    }
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    }
187}