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.DepartureBean; import dk.thoerup.traininfo.DepartureEntry; import dk.thoerup.traininfo.util.AndroidTimeoutCache; import dk.thoerup.traininfo.util.DownloadUtil; import dk.thoerup.traininfo.util.XmlUtil; public class XmlDepartureProvider implements DepartureProvider { final static int CACHE_TIMEOUT = 60*1000; AndroidTimeoutCache departureCache = new AndroidTimeoutCache(CACHE_TIMEOUT); DepartureEntry tempDeparture; StringBuilder builder = new StringBuilder(512); @Override public DepartureBean lookupDepartures(int stationID, boolean arrival) { String key = "" + stationID + ":" + arrival; DepartureBean departures = departureCache.get(key); if (departures == null) { departures = lookupDeparturesWorker(stationID, arrival); if (departures != null) { departureCache.put(key, departures); } } else { Log.i("XmlDepartureProvider", "cache hit !!!"); } return departures; } private DepartureBean lookupDeparturesWorker(int stationID, boolean arrival) { try { int iArrival = arrival ? 1 : 0; String url = XmlUtil.SERVICE_BASE + "/DepartureServlet?format=xml&station=" + stationID + "&arrival=" + iArrival; Log.i("xmlurl",url); String doc = DownloadUtil.getContentString(url, 30000, "ISO-8859-1"); InputSource source = new InputSource( new StringReader(doc)); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); DepartureParser departureParser = new DepartureParser(); xr.setContentHandler(departureParser); xr.setErrorHandler(departureParser); xr.parse(source); return departureParser.getDepartures(); } catch (Exception e) { Log.e("XmlDepartureProvider", "looupFunction", e); return null; } } class DepartureParser extends DefaultHandler { private DepartureBean departures = new DepartureBean(); public DepartureBean getDepartures() { return departures; } // 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("train")) tempDeparture = new DepartureEntry(); builder.setLength(0); //reset StringBuilder } @Override public void endElement (String uri, String name, String qName) throws SAXException { if (name.equals("train")) { departures.entries.add( tempDeparture ); } else if (name.equals("time")) { tempDeparture.setTime(builder.toString().trim()); } else if (name.equals("updated")) { tempDeparture.setLastUpdate(builder.toString().trim()); } else if (name.equals("trainnumber")) { tempDeparture.setTrainNumber(builder.toString().trim()); } else if (name.equals("destination")) { tempDeparture.setDestination(builder.toString().trim()); } else if (name.equals("origin")) { tempDeparture.setOrigin(builder.toString().trim()); } else if (name.equals("location")) { tempDeparture.setLocation(builder.toString().trim()); } else if (name.equals("status")) { tempDeparture.setStatus(builder.toString().trim()); } else if (name.equals("note")) { tempDeparture.setNote(builder.toString().trim()); } else if (name.equals("type")) { tempDeparture.setType(builder.toString().trim()); } else if (name.equals("notification")) { departures.notifications.add( builder.toString().trim() ); } } } }