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

  ViewVC Help
Powered by ViewVC 1.1.20