package dk.thoerup.traininfo.provider; import java.io.StringReader; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; import dk.thoerup.traininfo.util.AndroidTimeoutCache; import dk.thoerup.traininfo.util.DownloadUtil; import dk.thoerup.traininfo.util.XmlUtil; public class XmlMetroProvider implements MetroProvider { final int CACHE_TIMEOUT = 60000; AndroidTimeoutCache metroCache = new AndroidTimeoutCache(CACHE_TIMEOUT); @Override public MetroBean lookupMetroInfo(int stationID) { MetroBean metro = metroCache.get(stationID); if (metro == null) { metro = lookupMetroWorker(stationID); if (metro != null) { metroCache.put(stationID, metro); } } else { Log.i("XmlDepartureProvider", "cache hit !!!"); } return metro; } private MetroBean lookupMetroWorker(int stationID) { try { String url = XmlUtil.SERVICE_BASE + "/MetroServlet?station=" + stationID; Log.i("xmlurl",url); String doc = DownloadUtil.getContentString(url, 15000, "ISO-8859-1"); InputSource source = new InputSource( new StringReader(doc)); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); MetroParser metroParser = new MetroParser(); xr.setContentHandler(metroParser); xr.setErrorHandler(metroParser); xr.parse(source); return metroParser.getMetroDepartures(); } catch (Exception e) { Log.e("XmlMetroProvider", "lookupFunction", e); return null; } } class MetroParser extends DefaultHandler { StringBuilder builder = new StringBuilder(256); private MetroBean metro = new MetroBean(); MetroEntry tempEntry = new MetroEntry(); public MetroBean getMetroDepartures() { return metro; } // this can be called several times fore the same text-node if there are many chardata / lines @Override public void characters (char ch[], int start, int length) { builder.append(ch, start, length); } @Override public void startElement (String uri, String name, String qName, Attributes atts)throws SAXException { if (name.equalsIgnoreCase("entry")) tempEntry = new MetroEntry(); builder.setLength(0); //reset StringBuilder } @Override public void endElement (String uri, String name, String qName) throws SAXException { String str = builder.toString().trim(); if (name.equals("entry")) { metro.entries.add( tempEntry ); } else if (name.equals("head")) { metro.head = str; } else if (name.equals("operations")) { metro.operationInfo = str; } else if (name.equals("metro")) { tempEntry.metro = str; } else if (name.equals("destination")) { tempEntry.destination = str; } else if (name.equals("minutes")) { tempEntry.minutes = str; } else if (name.equals("plan")) { metro.plan = str; } } } }