package com.papagiannis.tuberun.fetchers;
import java.io.StringReader;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import android.os.AsyncTask;
import android.util.Log;
public class StationStatusesFetcher extends Fetcher {
private static final long serialVersionUID = 1L;
private final String URL = "http://cloud.tfl.gov.uk/TrackerNet/StationStatus/IncidentsOnly";
private final String URLALL = "http://cloud.tfl.gov.uk/TrackerNet/StationStatus";
private String url = URL;
private HashMap<String, String> result = new HashMap<String, String>();
private Date resultTime = null;
private boolean isRecent() {
return resultTime != null
&& new Date().getTime() - resultTime.getTime() < 120 * 1000; // 2min
}
public static StationStatusesFetcher fetcherNowSigleton;
public StationStatusesFetcher() {
// setAll(true);
}
public static StationStatusesFetcher getInstance() {
return create();
}
private static StationStatusesFetcher create() {
if (fetcherNowSigleton == null) {
fetcherNowSigleton = new StationStatusesFetcher();
}
return fetcherNowSigleton;
}
public StationStatusesFetcher setAll(boolean forAll) {
url = (forAll) ? URLALL : URL;
return this;
}
protected AtomicBoolean isFirst = new AtomicBoolean(true);
protected transient RequestTask task = null;
public void update() {
boolean first = isFirst.compareAndSet(true, false);
if (!first)
return; // only one at a time
if (isRecent()) {
notifyClients();
isFirst.set(true);
return;
}
task = new RequestTask(new HttpCallback() {
public void onReturn(String s) {
getStatusesCallBack(s);
}
});
task.execute(url);
}
protected void getStatusesCallBack(String reply) {
try {
if (reply != null && reply.length() > 10) {
AsyncTask<String, Integer, HashMap<String, String>> decodeTask = new AsyncTask<String, Integer, HashMap<String, String>>() {
@Override
protected HashMap<String, String> doInBackground(
String... params) {
HashMap<String, String> res = new HashMap<String, String>();
int i = params[0].indexOf('<');
if (i>0) params[0]=params[0].substring(i);
parseXMLResponse(params[0], res);
return res;
}
@Override
protected void onPostExecute(HashMap<String, String> res) {
result=res;
resultTime=new Date();
notifyClients();
isFirst.set(true);
}
};
decodeTask.execute(reply);
}
} catch (Exception e) {
Log.w(getClass().toString(), e);
} finally {
notifyClients();
isFirst.set(true);
}
}
private void parseXMLResponse(String response,
HashMap<String, String> res) {
try {
// android.os.Debug.waitForDebugger();
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(new InputSource(new StringReader(
response)));
NodeList list = dom.getElementsByTagName("StationStatus");
for (int i = 0; i < list.getLength(); i++) {
Node status = list.item(i);
NodeList children = status.getChildNodes();
String name="";
String statusDetails=status.getAttributes().getNamedItem("StatusDetails").getNodeValue();
if (children.getLength()>2 ) {
for (int j = 0; j < children.getLength(); j++) {
Node child=children.item(j);
if (child.getNodeName().equals("Station")) {
name=child.getAttributes().getNamedItem("Name").getNodeValue();
}
if (child.getNodeName().equals("Status")) {
statusDetails=child.getAttributes().getNamedItem("Description").getNodeValue()
+ "\n" +statusDetails;
}
}
}
if (name.length()>0) res.put(name, statusDetails);
}
} catch (Exception e) {
Log.w(getClass().toString(), e);
}
}
@Override
public void abort() {
isFirst.set(true);
if (task != null)
task.cancel(true);
}
@Override
public Date getUpdateTime() {
return (resultTime != null) ? resultTime : new Date();
}
public boolean hasStatus(String stationName) {
return result.containsKey(stationName);
}
public String getStatus(String stationName) {
if (result.containsKey(stationName))
return result.get(stationName);
else
return "";
}
}