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

  ViewVC Help
Powered by ViewVC 1.1.20