source: josm/trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java@ 13496

Last change on this file since 13496 was 13352, checked in by Don-vip, 6 years ago

fix #15816 - full XZ support

  • Property svn:eol-style set to native
File size: 9.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.Collections;
9import java.util.List;
10
11import org.openstreetmap.josm.data.gpx.GpxData;
12import org.openstreetmap.josm.data.notes.Note;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.gui.progress.ProgressMonitor;
15import org.openstreetmap.josm.tools.Utils;
16import org.xml.sax.SAXException;
17
18/**
19 * Read content from OSM server for a given URL
20 * @since 1146
21 */
22public class OsmServerLocationReader extends OsmServerReader {
23
24 // CHECKSTYLE.OFF: MethodParamPad
25 // CHECKSTYLE.OFF: SingleSpaceSeparator
26
27 /**
28 * Patterns for OSM data download URLs.
29 * @since 12679
30 */
31 public enum OsmUrlPattern {
32 OSM_API_URL ("https?://.*/api/0.6/(map|nodes?|ways?|relations?|\\*).*"),
33 OVERPASS_API_URL ("https?://.*/interpreter\\?data=.*"),
34 OVERPASS_API_XAPI_URL ("https?://.*/xapi(\\?.*\\[@meta\\]|_meta\\?).*"),
35 EXTERNAL_OSM_FILE ("https?://.*/.*\\.osm");
36
37 private final String urlPattern;
38
39 OsmUrlPattern(String urlPattern) {
40 this.urlPattern = urlPattern;
41 }
42
43 /**
44 * Returns the URL pattern.
45 * @return the URL pattern
46 */
47 public String pattern() {
48 return urlPattern;
49 }
50 }
51
52 /**
53 * Patterns for GPX download URLs.
54 * @since 12679
55 */
56 public enum GpxUrlPattern {
57 TRACE_ID ("https?://.*(osm|openstreetmap).org/trace/\\p{Digit}+/data"),
58 USER_TRACE_ID("https?://.*(osm|openstreetmap).org/user/[^/]+/traces/(\\p{Digit}+)"),
59 EDIT_TRACE_ID("https?://.*(osm|openstreetmap).org/edit/?\\?gpx=(\\p{Digit}+)(#.*)?"),
60
61 TRACKPOINTS_BBOX("https?://.*/api/0.6/trackpoints\\?bbox=.*,.*,.*,.*"),
62
63 EXTERNAL_GPX_SCRIPT("https?://.*exportgpx.*"),
64 EXTERNAL_GPX_FILE ("https?://.*/(.*\\.gpx)");
65
66 private final String urlPattern;
67
68 GpxUrlPattern(String urlPattern) {
69 this.urlPattern = urlPattern;
70 }
71
72 /**
73 * Returns the URL pattern.
74 * @return the URL pattern
75 */
76 public String pattern() {
77 return urlPattern;
78 }
79 }
80
81 /**
82 * Patterns for Note download URLs.
83 * @since 12679
84 */
85 public enum NoteUrlPattern {
86 /** URL of OSM API Notes endpoint */
87 API_URL ("https?://.*/api/0.6/notes.*"),
88 /** URL of OSM API Notes compressed dump file */
89 DUMP_FILE("https?://.*/(.*\\.osn(\\.(gz|xz|bz2?|zip))?)");
90
91 private final String urlPattern;
92
93 NoteUrlPattern(String urlPattern) {
94 this.urlPattern = urlPattern;
95 }
96
97 /**
98 * Returns the URL pattern.
99 * @return the URL pattern
100 */
101 public String pattern() {
102 return urlPattern;
103 }
104 }
105
106 // CHECKSTYLE.ON: SingleSpaceSeparator
107 // CHECKSTYLE.ON: MethodParamPad
108
109 protected final String url;
110
111 /**
112 * Constructs a new {@code OsmServerLocationReader}.
113 * @param url The URL to fetch
114 */
115 public OsmServerLocationReader(String url) {
116 this.url = url;
117 }
118
119 protected abstract static class Parser<T> {
120 protected final ProgressMonitor progressMonitor;
121 protected final Compression compression;
122 protected InputStream in;
123
124 public Parser(ProgressMonitor progressMonitor, Compression compression) {
125 this.progressMonitor = progressMonitor;
126 this.compression = compression;
127 }
128
129 public abstract T parse() throws OsmTransferException, IllegalDataException, IOException, SAXException;
130 }
131
132 protected final <T> T doParse(Parser<T> parser, final ProgressMonitor progressMonitor) throws OsmTransferException {
133 progressMonitor.beginTask(tr("Contacting Server...", 10));
134 try {
135 return parser.parse();
136 } catch (OsmTransferException e) {
137 throw e;
138 } catch (IOException | SAXException | IllegalDataException e) {
139 if (cancel)
140 return null;
141 throw new OsmTransferException(e);
142 } finally {
143 progressMonitor.finishTask();
144 activeConnection = null;
145 Utils.close(parser.in);
146 parser.in = null;
147 }
148 }
149
150 @Override
151 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
152 return parseOsm(progressMonitor, Compression.NONE);
153 }
154
155 @Override
156 public DataSet parseOsm(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
157 return doParse(new OsmParser(progressMonitor, compression), progressMonitor);
158 }
159
160 @Override
161 public DataSet parseOsmChange(ProgressMonitor progressMonitor) throws OsmTransferException {
162 return parseOsmChange(progressMonitor, Compression.NONE);
163 }
164
165 @Override
166 public DataSet parseOsmChange(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
167 return doParse(new OsmChangeParser(progressMonitor, compression), progressMonitor);
168 }
169
170 @Override
171 public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
172 return parseRawGps(progressMonitor, Compression.NONE);
173 }
174
175 @Override
176 public GpxData parseRawGps(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
177 return doParse(new GpxParser(progressMonitor, compression), progressMonitor);
178 }
179
180 @Override
181 public List<Note> parseRawNotes(ProgressMonitor progressMonitor) throws OsmTransferException {
182 return parseRawNotes(progressMonitor, Compression.NONE);
183 }
184
185 @Override
186 public List<Note> parseRawNotes(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
187 return doParse(new NoteParser(progressMonitor, compression), progressMonitor);
188 }
189
190 protected class OsmParser extends Parser<DataSet> {
191 protected OsmParser(ProgressMonitor progressMonitor, Compression compression) {
192 super(progressMonitor, compression);
193 }
194
195 @Override
196 public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
197 in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
198 if (in == null)
199 return null;
200 progressMonitor.subTask(tr("Downloading OSM data..."));
201 return OsmReader.parseDataSet(compression.getUncompressedInputStream(in), progressMonitor.createSubTaskMonitor(1, false));
202 }
203 }
204
205 protected class OsmChangeParser extends Parser<DataSet> {
206 protected OsmChangeParser(ProgressMonitor progressMonitor, Compression compression) {
207 super(progressMonitor, compression);
208 }
209
210 @Override
211 public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
212 in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
213 if (in == null)
214 return null;
215 progressMonitor.subTask(tr("Downloading OSM data..."));
216 return OsmChangeReader.parseDataSet(compression.getUncompressedInputStream(in), progressMonitor.createSubTaskMonitor(1, false));
217 }
218 }
219
220 protected class GpxParser extends Parser<GpxData> {
221 protected GpxParser(ProgressMonitor progressMonitor, Compression compression) {
222 super(progressMonitor, compression);
223 }
224
225 @Override
226 public GpxData parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
227 in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(1, true), null, true);
228 if (in == null)
229 return null;
230 progressMonitor.subTask(tr("Downloading OSM data..."));
231 GpxReader reader = new GpxReader(compression.getUncompressedInputStream(in));
232 gpxParsedProperly = reader.parse(false);
233 GpxData result = reader.getGpxData();
234 result.fromServer = isGpxFromServer(url);
235 return result;
236 }
237 }
238
239 protected class NoteParser extends Parser<List<Note>> {
240
241 public NoteParser(ProgressMonitor progressMonitor, Compression compression) {
242 super(progressMonitor, compression);
243 }
244
245 @Override
246 public List<Note> parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
247 in = getInputStream(url, progressMonitor.createSubTaskMonitor(1, true));
248 if (in == null) {
249 return Collections.emptyList();
250 }
251 progressMonitor.subTask(tr("Downloading OSM notes..."));
252 NoteReader reader = new NoteReader(compression.getUncompressedInputStream(in));
253 return reader.parse();
254 }
255 }
256
257 /**
258 * Determines if the given URL denotes an OSM gpx-related API call.
259 * @param url The url to check
260 * @return true if the url matches "Trace ID" API call or "Trackpoints bbox" API call, false otherwise
261 * @see GpxData#fromServer
262 * @since 12679
263 */
264 public static final boolean isGpxFromServer(String url) {
265 return url != null && (url.matches(GpxUrlPattern.TRACE_ID.pattern()) || url.matches(GpxUrlPattern.TRACKPOINTS_BBOX.pattern()));
266 }
267}
Note: See TracBrowser for help on using the repository browser.