mirror of
https://gitlab.com/oeffi/public-transport-enabler.git
synced 2025-07-13 16:20:34 +00:00
parse XML directly from input stream
git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@271 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
parent
8e19081ca9
commit
a3ad65eabe
3 changed files with 96 additions and 27 deletions
|
@ -19,7 +19,8 @@ package de.schildbach.pte;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.InputStream;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -54,20 +55,24 @@ import de.schildbach.pte.util.XmlPullUtil;
|
|||
*/
|
||||
public abstract class AbstractEfaProvider implements NetworkProvider
|
||||
{
|
||||
private static final String DEFAULT_ENCODING = "ISO-8859-1";
|
||||
|
||||
protected abstract String autocompleteUri(final CharSequence constraint);
|
||||
|
||||
public List<Location> autocompleteStations(final CharSequence constraint) throws IOException
|
||||
{
|
||||
final String uri = autocompleteUri(constraint);
|
||||
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
final CharSequence page = ParserUtils.scrape(uri);
|
||||
is = ParserUtils.scrapeInputStream(uri);
|
||||
|
||||
final List<Location> results = new ArrayList<Location>();
|
||||
|
||||
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
||||
final XmlPullParser pp = factory.newPullParser();
|
||||
pp.setInput(new StringReader(page.toString()));
|
||||
pp.setInput(is, DEFAULT_ENCODING);
|
||||
|
||||
// parse odv name elements
|
||||
XmlPullUtil.jumpToStartTag(pp, null, "itdOdv");
|
||||
|
@ -99,6 +104,15 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
{
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
catch (final SocketTimeoutException x)
|
||||
{
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Location processOdvNameElem(final XmlPullParser pp) throws XmlPullParserException, IOException
|
||||
|
@ -168,8 +182,6 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
return new Location(LocationType.STATION, id, lat, lon, name);
|
||||
}
|
||||
|
||||
private static final Pattern P_NEARBY_MESSAGES = Pattern.compile("(unsere Server zur Zeit ausgelastet)");
|
||||
|
||||
protected abstract String nearbyLatLonUri(int lat, int lon);
|
||||
|
||||
protected abstract String nearbyStationUri(String stationId);
|
||||
|
@ -185,16 +197,14 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
if (uri == null)
|
||||
throw new IllegalArgumentException("at least one of stationId or lat/lon must be given");
|
||||
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
final CharSequence page = ParserUtils.scrape(uri);
|
||||
|
||||
if (P_NEARBY_MESSAGES.matcher(page).find())
|
||||
return new NearbyStationsResult(uri, NearbyStationsResult.Status.SERVICE_DOWN);
|
||||
is = ParserUtils.scrapeInputStream(uri);
|
||||
|
||||
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
||||
final XmlPullParser pp = factory.newPullParser();
|
||||
pp.setInput(new StringReader(page.toString()));
|
||||
pp.setInput(is, DEFAULT_ENCODING);
|
||||
|
||||
XmlPullUtil.jumpToStartTag(pp, null, "itdOdvName");
|
||||
final String nameState = pp.getAttributeValue(null, "state");
|
||||
|
@ -274,6 +284,15 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
{
|
||||
return new NearbyStationsResult(uri, NearbyStationsResult.Status.SERVICE_DOWN);
|
||||
}
|
||||
catch (final SocketTimeoutException x)
|
||||
{
|
||||
return new NearbyStationsResult(uri, NearbyStationsResult.Status.SERVICE_DOWN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern P_LINE_IRE = Pattern.compile("IRE\\d+");
|
||||
|
@ -533,13 +552,14 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
|
||||
public QueryDeparturesResult queryDepartures(final String uri) throws IOException
|
||||
{
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
final CharSequence page = ParserUtils.scrape(uri);
|
||||
is = ParserUtils.scrapeInputStream(uri);
|
||||
|
||||
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
||||
final XmlPullParser pp = factory.newPullParser();
|
||||
pp.setInput(new StringReader(page.toString()));
|
||||
pp.setInput(is, DEFAULT_ENCODING);
|
||||
|
||||
XmlPullUtil.jumpToStartTag(pp, null, "itdOdvName");
|
||||
final String nameState = pp.getAttributeValue(null, "state");
|
||||
|
@ -602,6 +622,15 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
{
|
||||
return new QueryDeparturesResult(uri, QueryDeparturesResult.Status.SERVICE_DOWN);
|
||||
}
|
||||
catch (final SocketTimeoutException x)
|
||||
{
|
||||
return new QueryDeparturesResult(uri, QueryDeparturesResult.Status.SERVICE_DOWN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void processItdDateTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
|
||||
|
@ -654,25 +683,49 @@ public abstract class AbstractEfaProvider implements NetworkProvider
|
|||
{
|
||||
final String uri = connectionsQueryUri(from, via, to, date, dep, products, walkSpeed) + "&sessionID=0";
|
||||
|
||||
final CharSequence page = ParserUtils.scrape(uri);
|
||||
|
||||
return queryConnections(uri, page);
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
is = ParserUtils.scrapeInputStream(uri);
|
||||
return queryConnections(uri, is);
|
||||
}
|
||||
catch (final SocketTimeoutException x)
|
||||
{
|
||||
return new QueryConnectionsResult(QueryConnectionsResult.Status.SERVICE_DOWN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
public QueryConnectionsResult queryMoreConnections(final String uri) throws IOException
|
||||
{
|
||||
final CharSequence page = ParserUtils.scrape(uri);
|
||||
|
||||
return queryConnections(uri, page);
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
is = ParserUtils.scrapeInputStream(uri);
|
||||
return queryConnections(uri, is);
|
||||
}
|
||||
catch (final SocketTimeoutException x)
|
||||
{
|
||||
return new QueryConnectionsResult(QueryConnectionsResult.Status.SERVICE_DOWN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private QueryConnectionsResult queryConnections(final String uri, final CharSequence page) throws IOException
|
||||
private QueryConnectionsResult queryConnections(final String uri, final InputStream is) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
||||
final XmlPullParser pp = factory.newPullParser();
|
||||
pp.setInput(new StringReader(page.toString()));
|
||||
pp.setInput(is, DEFAULT_ENCODING);
|
||||
|
||||
if (!XmlPullUtil.jumpToStartTag(pp, null, "itdRequest"))
|
||||
throw new IllegalStateException("cannot find <itdRequest />");
|
||||
|
|
|
@ -27,7 +27,7 @@ public final class QueryConnectionsResult implements Serializable
|
|||
{
|
||||
public enum Status
|
||||
{
|
||||
OK, AMBIGUOUS, TOO_CLOSE, NO_CONNECTIONS, INVALID_DATE;
|
||||
OK, AMBIGUOUS, TOO_CLOSE, NO_CONNECTIONS, INVALID_DATE, SERVICE_DOWN;
|
||||
}
|
||||
|
||||
public static final QueryConnectionsResult TOO_CLOSE = new QueryConnectionsResult(Status.TOO_CLOSE);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package de.schildbach.pte.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
|
@ -55,19 +56,19 @@ public final class ParserUtils
|
|||
stateCookie = null;
|
||||
}
|
||||
|
||||
public static CharSequence scrape(final String url) throws IOException
|
||||
public static final CharSequence scrape(final String url) throws IOException
|
||||
{
|
||||
return scrape(url, false, null, null, false);
|
||||
}
|
||||
|
||||
public static CharSequence scrape(final String url, final boolean isPost, final String request, String encoding, final boolean cookieHandling)
|
||||
throws IOException
|
||||
public static final CharSequence scrape(final String url, final boolean isPost, final String request, String encoding,
|
||||
final boolean cookieHandling) throws IOException
|
||||
{
|
||||
return scrape(url, isPost, request, encoding, cookieHandling, 3);
|
||||
}
|
||||
|
||||
public static CharSequence scrape(final String url, final boolean isPost, final String request, String encoding, final boolean cookieHandling,
|
||||
int tries) throws IOException
|
||||
public static final CharSequence scrape(final String url, final boolean isPost, final String request, String encoding,
|
||||
final boolean cookieHandling, int tries) throws IOException
|
||||
{
|
||||
if (encoding == null)
|
||||
encoding = SCRAPE_DEFAULT_ENCODING;
|
||||
|
@ -149,7 +150,7 @@ public final class ParserUtils
|
|||
}
|
||||
}
|
||||
|
||||
private static long copy(final Reader reader, final StringBuilder builder) throws IOException
|
||||
private static final long copy(final Reader reader, final StringBuilder builder) throws IOException
|
||||
{
|
||||
final char[] buffer = new char[SCRAPE_INITIAL_CAPACITY];
|
||||
long count = 0;
|
||||
|
@ -162,6 +163,21 @@ public final class ParserUtils
|
|||
return count;
|
||||
}
|
||||
|
||||
public static final InputStream scrapeInputStream(final String url) throws IOException
|
||||
{
|
||||
final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(false);
|
||||
connection.setConnectTimeout(SCRAPE_CONNECT_TIMEOUT);
|
||||
connection.setReadTimeout(SCRAPE_READ_TIMEOUT);
|
||||
connection.addRequestProperty("User-Agent", SCRAPE_USER_AGENT);
|
||||
// workaround to disable Vodafone compression
|
||||
connection.addRequestProperty("Cache-Control", "no-cache");
|
||||
|
||||
return connection.getInputStream();
|
||||
}
|
||||
|
||||
private static final Pattern P_ENTITY = Pattern.compile("&(?:#(x[\\da-f]+|\\d+)|(amp|quot|apos));");
|
||||
|
||||
public static String resolveEntities(final CharSequence str)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue