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

  ViewVC Help
Powered by ViewVC 1.1.20