// License: GPL. Copyright 2007 by Immanuel Scholz and others
package org.openstreetmap.josm_server.io;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.io.BufferedReader;
import java.io.IOException;
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_server.gui.progress.ProgressMonitor;
/**
* GWT
*
* TODO
* cannot authenticate read request (requires explicit credentials)
*/
/**
* 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) {
throw new RuntimeException("not implemented");
// 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();
String encoding = activeConnection.getContentEncoding();
if (activeConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
String errorHeader = activeConnection.getHeaderField("Error");
StringBuilder errorBody = new StringBuilder();
try
{
InputStream i = FixEncoding(activeConnection.getErrorStream(), encoding);
if (i != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(i));
String s;
while((s = in.readLine()) != null) {
errorBody.append(s);
errorBody.append("\n");
}
}
}
catch(Exception e) {
errorBody.append(tr("Reading error text failed."));
}
throw new OsmApiException(activeConnection.getResponseCode(), errorHeader, errorBody.toString());
}
return FixEncoding(new ProgressInputStream(activeConnection, progressMonitor), encoding);
} catch(Exception e) {
if (e instanceof OsmTransferException)
throw (OsmTransferException)e;
else
throw new OsmTransferException(e);
}
} finally {
progressMonitor.invalidate();
}
}
private InputStream FixEncoding(InputStream stream, String encoding) throws IOException
{
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
stream = new GZIPInputStream(stream);
}
else if (encoding != null && encoding.equalsIgnoreCase("deflate")) {
stream = new InflaterInputStream(stream, new Inflater(true));
}
return stream;
}
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;
}
}