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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 992 - (hide 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 torben 305 package dk.thoerup.traininfoservice.banedk;
2    
3 torben 978
4 torben 992 import java.net.URL;
5 torben 307 import java.util.Collections;
6 torben 428 import java.util.Map;
7 torben 348 import java.util.logging.Logger;
8 torben 305
9 torben 992 import org.jsoup.nodes.Document;
10     import org.jsoup.nodes.Element;
11     import org.jsoup.select.Elements;
12 torben 305
13 torben 468 import dk.thoerup.circuitbreaker.CircuitBreaker;
14     import dk.thoerup.circuitbreaker.CircuitBreakerManager;
15 torben 588 import dk.thoerup.traininfoservice.StationBean;
16     import dk.thoerup.traininfoservice.StationDAO;
17 torben 711 import dk.thoerup.traininfoservice.Statistics;
18 torben 307
19 torben 305 public class DepartureFetcher {
20 torben 348
21 torben 972 enum TrainType{
22     STOG,
23     REGIONAL
24     }
25    
26 torben 348 Logger logger = Logger.getLogger(DepartureFetcher.class.getName());
27 torben 387
28 torben 978 Map<String, DepartureBean> cache;
29 torben 387
30 torben 588 StationDAO stationDao = new StationDAO();
31    
32 torben 580 private boolean useTempSite;
33    
34 torben 584 public DepartureFetcher(boolean tempSite, int cacheTimeout) {
35 torben 580 useTempSite = tempSite;
36 torben 978 cache = new TimeoutMap<String,DepartureBean>(cacheTimeout);
37 torben 580 }
38    
39    
40 torben 307
41 torben 387
42 torben 978 public DepartureBean cachedLookupDepartures(int stationID, boolean arrival) throws Exception {
43 torben 829 final String key = "" + stationID + ":" + arrival;
44 torben 980
45 torben 978 DepartureBean departureBean = cache.get(key);
46 torben 308
47 torben 387
48 torben 978 if (departureBean == null) {
49     departureBean = lookupDepartures(stationID,arrival);
50     cache.put(key, departureBean);
51 torben 387 } else {
52 torben 711 Statistics.getInstance().incrementDepartureCacheHits();
53 torben 829 logger.info("Departure: Cache hit " + key); //remove before production
54 torben 387 }
55 torben 980 return departureBean;
56 torben 387 }
57    
58    
59 torben 978 public DepartureBean lookupDepartures(int stationID, boolean arrival) throws Exception {
60 torben 307
61 torben 978 DepartureBean departureBean = new DepartureBean();
62    
63 torben 588 StationBean station = stationDao.getById(stationID);
64 torben 307
65 torben 588 if (station.getRegional() != null) {
66 torben 978 DepartureBean tempBean = lookupDepartures(station.getRegional(), TrainType.REGIONAL, arrival);
67     departureBean.departureEntries.addAll( tempBean.departureEntries );
68     departureBean.notifications.addAll(tempBean.notifications);
69 torben 307 }
70    
71 torben 588 if (station.getStrain() != null) {
72 torben 978 DepartureBean tempBean = lookupDepartures(station.getStrain(), TrainType.STOG, arrival);
73     departureBean.departureEntries.addAll( tempBean.departureEntries );
74     departureBean.notifications.addAll(tempBean.notifications);
75 torben 588 }
76    
77 torben 978 Collections.sort( departureBean.departureEntries );
78 torben 588
79    
80 torben 978 return departureBean;
81 torben 305 }
82    
83 torben 978 public DepartureBean lookupDepartures(String stationcode, TrainType type, boolean arrival) throws Exception {
84 torben 580 if (useTempSite == false) {
85 torben 829 return lookupDeparturesNormalSite(stationcode, type, arrival);
86 torben 580 } else {
87 torben 972 //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 torben 580 }
91     }
92    
93 torben 972 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 torben 978 public DepartureBean lookupDeparturesNormalSite(String stationcode, TrainType type, boolean arrival) throws Exception {
105 torben 305
106 torben 978 DepartureBean departureBean = new DepartureBean();
107 torben 992
108 torben 970
109 torben 972 String typeString = getTypeString(type);
110 torben 970 String arrivalDeparture = (arrival==false) ? "Afgang" : "Ankomst";
111 torben 313
112 torben 970 //String uri = "http://www.bane.dk/visStation.asp?ArtikelID=4275&W=" + type + "&S=" + stationcode;
113 torben 972 String uri = "http://trafikinfo.bane.dk/Trafikinformation/AfgangAnkomst/" + arrivalDeparture + "/" + stationcode + "/" + typeString + "/UdvidetVisning";
114 torben 970
115 torben 992 //logger.info("URI: " + uri);
116     JsoupInvocation wrapper = new JsoupInvocation( new URL(uri), 2500);
117 torben 421 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
118 torben 305
119 torben 992 Document page = (Document) breaker.invoke(wrapper);
120 torben 305
121 torben 829 String tableName = arrival == false ? "afgangtabel" : "ankomsttabel";
122 torben 992 Element table = page.getElementById(tableName);
123 torben 829
124 torben 342 if (table != null) {
125 torben 992 Elements tableRows = table.getElementsByTag("tr");
126 torben 342
127 torben 992 for (Element currentRow : tableRows) {
128     String rowClass = currentRow.attr("class");
129 torben 342 if (rowClass != null && rowClass.toLowerCase().contains("station") ) {
130 torben 992 Elements fields = currentRow.getElementsByTag("td");
131 torben 342
132 torben 978 DepartureEntry departure = new DepartureEntry();
133 torben 342
134 torben 992 String time = fields.get(0).text();
135 torben 375 if (time.equals(""))
136     time = "0:00"; //Bane.dk bug work-around
137 torben 342 departure.setTime(time);
138    
139     int updated = extractUpdated( fields.get(1) );
140     departure.setUpdated(updated);
141    
142 torben 992 String trainNumber = fields.get(2).text();
143 torben 972 if (type == TrainType.STOG) //If it is S-train we need to extract the trainNumber
144 torben 349 trainNumber = trainNumber + " " + extractTrainNumber(fields.get(2));
145 torben 342 departure.setTrainNumber(trainNumber);
146    
147 torben 992 String destination = fields.get(3).text();
148 torben 342 departure.setDestination(destination);
149    
150 torben 992 String origin = fields.get(4).text();
151 torben 342 departure.setOrigin(origin);
152    
153 torben 992 String location = fields.get(5).text();
154 torben 342 departure.setLocation(location);
155    
156 torben 992 String status = fields.get(6).text().trim();
157 torben 342 departure.setStatus(status);
158    
159     String note = extractNote( fields.get(7) );
160     departure.setNote(note);
161    
162 torben 972 departure.setType(typeString);
163 torben 697
164 torben 978 departureBean.departureEntries.add( departure );
165 torben 342 }
166     }
167 torben 348 } else {
168     logger.warning("No departures found for station=" + stationcode + ", type=" + type);
169 torben 305 }
170 torben 978
171 torben 992 Element notifDiv = page.getElementById("station_planlagte_text");
172 torben 978 if (notifDiv != null) {
173    
174 torben 992 Elements tables = notifDiv.getElementsByTag("table");
175     for (Element tab : tables) {
176 torben 978
177 torben 992 Elements anchors = tab.getElementsByTag("a");
178 torben 978 if (anchors.size() == 2) {
179 torben 992 departureBean.notifications.add( anchors.get(1).text() );
180 torben 978 }
181     }
182    
183     }
184    
185    
186     return departureBean;
187 torben 305 }
188    
189 torben 974 /*
190     @Deprecated
191 torben 580 public List<DepartureBean> lookupDeparturesFromTemporarySite(String stationcode, String type) throws Exception {
192    
193     List<DepartureBean> departureList = new ArrayList<DepartureBean>();
194    
195 torben 591 final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3);
196 torben 580 webClient.setTimeout(2500);
197     webClient.setJavaScriptEnabled(false);
198    
199    
200     String uri = "http://bane.dk/lite/station.asp?w=" + type + "&s=" + stationcode;
201    
202 torben 939 HtmlunitInvocation wrapper = new HtmlunitInvocation(webClient, uri);
203 torben 580 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 torben 583
226 torben 580 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 torben 582 String note = fields.get(5).asText();
244 torben 580 departure.setNote(note);
245    
246     departureList.add(departure);
247     }
248     } else {
249     logger.warning("No departures found for station=" + stationcode + ", type=" + type);
250     }
251 torben 591 webClient.closeAllWindows();
252 torben 580
253 torben 591
254 torben 580 return departureList;
255 torben 974 }*/
256 torben 580
257    
258 torben 992 private int extractUpdated(Element updatedTd) { //extract the digit (in this case: 4) from "media/trafikinfo/opdater4.gif"
259 torben 305 int updated = -1;
260    
261 torben 992 Elements updatedImgs = updatedTd.getElementsByTag("img");
262     String updatedStr = updatedImgs.get(0).attr("src");
263 torben 305
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 torben 992 private String extractNote(Element noteTd) {
277     String note = noteTd.text().trim();
278 torben 313
279 torben 992
280     Elements elems = noteTd.getElementsByClass("bemtype");
281 torben 313 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 torben 992 private String extractTrainNumber(Element trainTd) {
288     Element anchorElement = trainTd.getElementsByTag("a").get(0);
289     String href = anchorElement.attr("href");
290 torben 349
291 torben 973 int pos = href.lastIndexOf('/');
292     String number = href.substring(pos+1);
293 torben 970
294 torben 349 return number;
295     }
296    
297 torben 305 //test
298 torben 580 /*
299 torben 451 public static void main(String args[]) throws Exception {
300 torben 305 DepartureFetcher f = new DepartureFetcher();
301 torben 307 List<DepartureBean> deps = f.lookupDepartures("AR", "FJRN");
302 torben 305 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 torben 580 }*/
309 torben 305 }

  ViewVC Help
Powered by ViewVC 1.1.20