/[projects]/android/TrainInfoService/src/dk/thoerup/traininfoservice/banedk/DepartureFetcher.java
ViewVC logotype

Contents of /android/TrainInfoService/src/dk/thoerup/traininfoservice/banedk/DepartureFetcher.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 970 - (show annotations) (download)
Fri Jul 9 21:23:48 2010 UTC (13 years, 10 months ago) by torben
File size: 9635 byte(s)
Switch banedk fetchers to bane.dk's new site (http://trafikinfo.bane.dk/) ... this new site is some microsoft azure-based cloud thingie so hopefully it will have a better uptime/stability once we reach winter 
1 package dk.thoerup.traininfoservice.banedk;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.logging.Logger;
8
9 import com.gargoylesoftware.htmlunit.BrowserVersion;
10 import com.gargoylesoftware.htmlunit.WebClient;
11 import com.gargoylesoftware.htmlunit.html.DomNodeList;
12 import com.gargoylesoftware.htmlunit.html.HtmlElement;
13 import com.gargoylesoftware.htmlunit.html.HtmlPage;
14
15 import dk.thoerup.circuitbreaker.CircuitBreaker;
16 import dk.thoerup.circuitbreaker.CircuitBreakerManager;
17 import dk.thoerup.traininfoservice.StationBean;
18 import dk.thoerup.traininfoservice.StationDAO;
19 import dk.thoerup.traininfoservice.Statistics;
20
21 public class DepartureFetcher {
22
23 Logger logger = Logger.getLogger(DepartureFetcher.class.getName());
24
25 Map<String, List<DepartureBean>> cache;
26
27 StationDAO stationDao = new StationDAO();
28
29 private boolean useTempSite;
30
31 public DepartureFetcher(boolean tempSite, int cacheTimeout) {
32 useTempSite = tempSite;
33 cache = new TimeoutMap<String,List<DepartureBean>>(cacheTimeout);
34 }
35
36
37
38
39 public List<DepartureBean> cachedLookupDepartures(int stationID, boolean arrival) throws Exception {
40 final String key = "" + stationID + ":" + arrival;
41
42 List<DepartureBean> list = cache.get(key);
43
44
45 if (list == null) {
46 list = lookupDepartures(stationID,arrival);
47 cache.put(key, list);
48 } else {
49 Statistics.getInstance().incrementDepartureCacheHits();
50 logger.info("Departure: Cache hit " + key); //remove before production
51 }
52 return list;
53 }
54
55
56 public List<DepartureBean> lookupDepartures(int stationID, boolean arrival) throws Exception {
57 List<DepartureBean> departureList = new ArrayList<DepartureBean>();
58
59 StationBean station = stationDao.getById(stationID);
60
61 if (station.getRegional() != null) {
62 List<DepartureBean> list = lookupDepartures(station.getRegional(), "Fjerntog", arrival);
63 departureList.addAll(list);
64 }
65
66 if (station.getStrain() != null) {
67 List<DepartureBean> list = lookupDepartures(station.getStrain(), "S-Tog", arrival);
68 departureList.addAll(list);
69 }
70
71 Collections.sort( departureList );
72
73
74 return departureList;
75 }
76
77 public List<DepartureBean> lookupDepartures(String stationcode, String type, boolean arrival) throws Exception {
78 if (useTempSite == false) {
79 return lookupDeparturesNormalSite(stationcode, type, arrival);
80 } else {
81 return lookupDeparturesFromTemporarySite(stationcode, type);
82 }
83 }
84
85 public List<DepartureBean> lookupDeparturesNormalSite(String stationcode, String type, boolean arrival) throws Exception {
86
87 List<DepartureBean> departureList = new ArrayList<DepartureBean>();
88
89 final WebClient webClient = new WebClient( BrowserVersion.FIREFOX_3 );
90 webClient.setTimeout(2500);
91 webClient.setJavaScriptEnabled(false);
92
93 String arrivalDeparture = (arrival==false) ? "Afgang" : "Ankomst";
94
95 //String uri = "http://www.bane.dk/visStation.asp?ArtikelID=4275&W=" + type + "&S=" + stationcode;
96 String uri = "http://trafikinfo.bane.dk/Trafikinformation/AfgangAnkomst/" + arrivalDeparture + "/" + stationcode + "/" +type + "/UdvidetVisning";
97
98 logger.info("URI: " + uri);
99 HtmlunitInvocation wrapper = new HtmlunitInvocation(webClient, uri);
100 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
101
102 HtmlPage page = (HtmlPage) breaker.invoke(wrapper);
103
104 String tableName = arrival == false ? "afgangtabel" : "ankomsttabel";
105 HtmlElement table = page.getElementById(tableName);
106
107 if (table != null) {
108 DomNodeList<HtmlElement> tableRows = table.getElementsByTagName("tr");
109
110 for (HtmlElement currentRow : tableRows) {
111 String rowClass = currentRow.getAttribute("class");
112 if (rowClass != null && rowClass.toLowerCase().contains("station") ) {
113 DomNodeList<HtmlElement> fields = currentRow.getElementsByTagName("td");
114
115 DepartureBean departure = new DepartureBean();
116
117 String time = fields.get(0).asText();
118 if (time.equals(""))
119 time = "0:00"; //Bane.dk bug work-around
120 departure.setTime(time);
121
122 int updated = extractUpdated( fields.get(1) );
123 departure.setUpdated(updated);
124
125 String trainNumber = fields.get(2).asText();
126 if (type.equalsIgnoreCase("S-Tog")) //If it is S-train we need to extract the trainNumber
127 trainNumber = trainNumber + " " + extractTrainNumber(fields.get(2));
128 departure.setTrainNumber(trainNumber);
129
130 String destination = fields.get(3).asText();
131 departure.setDestination(destination);
132
133 String origin = fields.get(4).asText();
134 departure.setOrigin(origin);
135
136 String location = fields.get(5).asText();
137 departure.setLocation(location);
138
139 String status = fields.get(6).asText().trim();
140 departure.setStatus(status);
141
142 String note = extractNote( fields.get(7) );
143 departure.setNote(note);
144
145 departure.setType(type);
146
147 departureList.add(departure);
148 }
149 }
150 } else {
151 logger.warning("No departures found for station=" + stationcode + ", type=" + type);
152 }
153 webClient.closeAllWindows();
154
155 return departureList;
156 }
157
158 public List<DepartureBean> lookupDeparturesFromTemporarySite(String stationcode, String type) throws Exception {
159
160 List<DepartureBean> departureList = new ArrayList<DepartureBean>();
161
162 final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3);
163 webClient.setTimeout(2500);
164 webClient.setJavaScriptEnabled(false);
165
166
167 String uri = "http://bane.dk/lite/station.asp?w=" + type + "&s=" + stationcode;
168
169 HtmlunitInvocation wrapper = new HtmlunitInvocation(webClient, uri);
170 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
171
172 HtmlPage page = (HtmlPage) breaker.invoke(wrapper);
173
174 HtmlElement table = page.getElementById("traf_afgang");
175
176 if (table != null) {
177 DomNodeList<HtmlElement> tableRows = table.getElementsByTagName("tr");
178
179 boolean isFirst = true;
180
181 for (HtmlElement currentRow : tableRows) {
182 if (isFirst == true) { //skip table headers
183 isFirst = false;
184 continue;
185 }
186
187 DomNodeList<HtmlElement> fields = currentRow.getElementsByTagName("td");
188
189 DepartureBean departure = new DepartureBean();
190
191 String time = fields.get(0).asText().trim();
192
193 if (time.equals(""))
194 time = "0:00"; //Bane.dk bug work-around
195 departure.setTime(time);
196
197
198 String trainNumber = fields.get(1).asText();
199 departure.setTrainNumber(trainNumber);
200
201 String destination = fields.get(2).asText();
202 departure.setDestination(destination);
203
204 String origin = fields.get(3).asText();
205 departure.setOrigin(origin);
206
207 String status = fields.get(4).asText();
208 departure.setStatus(status);
209
210 String note = fields.get(5).asText();
211 departure.setNote(note);
212
213 departureList.add(departure);
214 }
215 } else {
216 logger.warning("No departures found for station=" + stationcode + ", type=" + type);
217 }
218 webClient.closeAllWindows();
219
220
221 return departureList;
222 }
223
224
225 private int extractUpdated(HtmlElement updatedTd) { //extract the digit (in this case: 4) from "media/trafikinfo/opdater4.gif"
226 int updated = -1;
227
228 DomNodeList<HtmlElement> updatedImgs = updatedTd.getElementsByTagName("img");
229 String updatedStr = updatedImgs.get(0).getAttribute("src");
230
231 if (updatedStr != null) {
232 for (int i=0; i<updatedStr.length(); i++) {
233 char c = updatedStr.charAt(i);
234 if ( Character.isDigit(c)) {
235 updated = Character.digit(c, 10);
236 break;
237 }
238 }
239 }
240 return updated;
241 }
242
243 private String extractNote(HtmlElement noteTd) {
244 String note = noteTd.asText().trim();
245
246 List<HtmlElement> elems = noteTd.getElementsByAttribute("span", "class", "bemtype");
247 if (elems.size() > 0 && note.charAt(note.length()-1) == 'i')
248 note = note.substring(0,note.length() -1 );
249
250 return note;
251 }
252
253 private String extractTrainNumber(HtmlElement trainTd) {
254 logger.info("Extract traininfo " + trainTd.toString() );
255 String number = "";
256 HtmlElement anchorElement = trainTd.getElementsByTagName("a").get(0);
257 String href = anchorElement.getAttribute("href");
258 String argstring = href.substring( href.indexOf('?') + 1);
259
260 String args[] = argstring.split("/");
261 number = args[args.length-1];
262
263 /*for (String arg : args) {
264 String pair[] = arg.split("="); // Key=pair[0], Value=pair[1]
265
266 if (pair[0].equalsIgnoreCase("TogNr"))
267 number = pair[1];
268 }*/
269
270
271 return number;
272 }
273
274 //test
275 /*
276 public static void main(String args[]) throws Exception {
277 DepartureFetcher f = new DepartureFetcher();
278 List<DepartureBean> deps = f.lookupDepartures("AR", "FJRN");
279 for(DepartureBean d : deps) {
280 System.out.println( d.getTime() + ";" + d.getUpdated() + ";" + d.getTrainNumber() + ";" +
281 d.getDestination() + ";" + d.getOrigin() + ";" + d.getLocation() + ";" + d.getStatus() + ";" + d.getNote() );
282 }
283
284 System.out.println("--------------------------");
285 }*/
286 }

  ViewVC Help
Powered by ViewVC 1.1.20