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