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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1412 - (show annotations) (download)
Mon May 2 12:21:49 2011 UTC (13 years ago) by torben
File size: 9090 byte(s)
Use stationentry instead of stationID, take #2
1 package dk.thoerup.traininfoservice.banedk;
2
3
4
5 import java.net.URL;
6 import java.sql.SQLException;
7 import java.util.Map;
8 import java.util.logging.Level;
9 import java.util.logging.Logger;
10
11 import org.jsoup.nodes.Document;
12 import org.jsoup.nodes.Element;
13 import org.jsoup.select.Elements;
14
15 import dk.thoerup.android.traininfo.common.StationBean;
16 import dk.thoerup.android.traininfo.common.StationEntry;
17 import dk.thoerup.android.traininfo.common.TimetableBean;
18 import dk.thoerup.android.traininfo.common.TimetableEntry;
19 import dk.thoerup.circuitbreaker.CircuitBreaker;
20 import dk.thoerup.circuitbreaker.CircuitBreakerManager;
21 import dk.thoerup.genericjavautils.TimeoutMap;
22 import dk.thoerup.traininfoservice.Statistics;
23 import dk.thoerup.traininfoservice.TraininfoSettings;
24 import dk.thoerup.traininfoservice.db.StationDAO;
25
26 public class TimetableFetcher {
27
28
29 Map<String, TimetableBean> cache;
30 Map<String, StationEntry> stationCache;
31
32 StationDAO stationDao = new StationDAO();
33
34
35 Logger logger = Logger.getLogger(TimetableFetcher.class.getName());
36
37 TraininfoSettings settings;
38
39 public TimetableFetcher(TraininfoSettings settings) {
40 this.settings = settings;
41
42 cache = new TimeoutMap<String,TimetableBean>( settings.getCacheTimeout() );
43 stationCache = new TimeoutMap<String,StationEntry>( 3*60*60*1000 );
44 }
45
46
47 TimetableBean cachedLookupTimetable(String trainID, String type) throws Exception {
48 String key = trainID+type;
49 TimetableBean list = cache.get(key);
50
51 if (list == null) {
52 list = lookupTimetable(trainID,type);
53 cache.put(key, list);
54 } else {
55 Statistics.getInstance().incrementTimetableCacheHits();
56 logger.info("Timetable: Cache hit " + trainID);
57 }
58 return list;
59 }
60
61 TimetableBean lookupTimetable(String trainID, String type) throws Exception {
62 if (settings.getBackend() == TraininfoSettings.Backend.Azure ){
63 return lookupTimetableAzureSite(trainID, type);
64
65 } else {
66 return lookupTimetableMobileSite(trainID, type);
67 }
68 }
69
70 StationEntry getStationId(String name) {
71 StationEntry station = stationCache.get(name);
72
73 if (station == null) {
74 try {
75 StationBean bean = stationDao.getByName(name);
76 if (bean.entries.size() == 1) {
77 station = bean.entries.get(0);
78 stationCache.put(name,station);
79 }
80 } catch (SQLException e) {
81 logger.log(Level.SEVERE, "getStationId failed", e);
82 }
83 }
84
85 return station;
86 }
87
88 String correctStationName(String name) {
89 if (name.equals("København"))
90 name = "København H"; //correct inconsistency in naming
91
92 return name;
93 }
94
95 TimetableBean lookupTimetableAzureSite(String trainID, String type) throws Exception {
96 TimetableBean timetableBean = new TimetableBean();
97
98
99 String url = "http://trafikinfo.bane.dk/TrafikInformation/Ruteplan/" + trainID;
100 logger.fine("URL:" + url);
101
102 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
103 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
104
105 Document doc = (Document) breaker.invoke(wrapper);
106
107
108 boolean currentStation = false;
109 boolean currentStationSaved = false;
110
111 Elements tables = doc.getElementsByClass("Rute");
112
113 if (tables.size() == 1) {
114 Element timetable = tables.get(0);
115 Elements rows = timetable.getElementsByTag("tr");
116
117 for (int i=0; i<rows.size(); i++) {
118 if (i==0) //First row is column headers
119 continue;
120
121
122 Element row = rows.get(i);
123 Elements fields = row.getElementsByTag("td");
124
125
126 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
127 currentStation = true;
128 continue;
129 }
130
131 TimetableEntry entry = new TimetableEntry();
132
133 String station = correctStationName( fields.get(0).text() );
134
135 entry.setStation( station );
136 entry.setArrival( fields.get(1).text() );
137 entry.setDeparture( fields.get(2).text() );
138
139 boolean cancelled = fields.get(3).text().equalsIgnoreCase("aflyst");
140 entry.setCancelled(cancelled);
141
142 if (currentStation == true && currentStationSaved == false ) {
143 entry.setCurrent(currentStation);
144 currentStationSaved = true;
145 }
146
147 entry.setStationEntry( getStationId( station ));
148
149 timetableBean.entries.add(entry);
150 }
151
152 //TODO: There is an off-by-one error in this cancelled parser thingie
153 final String cancelledString = "Aflyst";
154 for (int i=0;i<timetableBean.entries.size(); i++) { //handle cancelled labels
155 final int lastIdx = (timetableBean.entries.size() - 1);
156
157 TimetableEntry current = timetableBean.entries.get(i);
158 if (current.isCancelled()) {
159 if (i == 0) {
160 current.setDeparture(cancelledString);
161 } else if (i == lastIdx) {
162 current.setArrival(cancelledString);
163 } else if (i>0 && i<lastIdx) {
164 TimetableEntry next = timetableBean.entries.get(i+1);
165 TimetableEntry prev = timetableBean.entries.get(i-1);
166
167 if (next.isCancelled())
168 current.setDeparture(cancelledString);
169 if (prev.isCancelled())
170 current.setArrival(cancelledString);
171 }
172 }
173 }
174
175 } else {
176 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
177 }
178
179
180 return timetableBean;
181 }
182
183 TimetableBean lookupTimetableMobileSite(String trainID, String type) throws Exception {
184 TimetableBean timetableBean = new TimetableBean();
185
186 String url = "http://mobil.bane.dk/mobilStation.asp?artikelID=5332&tognummer=" + trainID + "&webprofil=" + type + "&mode=rute";
187 logger.fine("URL:" + url);
188
189
190 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
191 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
192
193 Document doc = (Document) breaker.invoke(wrapper);
194
195 Element content = doc.getElementsByClass("contentDiv").get(1);
196 Element dlist = content.child(0);
197
198
199 Elements rows = dlist.getElementsByTag("dt");
200
201 for (int i=0; i<rows.size(); i++) {
202
203 Element row = rows.get(i);
204
205 logger.fine( row.text() );
206
207 String parts[] = row.text().split(",");
208
209 TimetableEntry entry = new TimetableEntry();
210
211 String station = DepartureFetcher.cleanText( parts[0] ) ;
212 station = correctStationName(station);
213
214
215 String arrival = DepartureFetcher.cleanText( parts[1] );
216 String departure = DepartureFetcher.cleanText( "" );
217
218 entry.setStation( station );
219 entry.setArrival( arrival );
220 entry.setDeparture( departure );
221
222
223 entry.setStationEntry( getStationId( station ));
224
225 timetableBean.entries.add(entry);
226 }
227
228
229 return timetableBean;
230
231 }
232
233 @Deprecated
234 TimetableBean lookupTimetableWwwSite(String trainID, String type) throws Exception {
235 TimetableBean timetableBean = new TimetableBean();
236
237 String url = "http://www.bane.dk/visRute.asp?W=" + type + "&TogNr=" + trainID + "&artikelId=4276";
238 logger.fine("URL:" + url);
239
240
241 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
242 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
243
244 Document doc = (Document) breaker.invoke(wrapper);
245
246
247 boolean currentStation = false;
248 boolean currentStationSaved = false;
249
250 Elements tables = doc.getElementsByClass("Rute");
251
252 if (tables.size() == 1) {
253 Element timetable = tables.get(0);
254 Elements rows = timetable.getElementsByTag("tr");
255
256 for (int i=0; i<rows.size(); i++) {
257 if (i==0) //First row is column headers
258 continue;
259
260
261 Element row = rows.get(i);
262 Elements fields = row.getElementsByTag("td");
263
264
265 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
266 currentStation = true;
267 continue;
268 }
269
270 TimetableEntry entry = new TimetableEntry();
271
272 String station = DepartureFetcher.cleanText( fields.get(0).text() ) ;
273 station = correctStationName(station);
274
275
276 String arrival = DepartureFetcher.cleanText( fields.get(1).text() );
277 String departure = DepartureFetcher.cleanText( fields.get(2).text() );
278
279 entry.setStation( station );
280 entry.setArrival( arrival );
281 entry.setDeparture( departure );
282
283
284 if (currentStation == true && currentStationSaved == false ) {
285 entry.setCurrent(currentStation);
286 currentStationSaved = true;
287 }
288
289 entry.setStationEntry( getStationId( station ));
290
291 timetableBean.entries.add(entry);
292 }
293
294 } else {
295 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
296 }
297
298
299 return timetableBean;
300 }
301
302 }

  ViewVC Help
Powered by ViewVC 1.1.20