1 |
package dk.thoerup.traininfo.provider; |
2 |
|
3 |
import java.io.StringReader; |
4 |
|
5 |
import javax.xml.parsers.SAXParser; |
6 |
import javax.xml.parsers.SAXParserFactory; |
7 |
|
8 |
import org.xml.sax.Attributes; |
9 |
import org.xml.sax.InputSource; |
10 |
import org.xml.sax.SAXException; |
11 |
import org.xml.sax.XMLReader; |
12 |
import org.xml.sax.helpers.DefaultHandler; |
13 |
|
14 |
import android.util.Log; |
15 |
|
16 |
import dk.thoerup.traininfo.util.AndroidTimeoutCache; |
17 |
import dk.thoerup.traininfo.util.DownloadUtil; |
18 |
import dk.thoerup.traininfo.util.XmlUtil; |
19 |
|
20 |
public class XmlMetroProvider implements MetroProvider { |
21 |
|
22 |
final int CACHE_TIMEOUT = 60000; |
23 |
|
24 |
AndroidTimeoutCache<Integer,MetroBean> metroCache = new AndroidTimeoutCache<Integer,MetroBean>(CACHE_TIMEOUT); |
25 |
|
26 |
|
27 |
@Override |
28 |
public MetroBean lookupMetroInfo(int stationID) { |
29 |
|
30 |
MetroBean metro = metroCache.get(stationID); |
31 |
|
32 |
if (metro == null) { |
33 |
metro = lookupMetroWorker(stationID); |
34 |
|
35 |
if (metro != null) { |
36 |
metroCache.put(stationID, metro); |
37 |
} |
38 |
|
39 |
} else { |
40 |
Log.i("XmlDepartureProvider", "cache hit !!!"); |
41 |
} |
42 |
|
43 |
return metro; |
44 |
} |
45 |
|
46 |
|
47 |
private MetroBean lookupMetroWorker(int stationID) { |
48 |
|
49 |
try |
50 |
{ |
51 |
String url = XmlUtil.SERVICE_BASE + "/MetroServlet?station=" + stationID; |
52 |
Log.i("xmlurl",url); |
53 |
String doc = DownloadUtil.getContentString(url, 15000, "ISO-8859-1"); |
54 |
|
55 |
InputSource source = new InputSource( new StringReader(doc)); |
56 |
|
57 |
SAXParserFactory spf = SAXParserFactory.newInstance(); |
58 |
SAXParser sp = spf.newSAXParser(); |
59 |
XMLReader xr = sp.getXMLReader(); |
60 |
|
61 |
MetroParser metroParser = new MetroParser(); |
62 |
xr.setContentHandler(metroParser); |
63 |
xr.setErrorHandler(metroParser); |
64 |
xr.parse(source); |
65 |
|
66 |
return metroParser.getMetroDepartures(); |
67 |
|
68 |
} catch (Exception e) { |
69 |
Log.e("XmlMetroProvider", "lookupFunction", e); |
70 |
return null; |
71 |
} |
72 |
} |
73 |
|
74 |
|
75 |
class MetroParser extends DefaultHandler { |
76 |
|
77 |
StringBuilder builder = new StringBuilder(256); |
78 |
private MetroBean metro = new MetroBean(); |
79 |
|
80 |
MetroEntry tempEntry = new MetroEntry(); |
81 |
|
82 |
public MetroBean getMetroDepartures() { |
83 |
return metro; |
84 |
} |
85 |
|
86 |
|
87 |
// this can be called several times fore the same text-node if there are many chardata / lines |
88 |
@Override |
89 |
public void characters (char ch[], int start, int length) |
90 |
{ |
91 |
builder.append(ch, start, length); |
92 |
} |
93 |
|
94 |
@Override |
95 |
public void startElement (String uri, String name, String qName, Attributes atts)throws SAXException |
96 |
{ |
97 |
if (name.equalsIgnoreCase("entry")) |
98 |
tempEntry = new MetroEntry(); |
99 |
|
100 |
builder.setLength(0); //reset StringBuilder |
101 |
} |
102 |
|
103 |
@Override |
104 |
public void endElement (String uri, String name, String qName) throws SAXException |
105 |
{ |
106 |
String str = builder.toString().trim(); |
107 |
|
108 |
if (name.equals("entry")) { |
109 |
metro.entries.add( tempEntry ); |
110 |
} else if (name.equals("head")) { |
111 |
metro.head = str; |
112 |
} else if (name.equals("operations")) { |
113 |
metro.operationInfo = str; |
114 |
} else if (name.equals("metro")) { |
115 |
tempEntry.metro = str; |
116 |
} else if (name.equals("destination")) { |
117 |
tempEntry.destination = str; |
118 |
} else if (name.equals("minutes")) { |
119 |
tempEntry.minutes = str; |
120 |
} else if (name.equals("plan")) { |
121 |
metro.plan = str; |
122 |
} |
123 |
} |
124 |
} |
125 |
|
126 |
} |