// License: GPL. Copyright 2007 by Immanuel Scholz and others package org.openstreetmap.josm.io; import static org.openstreetmap.josm.tools.I18n.tr; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.gui.progress.ProgressMonitor; /** * This DataReader reads directly from the REST API of the osm server. * * It supports plain text transfer as well as gzip or deflate encoded transfers; * if compressed transfers are unwanted, set property osm-server.use-compression * to false. * * @author imi */ public abstract class OsmServerReader extends OsmConnection { @SuppressWarnings("unused") static private final Logger logger = Logger.getLogger(OsmServerReader.class.getName()); private OsmApi api = OsmApi.getOsmApi(); private boolean doAuthenticate = false; /** * Open a connection to the given url and return a reader on the input stream * from that connection. In case of user cancel, return <code>null</code>. * @param urlStr The exact url to connect to. * @param pleaseWaitDlg * @return An reader reading the input stream (servers answer) or <code>null</code>. */ protected InputStream getInputStream(String urlStr, ProgressMonitor progressMonitor) throws OsmTransferException { try { api.initialize(progressMonitor); urlStr = api.getBaseUrl() + urlStr; return getInputStreamRaw(urlStr, progressMonitor); } finally { progressMonitor.invalidate(); } } protected InputStream getInputStreamRaw(String urlStr, ProgressMonitor progressMonitor) throws OsmTransferException { try { URL url = null; try { url = new URL(urlStr.replace(" ", "%20")); } catch(MalformedURLException e) { throw new OsmTransferException(e); } try { activeConnection = (HttpURLConnection)url.openConnection(); } catch(Exception e) { throw new OsmTransferException(tr("Failed to open connection to API {0}.", url.toExternalForm()), e); } if (cancel) { activeConnection.disconnect(); return null; } if (doAuthenticate) { addAuth(activeConnection); } if (cancel) throw new OsmTransferCancelledException(); if (Main.pref.getBoolean("osm-server.use-compression", true)) { activeConnection.setRequestProperty("Accept-Encoding", "gzip, deflate"); } activeConnection.setConnectTimeout(15000); try { System.out.println("GET " + url); activeConnection.connect(); } catch (Exception e) { e.printStackTrace(); throw new OsmTransferException(tr("Could not connect to the OSM server. Please check your internet connection."), e); } try { if (activeConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) throw new OsmApiException(HttpURLConnection.HTTP_UNAUTHORIZED,null,null); if (activeConnection.getResponseCode() == HttpURLConnection.HTTP_PROXY_AUTH) throw new OsmTransferCancelledException(); if (activeConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { String errorHeader = activeConnection.getHeaderField("Error"); InputStream i = null; i = activeConnection.getErrorStream(); StringBuilder errorBody = new StringBuilder(); if (i != null) { BufferedReader in = new BufferedReader(new InputStreamReader(i)); String s; while((s = in.readLine()) != null) { errorBody.append(s); errorBody.append("\n"); } } throw new OsmApiException(activeConnection.getResponseCode(), errorHeader, errorBody.toString()); } String encoding = activeConnection.getContentEncoding(); InputStream inputStream = new ProgressInputStream(activeConnection, progressMonitor); if (encoding != null && encoding.equalsIgnoreCase("gzip")) { inputStream = new GZIPInputStream(inputStream); } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { inputStream = new InflaterInputStream(inputStream, new Inflater(true)); } return inputStream; } catch(Exception e) { if (e instanceof OsmTransferException) throw (OsmTransferException)e; else throw new OsmTransferException(e); } } finally { progressMonitor.invalidate(); } } public abstract DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException; /** * Returns true if this reader is adding authentication credentials to the read * request sent to the server. * * @return true if this reader is adding authentication credentials to the read * request sent to the server */ public boolean isDoAuthenticate() { return doAuthenticate; } /** * Sets whether this reader adds authentication credentials to the read * request sent to the server. * * @param doAuthenticate true if this reader adds authentication credentials to the read * request sent to the server */ public void setDoAuthenticate(boolean doAuthenticate) { this.doAuthenticate = doAuthenticate; } }