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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20