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

  ViewVC Help
Powered by ViewVC 1.1.20