/[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 1036 - (show annotations) (download)
Wed Sep 8 12:49:22 2010 UTC (13 years, 8 months ago) by torben
File size: 7093 byte(s)
also enable timetables to use both new azure and old www
1 package dk.thoerup.traininfoservice.banedk;
2
3
4
5 import java.net.URL;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.logging.Level;
11 import java.util.logging.Logger;
12
13 import org.jsoup.nodes.Document;
14 import org.jsoup.nodes.Element;
15 import org.jsoup.select.Elements;
16
17 import dk.thoerup.circuitbreaker.CircuitBreaker;
18 import dk.thoerup.circuitbreaker.CircuitBreakerManager;
19 import dk.thoerup.traininfoservice.StationDAO;
20 import dk.thoerup.traininfoservice.Statistics;
21
22 public class TimetableFetcher {
23
24
25 Map<String, List<TimetableBean>> cache;
26 Map<String, Integer> stationCache;
27
28 StationDAO stationDao = new StationDAO();
29
30
31 Logger logger = Logger.getLogger(TimetableFetcher.class.getName());
32
33 private boolean useAzureSite;
34 private int replyTimeout;
35
36 public TimetableFetcher(boolean azureSite, int cacheTimeout, int replyTimeout) {
37 useAzureSite = azureSite;
38 this.replyTimeout = replyTimeout;
39
40 cache = new TimeoutMap<String,List<TimetableBean>>(cacheTimeout);
41 stationCache = new TimeoutMap<String,Integer>( 3*60*60*1000 );
42 }
43
44
45 List<TimetableBean> cachedLookupTimetable(String trainID, String type) throws Exception {
46 String key = trainID+type;
47 List<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 List<TimetableBean> lookupTimetable(String trainID, String type) throws Exception {
60 if (useAzureSite == true ){
61 return lookupTimetableAzureSite(trainID, type);
62
63 } else {
64 return lookupTimetableWwwSite(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 List<TimetableBean> lookupTimetableAzureSite(String trainID, String type) throws Exception {
85 List<TimetableBean> timetableList = new ArrayList<TimetableBean>();
86
87 //String url = "http://www.bane.dk/visRute.asp?W=" + type + "&TogNr=" + trainID + "&artikelId=4276";
88 String url = "http://trafikinfo.bane.dk/TrafikInformation/Ruteplan/" + trainID;
89
90
91 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , replyTimeout);
92 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
93
94 Document doc = (Document) breaker.invoke(wrapper);
95
96
97 boolean currentStation = false;
98 boolean currentStationSaved = false;
99
100 Elements tables = doc.getElementsByClass("Rute");
101
102 if (tables.size() == 1) {
103 Element timetable = tables.get(0);
104 Elements rows = timetable.getElementsByTag("tr");
105
106 for (int i=0; i<rows.size(); i++) {
107 if (i==0) //First row is column headers
108 continue;
109
110
111 Element row = rows.get(i);
112 Elements fields = row.getElementsByTag("td");
113
114
115 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
116 currentStation = true;
117 continue;
118 }
119
120 TimetableBean bean = new TimetableBean();
121
122 String station = fields.get(0).text() ;
123 if (station.equals("København"))
124 station = "København H"; //correct inconsistency in naming
125
126 bean.setStation( station );
127 bean.setArrival( fields.get(1).text() );
128 bean.setDeparture( fields.get(2).text() );
129
130 boolean cancelled = fields.get(3).text().equalsIgnoreCase("aflyst");
131 bean.setCancelled(cancelled);
132
133 if (currentStation == true && currentStationSaved == false ) {
134 bean.setCurrent(currentStation);
135 currentStationSaved = true;
136 }
137
138 bean.setStationId( getStationId( station ));
139
140 timetableList.add(bean);
141 }
142
143 //TODO: There is an off-by-one error in this cancelled parser thingie
144 final String cancelledString = "Aflyst";
145 for (int i=0;i<timetableList.size(); i++) { //handle cancelled labels
146 final int lastIdx = (timetableList.size() - 1);
147
148 TimetableBean current = timetableList.get(i);
149 if (current.isCancelled()) {
150 if (i == 0) {
151 current.setDeparture(cancelledString);
152 } else if (i == lastIdx) {
153 current.setArrival(cancelledString);
154 } else if (i>0 && i<lastIdx) {
155 TimetableBean next = timetableList.get(i+1);
156 TimetableBean prev = timetableList.get(i-1);
157
158 if (next.isCancelled())
159 current.setDeparture(cancelledString);
160 if (prev.isCancelled())
161 current.setArrival(cancelledString);
162 }
163 }
164 }
165
166 } else {
167 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
168 }
169
170
171 return timetableList;
172 }
173
174 List<TimetableBean> lookupTimetableWwwSite(String trainID, String type) throws Exception {
175 List<TimetableBean> timetableList = new ArrayList<TimetableBean>();
176
177 String url = "http://www.bane.dk/visRute.asp?W=" + type + "&TogNr=" + trainID + "&artikelId=4276";
178
179
180
181 JsoupInvocation wrapper = new JsoupInvocation( new URL(url) , replyTimeout);
182 CircuitBreaker breaker = CircuitBreakerManager.getManager().getCircuitBreaker("banedk");
183
184 Document doc = (Document) breaker.invoke(wrapper);
185
186
187 boolean currentStation = false;
188 boolean currentStationSaved = false;
189
190 Elements tables = doc.getElementsByClass("Rute");
191
192 if (tables.size() == 1) {
193 Element timetable = tables.get(0);
194 Elements rows = timetable.getElementsByTag("tr");
195
196 for (int i=0; i<rows.size(); i++) {
197 if (i==0) //First row is column headers
198 continue;
199
200
201 Element row = rows.get(i);
202 Elements fields = row.getElementsByTag("td");
203
204
205 if (currentStationSaved == false && fields.get(0).attr("class").equalsIgnoreCase("Tidsstreg")) {
206 currentStation = true;
207 continue;
208 }
209
210 TimetableBean bean = new TimetableBean();
211
212 String station = fields.get(0).text() ;
213 if (station.equals("København"))
214 station = "København H"; //correct inconsistency in naming
215
216 bean.setStation( station );
217 bean.setArrival( fields.get(1).text() );
218 bean.setDeparture( fields.get(2).text() );
219
220
221 if (currentStation == true && currentStationSaved == false ) {
222 bean.setCurrent(currentStation);
223 currentStationSaved = true;
224 }
225
226 bean.setStationId( getStationId( station ));
227
228 timetableList.add(bean);
229 }
230
231 } else {
232 logger.warning("No time table found, trainID=" + trainID + " type=" + type);
233 }
234
235
236 return timetableList;
237 }
238
239 }

  ViewVC Help
Powered by ViewVC 1.1.20