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

  ViewVC Help
Powered by ViewVC 1.1.20