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        protected final InputStream getUncompressedInputStream() throws IOException {
043            switch (compression) {
044                case BZIP2: return FileImporter.getBZip2InputStream(in);
045                case GZIP: return FileImporter.getGZipInputStream(in);
046                case NONE: 
047                default: return in;
048            }
049        }
050        
051        public abstract T parse() throws OsmTransferException, IllegalDataException, IOException, SAXException;
052    }
053
054    protected final <T> T doParse(Parser<T> parser, final ProgressMonitor progressMonitor) throws OsmTransferException {
055        progressMonitor.beginTask(tr("Contacting Server...", 10));
056        try {
057            return parser.parse();
058        } catch(OsmTransferException e) {
059            throw e;
060        } catch (Exception e) {
061            if (cancel)
062                return null;
063            throw new OsmTransferException(e);
064        } finally {
065            progressMonitor.finishTask();
066            activeConnection = null;
067            Utils.close(parser.in);
068            parser.in = null;
069        }
070    }
071
072    @Override
073    public DataSet parseOsm(final ProgressMonitor progressMonitor) throws OsmTransferException {
074        return doParse(new OsmParser(progressMonitor, Compression.NONE), progressMonitor);
075    }
076
077    @Override
078    public DataSet parseOsmBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
079        return doParse(new OsmParser(progressMonitor, Compression.BZIP2), progressMonitor);
080    }
081
082    @Override
083    public DataSet parseOsmGzip(final ProgressMonitor progressMonitor) throws OsmTransferException {
084        return doParse(new OsmParser(progressMonitor, Compression.GZIP), progressMonitor);
085    }
086
087    @Override
088    public DataSet parseOsmChange(final ProgressMonitor progressMonitor) throws OsmTransferException {
089        return doParse(new OsmChangeParser(progressMonitor, Compression.NONE), progressMonitor);
090    }
091
092    @Override
093    public DataSet parseOsmChangeBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
094        return doParse(new OsmChangeParser(progressMonitor, Compression.BZIP2), progressMonitor);
095    }
096
097    @Override
098    public DataSet parseOsmChangeGzip(final ProgressMonitor progressMonitor) throws OsmTransferException {
099        return doParse(new OsmChangeParser(progressMonitor, Compression.GZIP), progressMonitor);
100    }
101
102    @Override
103    public GpxData parseRawGps(final ProgressMonitor progressMonitor) throws OsmTransferException {
104        return doParse(new GpxParser(progressMonitor, Compression.NONE), progressMonitor);
105    }
106
107    @Override
108    public GpxData parseRawGpsBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
109        return doParse(new GpxParser(progressMonitor, Compression.BZIP2), progressMonitor);
110    }
111
112    protected class OsmParser extends Parser<DataSet> {
113        protected OsmParser(ProgressMonitor progressMonitor, Compression compression) {
114            super(progressMonitor, compression);
115        }
116
117        @Override
118        public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
119            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
120            if (in == null)
121                return null;
122            progressMonitor.subTask(tr("Downloading OSM data..."));
123            return OsmReader.parseDataSet(getUncompressedInputStream(), progressMonitor.createSubTaskMonitor(1, false));
124        }
125    }
126    
127    protected class OsmChangeParser extends Parser<DataSet> {
128        protected OsmChangeParser(ProgressMonitor progressMonitor, Compression compression) {
129            super(progressMonitor, compression);
130        }
131
132        @Override
133        public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
134            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
135            if (in == null)
136                return null;
137            progressMonitor.subTask(tr("Downloading OSM data..."));
138            return OsmChangeReader.parseDataSet(getUncompressedInputStream(), progressMonitor.createSubTaskMonitor(1, false));
139        }
140    }
141
142    protected class GpxParser extends Parser<GpxData> {
143        protected GpxParser(ProgressMonitor progressMonitor, Compression compression) {
144            super(progressMonitor, compression);
145        }
146        
147        @Override
148        public GpxData parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
149            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(1, true));
150            if (in == null)
151                return null;
152            progressMonitor.subTask(tr("Downloading OSM data..."));
153            GpxReader reader = new GpxReader(getUncompressedInputStream());
154            gpxParsedProperly = reader.parse(false);
155            GpxData result = reader.getGpxData();
156            result.fromServer = DownloadGpsTask.isFromServer(url);
157            return result;
158        }
159    }
160}