View Javadoc
1   /**
2    * Copyright 2011-2014 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  package org.kuali.mobility.bus.dao;
16  
17  import com.thoughtworks.xstream.XStream;
18  import com.thoughtworks.xstream.io.StreamException;
19  import org.apache.commons.collections.CollectionUtils;
20  import org.slf4j.Logger;
21  import org.slf4j.LoggerFactory;
22  import org.kuali.mobility.bus.dao.helper.BusStopNameUtil;
23  import org.kuali.mobility.bus.entity.*;
24  import org.kuali.mobility.bus.entity.helper.*;
25  import org.springframework.context.ApplicationContext;
26  import org.springframework.context.ApplicationContextAware;
27  
28  import java.net.MalformedURLException;
29  import java.net.URL;
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  /**
34   *
35   * @author Kuali Mobility Team <mobility.collab@kuali.org>
36   */
37  public class BusDaoUMImpl implements BusDao, ApplicationContextAware {
38  
39  	public static Logger LOG = LoggerFactory.getLogger(BusDaoUMImpl.class);
40  
41  	private ApplicationContext applicationContext;
42  
43  	private List<BusStop> busStops;
44  	private List<BusRoute> busRoutes;
45  	private List<Bus> buses;
46  	private List<BusAlert> alerts;
47  
48  	private String busAlertUrl;
49  	private String busStopUrl;
50  	private String busRouteUrl;
51  	private String busLocationUrl;
52  	private String busRoutePathUrl;
53  	
54  	private BusStopNameUtil busStopNameMapper;
55  
56      @Override
57  	public void loadAlerts() {
58      	XStream xstream = new XStream();
59      	xstream.processAnnotations(UMBusAlertReader.class);
60      	xstream.processAnnotations(UMBusAlert.class);
61      	xstream.addImplicitCollection(UMBusAlertReader.class, "alerts");
62      	
63      	UMBusAlertReader busAlertReader = null;
64      	try {
65      		busAlertReader = (UMBusAlertReader) xstream.fromXML(new URL(getBusAlertUrl()));
66      	} catch (MalformedURLException ex) {
67      		LOG.error(ex.toString());
68      	}
69      	List<BusAlert> busAlerts = new ArrayList<BusAlert>();
70      	if (busAlertReader == null) {
71      		LOG.debug("busAlertReader == null");
72      	} else if (busAlertReader.getAlerts() == null) {
73      		LOG.debug("busAlertReader.getAlerts() == null");
74      	} else {
75      		for (UMBusAlert b : busAlertReader.getAlerts()) {
76      			BusAlert busAlert = (BusAlert) getApplicationContext().getBean("busAlert");
77      			busAlert.setTitle(b.getTitle());
78      			busAlert.setMessage(b.getMessage());
79      			busAlert.setColor(b.getColor());
80      			busAlert.setMessageType(b.getMessageType());
81      			busAlerts.add(busAlert);
82      		}
83      	}
84      	this.setAlerts(busAlerts);
85  	}
86      
87  	public void loadRoutes() {
88  		XStream xstream = new XStream();
89  		xstream.processAnnotations(UMBusRouteReader.class);
90  		xstream.processAnnotations(UMBusRoute.class);
91  		xstream.processAnnotations(UMBusStop.class);
92  		xstream.processAnnotations(UMBusRoutePathReader.class);
93  		xstream.processAnnotations(UMBusRoutePathLatLong.class);
94  		xstream.processAnnotations(UMBusRoutePathInfo.class);
95  		xstream.addImplicitCollection(UMBusRouteReader.class, "routes");
96  		xstream.addImplicitCollection(UMBusRoute.class, "stops");
97  		xstream.addImplicitCollection(UMBusRoutePathReader.class, "paths");
98  
99  		UMBusRouteReader routeReader = null;
100 		try {
101 			routeReader = (UMBusRouteReader) xstream.fromXML(new URL(
102 					getBusRouteUrl()));
103 		} catch (MalformedURLException ex) {
104 			LOG.error(ex.toString());
105 		}
106 
107 		List<BusRoute> routes = new ArrayList<BusRoute>();
108         List<BusStop>  stops  = new ArrayList<BusStop>();
109         boolean hasRoutes = routeReader != null && CollectionUtils.isNotEmpty(routeReader.getRoutes());
110         if (hasRoutes) {
111 			for (UMBusRoute r : routeReader.getRoutes()) {
112 				BusRoute route = (BusRoute) getApplicationContext().getBean("busRoute");
113 				route.setId(Long.parseLong(r.getId()));
114 				UMBusRoutePathReader pathReader = null;
115 				try {
116 					String fullUrl = getBusRoutePathUrl() + route.getId() + ".xml";
117 					pathReader = (UMBusRoutePathReader) xstream.fromXML(new URL(fullUrl));
118 				} catch (MalformedURLException ex) {
119 					LOG.error(ex.toString());
120 				} catch (StreamException ex) {
121 					LOG.error(ex.toString());
122 				}
123 				boolean hasPathReader = pathReader != null && (pathReader.getPaths() != null || pathReader.getInfo() != null);
124 		        if (hasPathReader) {
125 		        	BusRoutePath routePath = (BusRoutePath) getApplicationContext().getBean("busRoutePath");
126 		        	routePath.setId(pathReader.getInfo().getId());
127 		        	routePath.setColor(pathReader.getInfo().getColor());
128 		        	routePath.setTransparency(pathReader.getInfo().getTransparency());
129 		        	routePath.setLineWidth(pathReader.getInfo().getLineWidth());
130 		        	List<Double> points = new ArrayList<Double>();
131 		        	for (UMBusRoutePathLatLong point : pathReader.getPaths()) {
132 		        		points.add(Double.parseDouble(point.getLatitude()));
133 		        		points.add(Double.parseDouble(point.getLongitude()));
134 		        	}
135 		        	routePath.setLatLongs(points);
136 		        	route.setPath(routePath);
137 				}
138 				route.setName(r.getName());
139 				route.setColor(r.getColor());
140 				LOG.debug("route color:" + route.getColor());
141 				if (null == getBusStops()) {
142 					setBusStops(new ArrayList<BusStop>());
143 				}
144 
145 				if (r!=null && r.getStops()!=null) {
146 					for (UMBusStop s : r.getStops()) {
147 						BusStop stop = (BusStop) getApplicationContext().getBean("busStop");
148 						//stop.setName(s.getName());
149 						//LOG.debug("bus stop ROUTE name: " + r.getName() + ", stopname -" + s.getName() + ", stopname2 -" + s.getName2() + ", stopname3 - " + s.getName3());
150 						//set busstopname loaded from xml
151 						stop.setName(getBusStopNameMapper().updateBusStopName(s.getName()));
152 						stop.setId(s.getName().hashCode());
153 						stop.setLatitude(s.getLatitude());
154 						stop.setLongitude(s.getLongitude());
155 
156                         List<ScheduledStop> schedule = new ArrayList<ScheduledStop>();
157 
158                         // TODO: Fix this to dynamically utilize the toacount
159 						// variable.
160 						// This is functional but potentially will break.
161 						if (s.getId1() != null) {
162 							LOG.debug("Looking up bus " + s.getId1());
163 							Bus tBus = getBus(Long.parseLong(s.getId1()));
164 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
165 									+ "found.");
166                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
167                             scheduledStop.setBus(tBus);
168                             scheduledStop.setBusStopRouteName(r.getName());
169                            // scheduledStop.setTimeToArrival( (new Float( s.getToa1() ) ).intValue() );
170                             // fix time as not rounding properly for float, changed to double
171                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa1())/60));
172 							schedule.add( scheduledStop );
173 						}
174 						if (s.getId2() != null) {
175 							LOG.debug("Looking up bus " + s.getId2());
176 							Bus tBus = getBus(Long.parseLong(s.getId2()));
177 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
178 									+ "found.");
179                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
180                             scheduledStop.setBus(tBus);
181                             scheduledStop.setBusStopRouteName(r.getName());
182                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa2())/60));
183 							schedule.add( scheduledStop );
184 						}
185 						if (s.getId3() != null) {
186 							LOG.debug("Looking up bus " + s.getId3());
187 							Bus tBus = getBus(Long.parseLong(s.getId3()));
188 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
189 									+ "found.");
190                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
191                             scheduledStop.setBus(tBus);
192                             scheduledStop.setBusStopRouteName(r.getName());
193                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa3())/60));
194 							schedule.add( scheduledStop );
195 						}
196 						if (s.getId4() != null) {
197 							LOG.debug("Looking up bus " + s.getId4());
198 							Bus tBus = getBus(Long.parseLong(s.getId4()));
199 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
200 									+ "found.");
201                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
202                             scheduledStop.setBus(tBus);
203                             scheduledStop.setBusStopRouteName(r.getName());
204                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa4())/60));
205 							schedule.add( scheduledStop );
206 						}
207 						if (s.getId5() != null) {
208 							LOG.debug("Looking up bus " + s.getId5());
209 							Bus tBus = getBus(Long.parseLong(s.getId5()));
210 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
211 									+ "found.");
212                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
213                             scheduledStop.setBus(tBus);
214                             scheduledStop.setBusStopRouteName(r.getName());
215                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa5())/60));
216 							schedule.add( scheduledStop );
217 						}
218 						if (s.getId6() != null) {
219 							LOG.debug("Looking up bus " + s.getId6());
220 							Bus tBus = getBus(Long.parseLong(s.getId6()));
221 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
222 									+ "found.");
223                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
224                             scheduledStop.setBus(tBus);
225                             scheduledStop.setBusStopRouteName(r.getName());
226                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa6())/60));
227 							schedule.add( scheduledStop );
228 						}
229 						if (s.getId7() != null) {
230 							LOG.debug("Looking up bus " + s.getId7());
231 							Bus tBus = getBus(Long.parseLong(s.getId7()));
232 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
233 									+ "found.");
234                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
235                             scheduledStop.setBus(tBus);
236                             scheduledStop.setBusStopRouteName(r.getName());
237                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa7())/60));
238 							schedule.add( scheduledStop );
239 						}
240 						if (s.getId8() != null) {
241 						    LOG.debug("Looking up bus " + s.getId8());
242 							Bus tBus = getBus(Long.parseLong(s.getId8()));
243 							LOG.debug("Bus was " + (tBus == null ? "not " : "")
244 									+ "found.");
245                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
246                             scheduledStop.setBus(tBus);
247                             scheduledStop.setBusStopRouteName(r.getName());
248                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa8())/60));
249 							schedule.add( scheduledStop );
250 						}
251 						if (s.getId9() != null) {
252 						    LOG.debug("Looking up bus " + s.getId9());
253 							Bus tBus = getBus(Long.parseLong(s.getId9()));
254 						    LOG.debug("Bus was " + (tBus == null ? "not " : "")
255 									+ "found.");
256                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
257                             scheduledStop.setBus(tBus);
258                             scheduledStop.setBusStopRouteName(r.getName());
259                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa9())/60));
260 							schedule.add( scheduledStop );
261 						}
262 						if (s.getId10() != null) {
263 						 	LOG.debug("Looking up bus " + s.getId10());
264 							Bus tBus = getBus(Long.parseLong(s.getId10()));
265 						    LOG.debug("Bus was " + (tBus == null ? "not " : "")
266 									+ "found.");
267                             ScheduledStop scheduledStop = (ScheduledStop)getApplicationContext().getBean("scheduledStop");
268                             scheduledStop.setBus(tBus);
269                             scheduledStop.setBusStopRouteName(r.getName());
270                             scheduledStop.setTimeToArrival( Math.round(new Double(s.getToa10())/60));
271 							schedule.add( scheduledStop );
272 						}
273 
274 						if( stops.contains(stop) ) {
275 	                        LOG.debug( "Bus stop already exists in the list for: "+stop.getName() );
276 	                        int i = stops.indexOf( stop );
277 	                        BusStop oldStop = stops.get( i );
278 	                        if (oldStop.getScheduledStop()==null) {
279 	                        	oldStop.setScheduledStop(schedule);
280 	                        }
281 	                        else {
282 	                        	oldStop.getScheduledStop().addAll(schedule);
283 	                        }
284 	                        stop = oldStop;
285 						}
286 						else {
287 							LOG.debug( "Bus Stop is not found in master list for: "+stop.getName() );
288 							stop.setScheduledStop(schedule);
289 	                        stops.add(stop);
290 						}
291 
292 						route.addStop(stop);
293 
294 					}
295 				}
296 				if ( route.getStops()==null || route.getStops().isEmpty() ) {
297 					LOG.info("Route " + route.getName() + " has NO stops, so do NOT show it!!!");
298 				}
299 				else {
300 					routes.add(route);
301 				}
302 			}
303         }
304         setBusRoutes(routes);
305         setBusStops( stops );
306 		LOG.info((null == getBusRoutes() ? "Failed to load" : "Loaded " + getBusRoutes().size()) + " routes.");
307 	}
308 
309 	@Override
310 	public void loadStops() {
311 		throw new UnsupportedOperationException("Not supported yet.");
312 	}
313 
314 	@Override
315 	public void loadBusLocations() {
316 		XStream xstream = new XStream();
317 		xstream.processAnnotations(UMBusReader.class);
318 		xstream.processAnnotations(UMBus.class);
319 		xstream.addImplicitCollection(UMBusReader.class, "items");
320 
321 		UMBusReader busReader = null;
322 		try {
323 			busReader = (UMBusReader) xstream.fromXML(new URL(
324 					getBusLocationUrl()));
325 		} catch (MalformedURLException ex) {
326 			LOG.error(ex.toString());
327 		}
328 
329 		List<Bus> busData = new ArrayList<Bus>();
330 		if (busReader == null){
331 			LOG.debug("busReader == null");
332 		}
333 		else if (busReader.getItems() == null) {
334 			LOG.debug("busReader.getItems() == null");
335 		}
336 		else {
337 			for (UMBus b : busReader.getItems()) {
338 				Bus bus = (Bus) getApplicationContext().getBean("bus");
339 				bus.setName(b.getRouteName());
340 				bus.setId(b.getId());
341 				bus.setRouteId(b.getRouteId());
342 				bus.setRouteName(b.getRouteName());
343 				bus.setHeading(b.getHeading());
344 				bus.setColor(b.getColor());
345 				bus.setLatitude(b.getLatitude());
346 				bus.setLongitude(b.getLongitude());
347 				busData.add(bus);
348 			}
349 		}
350 		this.setBuses(busData);
351 	}
352 	
353 	@Override
354 	public List<BusAlert> getBusAlerts() {
355 		return alerts;
356 	}
357 
358 	/**
359 	 * @return the applicationContext
360 	 */
361 	public ApplicationContext getApplicationContext() {
362 		return applicationContext;
363 	}
364 
365 	/**
366 	 * @param applicationContext
367 	 *            the applicationContext to set
368 	 */
369 	public void setApplicationContext(ApplicationContext applicationContext) {
370 		this.applicationContext = applicationContext;
371 	}
372 
373 	/**
374 	 * @return the busStops
375 	 */
376 	public List<BusStop> getBusStops() {
377 		return busStops;
378 	}
379 
380 	/**
381 	 * @param busStops
382 	 *            the busStops to set
383 	 */
384 	public void setBusStops(List<BusStop> busStops) {
385 		this.busStops = busStops;
386 	}
387 
388 	/**
389 	 * @return the busRoutes
390 	 */
391 	public List<BusRoute> getBusRoutes() {
392 		return busRoutes;
393 	}
394 
395 	/**
396 	 * @param busRoutes
397 	 *            the busRoutes to set
398 	 */
399 	public void setBusRoutes(List<BusRoute> busRoutes) {
400 		this.busRoutes = busRoutes;
401 	}
402 
403 	/**
404 	 * @return the buses
405 	 */
406 	public List<Bus> getBuses() {
407 		return buses;
408 	}
409 
410 	/**
411 	 * @param buses
412 	 *            the buses to set
413 	 */
414 	public void setBuses(List<Bus> buses) {
415 		this.buses = buses;
416 	}
417 
418 	public Bus getBus(long id) {
419 		Bus bus = null;
420 		if (null == getBuses()) {
421 			loadBusLocations();
422 		}
423 		for (Bus b : getBuses()) {
424 			if (bus != null) {
425 				break;
426 			}
427 			if (b.getId() == id) {
428 				bus = b;
429 			}
430 		}
431 		return bus;
432 	}
433 
434 	/**
435 	 * @return the busStopUrl
436 	 */
437 	public String getBusStopUrl() {
438 		return busStopUrl;
439 	}
440 
441 	/**
442 	 * @param busStopUrl
443 	 *            the busStopUrl to set
444 	 */
445 	public void setBusStopUrl(String busStopUrl) {
446 		this.busStopUrl = busStopUrl;
447 	}
448 
449 	/**
450 	 * @return the busRouteUrl
451 	 */
452 	public String getBusRouteUrl() {
453 		return busRouteUrl;
454 	}
455 
456 	/**
457 	 * @param busRouteUrl
458 	 *            the busRouteUrl to set
459 	 */
460 	public void setBusRouteUrl(String busRouteUrl) {
461 		this.busRouteUrl = busRouteUrl;
462 	}
463 
464 	/**
465 	 * @return the busLocationUrl
466 	 */
467 	public String getBusLocationUrl() {
468 		return busLocationUrl;
469 	}
470 
471 	/**
472 	 * @param busLocationUrl
473 	 * the busLocationUrl to set
474 	 */
475 	public void setBusLocationUrl(String busLocationUrl) {
476 		this.busLocationUrl = busLocationUrl;
477 	}
478 
479     /**
480      * @return the busStopNameMapper
481      */
482     public BusStopNameUtil getBusStopNameMapper() {
483         return busStopNameMapper;
484     }
485 
486     /**
487      * @param busStopNameMapper the busStopNameMapper to set
488      */
489     public void setBusStopNameMapper(BusStopNameUtil busStopNameMapper) {
490         this.busStopNameMapper = busStopNameMapper;
491     }
492 
493 	public String getBusRoutePathUrl() {
494 		return busRoutePathUrl;
495 	}
496 
497 	public void setBusRoutePathUrl(String busRoutePathUrl) {
498 		this.busRoutePathUrl = busRoutePathUrl;
499 	}
500 
501 	public String getBusAlertUrl() {
502 		return busAlertUrl;
503 	}
504 
505 	public void setBusAlertUrl(String busAlertUrl) {
506 		this.busAlertUrl = busAlertUrl;
507 	}
508 
509 	public List<BusAlert> getAlerts() {
510 		return alerts;
511 	}
512 
513 	public void setAlerts(List<BusAlert> alerts) {
514 		this.alerts = alerts;
515 	}
516 }