/[projects]/android/TrainInfoService/src/dk/thoerup/traininfoservice/banedk/TimetableFetcher.java
ViewVC logotype

Annotation of /android/TrainInfoService/src/dk/thoerup/traininfoservice/banedk/TimetableFetcher.java

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20