/[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 1303 - (show annotations) (download)
Tue Apr 19 11:52:39 2011 UTC (13 years ago) by torben
File size: 7308 byte(s)
first step towards a settings system
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.traininfoservice.Statistics;
20 import dk.thoerup.traininfoservice.TraininfoSettings;
21 import dk.thoerup.traininfoservice.db.StationDAO;
22
23 public class TimetableFetcher {
24
25
26 Map<String, TimetableBean> cache;
27 Map<String, Integer> stationCache;
28
29 StationDAO stationDao = new StationDAO();
30
31
32 Logger logger = Logger.getLogger(TimetableFetcher.class.getName());
33
34 TraininfoSettings settings;
35
36 public TimetableFetcher(TraininfoSettings settings) {
37 this.settings = settings;
38
39 cache = new TimeoutMap<String,TimetableBean>( settings.getCacheTimeout() );
40 stationCache = new TimeoutMap<String,Integer>( 3*60*60*1000 );
41 }
42
43
44 TimetableBean cachedLookupTimetable(String trainID, String type) throws Exception {
45 String key = trainID+type;
46 TimetableBean list = cache.get(key);
47
48 if (list == null) {
49 list = lookupTimetable(trainID,type);
50 cache.put(key, list);
51 } else {
52 Statistics.getInstance().incrementTimetableCacheHits();
53 logger.info("Timetable: Cache hit " + trainID);
54 }
55 return list;
56 }
57
58 TimetableBean lookupTimetable(String trainID, String type) throws Exception {
59 if (settings.getUseAzureSite() == true ){
60 return lookupTimetableAzureSite(trainID, type);
61
62 } else {
63 return lookupTimetableWwwSite(trainID, type);
64 }
65 }
66
67 int getStationId(String name) {
68 Integer id = stationCache.get(name);
69
70 if (id == null) {
71 try {
72 id = stationDao.getIdByName(name);
73 stationCache.put(name, id);
74 } catch (SQLException e) {
75 logger.log(Level.SEVERE, "getStationId failed", e);
76 id = -1;
77 }
78 }
79
80 return id;
81 }
82
83 TimetableBean lookupTimetableAzureSite(String trainID, String type) throws Exception {
84 TimetableBean timetableBean = new TimetableBean();
85
86
87 String url = "http://trafikinfo.bane.dk/TrafikInformation/Ruteplan/" + trainID;
88 logger.fine("URL:" + url);
89
90 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
91 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
92
93 Document doc = (Document) breaker.invoke(wrapper);
94
95
96 boolean currentStation = false;
97 boolean currentStationSaved = false;
98
99 Elements tables = doc.getElementsByClass("Rute");
100
101 if (tables.size() == 1) {
102 Element timetable = tables.get(0);
103 Elements rows = timetable.getElementsByTag("tr");
104
105 for (int i=0; i<rows.size(); i++) {
106 if (i==0) //First row is column headers
107 continue;
108
109
110 Element row = rows.get(i);
111 Elements fields = row.getElementsByTag("td");
112
113
114 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
115 currentStation = true;
116 continue;
117 }
118
119 TimetableEntry entry = new TimetableEntry();
120
121 String station = fields.get(0).text() ;
122 if (station.equals("København"))
123 station = "København H"; //correct inconsistency in naming
124
125 entry.setStation( station );
126 entry.setArrival( fields.get(1).text() );
127 entry.setDeparture( fields.get(2).text() );
128
129 boolean cancelled = fields.get(3).text().equalsIgnoreCase("aflyst");
130 entry.setCancelled(cancelled);
131
132 if (currentStation == true && currentStationSaved == false ) {
133 entry.setCurrent(currentStation);
134 currentStationSaved = true;
135 }
136
137 entry.setStationId( getStationId( station ));
138
139 timetableBean.entries.add(entry);
140 }
141
142 //TODO: There is an off-by-one error in this cancelled parser thingie
143 final String cancelledString = "Aflyst";
144 for (int i=0;i<timetableBean.entries.size(); i++) { //handle cancelled labels
145 final int lastIdx = (timetableBean.entries.size() - 1);
146
147 TimetableEntry current = timetableBean.entries.get(i);
148 if (current.isCancelled()) {
149 if (i == 0) {
150 current.setDeparture(cancelledString);
151 } else if (i == lastIdx) {
152 current.setArrival(cancelledString);
153 } else if (i>0 && i<lastIdx) {
154 TimetableEntry next = timetableBean.entries.get(i+1);
155 TimetableEntry prev = timetableBean.entries.get(i-1);
156
157 if (next.isCancelled())
158 current.setDeparture(cancelledString);
159 if (prev.isCancelled())
160 current.setArrival(cancelledString);
161 }
162 }
163 }
164
165 } else {
166 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
167 }
168
169
170 return timetableBean;
171 }
172
173 TimetableBean lookupTimetableWwwSite(String trainID, String type) throws Exception {
174 TimetableBean timetableBean = new TimetableBean();
175
176 String url = "http://www.bane.dk/visRute.asp?W=" + type + "&TogNr=" + trainID + "&artikelId=4276";
177 logger.fine("URL:" + url);
178
179
180 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , settings.getReplyTimeout() );
181 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
182
183 Document doc = (Document) breaker.invoke(wrapper);
184
185
186 boolean currentStation = false;
187 boolean currentStationSaved = false;
188
189 Elements tables = doc.getElementsByClass("Rute");
190
191 if (tables.size() == 1) {
192 Element timetable = tables.get(0);
193 Elements rows = timetable.getElementsByTag("tr");
194
195 for (int i=0; i<rows.size(); i++) {
196 if (i==0) //First row is column headers
197 continue;
198
199
200 Element row = rows.get(i);
201 Elements fields = row.getElementsByTag("td");
202
203
204 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
205 currentStation = true;
206 continue;
207 }
208
209 TimetableEntry entry = new TimetableEntry();
210
211 String station = DepartureFetcher.cleanText( fields.get(0).text() ) ;
212 if (station.equals("København"))
213 station = "København H"; //correct inconsistency in naming
214
215 String arrival = DepartureFetcher.cleanText( fields.get(1).text() );
216 String departure = DepartureFetcher.cleanText( fields.get(2).text() );
217
218 entry.setStation( station );
219 entry.setArrival( arrival );
220 entry.setDeparture( departure );
221
222
223 if (currentStation == true && currentStationSaved == false ) {
224 entry.setCurrent(currentStation);
225 currentStationSaved = true;
226 }
227
228 entry.setStationId( getStationId( station ));
229
230 timetableBean.entries.add(entry);
231 }
232
233 } else {
234 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
235 }
236
237
238 return timetableBean;
239 }
240
241 }

  ViewVC Help
Powered by ViewVC 1.1.20