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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20