/[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 1368 - (show annotations) (download)
Wed Apr 20 20:40:35 2011 UTC (13 years ago) by torben
File size: 8905 byte(s)
make log level=fine so we don't get it on prod. server
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.getUseAzureSite() == true ){
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 TimetableBean lookupTimetableAzureSite(String trainID, String type) throws Exception {
86 TimetableBean timetableBean = new TimetableBean();
87
88
89 String url = "http://trafikinfo.bane.dk/TrafikInformation/Ruteplan/" + trainID;
90 logger.fine("URL:" + url);
91
92 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
93 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
94
95 Document doc = (Document) breaker.invoke(wrapper);
96
97
98 boolean currentStation = false;
99 boolean currentStationSaved = false;
100
101 Elements tables = doc.getElementsByClass("Rute");
102
103 if (tables.size() == 1) {
104 Element timetable = tables.get(0);
105 Elements rows = timetable.getElementsByTag("tr");
106
107 for (int i=0; i<rows.size(); i++) {
108 if (i==0) //First row is column headers
109 continue;
110
111
112 Element row = rows.get(i);
113 Elements fields = row.getElementsByTag("td");
114
115
116 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
117 currentStation = true;
118 continue;
119 }
120
121 TimetableEntry entry = new TimetableEntry();
122
123 String station = fields.get(0).text() ;
124 if (station.equals("København"))
125 station = "København H"; //correct inconsistency in naming
126
127 entry.setStation( station );
128 entry.setArrival( fields.get(1).text() );
129 entry.setDeparture( fields.get(2).text() );
130
131 boolean cancelled = fields.get(3).text().equalsIgnoreCase("aflyst");
132 entry.setCancelled(cancelled);
133
134 if (currentStation == true && currentStationSaved == false ) {
135 entry.setCurrent(currentStation);
136 currentStationSaved = true;
137 }
138
139 entry.setStationId( getStationId( station ));
140
141 timetableBean.entries.add(entry);
142 }
143
144 //TODO: There is an off-by-one error in this cancelled parser thingie
145 final String cancelledString = "Aflyst";
146 for (int i=0;i<timetableBean.entries.size(); i++) { //handle cancelled labels
147 final int lastIdx = (timetableBean.entries.size() - 1);
148
149 TimetableEntry current = timetableBean.entries.get(i);
150 if (current.isCancelled()) {
151 if (i == 0) {
152 current.setDeparture(cancelledString);
153 } else if (i == lastIdx) {
154 current.setArrival(cancelledString);
155 } else if (i>0 && i<lastIdx) {
156 TimetableEntry next = timetableBean.entries.get(i+1);
157 TimetableEntry prev = timetableBean.entries.get(i-1);
158
159 if (next.isCancelled())
160 current.setDeparture(cancelledString);
161 if (prev.isCancelled())
162 current.setArrival(cancelledString);
163 }
164 }
165 }
166
167 } else {
168 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
169 }
170
171
172 return timetableBean;
173 }
174
175 TimetableBean lookupTimetableMobileSite(String trainID, String type) throws Exception {
176 TimetableBean timetableBean = new TimetableBean();
177
178 String url = "http://mobil.bane.dk/mobilStation.asp?artikelID=5332&tognummer=" + trainID + "&webprofil=" + type + "&mode=rute";
179 logger.fine("URL:" + url);
180
181
182 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
183 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
184
185 Document doc = (Document) breaker.invoke(wrapper);
186
187 Element content = doc.getElementsByClass("contentDiv").get(1);
188 Element dlist = content.child(0);
189
190
191 Elements rows = dlist.getElementsByTag("dt");
192
193 for (int i=0; i<rows.size(); i++) {
194
195 Element row = rows.get(i);
196
197 logger.fine( row.text() );
198
199 String parts[] = row.text().split(",");
200
201 TimetableEntry entry = new TimetableEntry();
202
203 String station = DepartureFetcher.cleanText( parts[0] ) ;
204 if (station.equals("København"))
205 station = "København H"; //correct inconsistency in naming
206
207 String arrival = DepartureFetcher.cleanText( parts[1] );
208 String departure = DepartureFetcher.cleanText( "" );
209
210 entry.setStation( station );
211 entry.setArrival( arrival );
212 entry.setDeparture( departure );
213
214
215 entry.setStationId( getStationId( station ));
216
217 timetableBean.entries.add(entry);
218 }
219
220
221 return timetableBean;
222
223 }
224
225 @Deprecated
226 TimetableBean lookupTimetableWwwSite(String trainID, String type) throws Exception {
227 TimetableBean timetableBean = new TimetableBean();
228
229 String url = "http://www.bane.dk/visRute.asp?W=" + type + "&TogNr=" + trainID + "&artikelId=4276";
230 logger.fine("URL:" + url);
231
232
233 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
234 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
235
236 Document doc = (Document) breaker.invoke(wrapper);
237
238
239 boolean currentStation = false;
240 boolean currentStationSaved = false;
241
242 Elements tables = doc.getElementsByClass("Rute");
243
244 if (tables.size() == 1) {
245 Element timetable = tables.get(0);
246 Elements rows = timetable.getElementsByTag("tr");
247
248 for (int i=0; i<rows.size(); i++) {
249 if (i==0) //First row is column headers
250 continue;
251
252
253 Element row = rows.get(i);
254 Elements fields = row.getElementsByTag("td");
255
256
257 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
258 currentStation = true;
259 continue;
260 }
261
262 TimetableEntry entry = new TimetableEntry();
263
264 String station = DepartureFetcher.cleanText( fields.get(0).text() ) ;
265 if (station.equals("København"))
266 station = "København H"; //correct inconsistency in naming
267
268 String arrival = DepartureFetcher.cleanText( fields.get(1).text() );
269 String departure = DepartureFetcher.cleanText( fields.get(2).text() );
270
271 entry.setStation( station );
272 entry.setArrival( arrival );
273 entry.setDeparture( departure );
274
275
276 if (currentStation == true && currentStationSaved == false ) {
277 entry.setCurrent(currentStation);
278 currentStationSaved = true;
279 }
280
281 entry.setStationId( getStationId( station ));
282
283 timetableBean.entries.add(entry);
284 }
285
286 } else {
287 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
288 }
289
290
291 return timetableBean;
292 }
293
294 }

  ViewVC Help
Powered by ViewVC 1.1.20