package dk.thoerup.traininfoservice; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.jdo.Extent; import javax.jdo.PersistenceManager; import javax.jdo.Query; import net.sf.jsr107cache.Cache; import net.sf.jsr107cache.CacheException; import net.sf.jsr107cache.CacheManager; import com.google.appengine.api.memcache.jsr107cache.GCacheFactory; import dk.thoerup.android.traininfo.common.StationBean; import dk.thoerup.android.traininfo.common.StationEntry; import dk.thoerup.traininfoservice.geo.Geo; import dk.thoerup.traininfoservice.jdo.JdoStationBean; import dk.thoerup.traininfoservice.jdo.PMF; public class StationDAO { final static int LOCATION_LIMIT = 8; static final Logger logger = Logger.getLogger(StationDAO.class.getName()); final int TIMEOUT_SECONDS = 30*60; Cache cache; @SuppressWarnings("unchecked") public StationDAO() { Map props = new HashMap(); props.put(GCacheFactory.EXPIRATION_DELTA, TIMEOUT_SECONDS); try { cache = CacheManager.getInstance().getCacheFactory().createCache(props); } catch (CacheException e) { logger.log(Level.WARNING, "error creating cache", e); } } public StationEntry getById(int id) { PersistenceManager pm = null; try { pm = PMF.get().getPersistenceManager(); JdoStationBean bean =pm.getObjectById(JdoStationBean.class, new Integer(id) ); return bean.toStationEntry(); } finally { pm.close(); } } /* damn that JDO sucks so we to the filtering in java-code */ public StationBean getByName(String searchname) { List beanList = getAllStations(); StationBean stationBean = new StationBean(); searchname = searchname.toLowerCase(); for(JdoStationBean bean : beanList) { if (bean.getName().toLowerCase().startsWith(searchname)) { stationBean.entries.add( bean.toStationEntry() ); } /*else { for (String alias : bean.aliases ) { if (alias.toLowerCase().startsWith(searchname)) { stationBean.entries.add( bean.toStationEntry() ); } } }*/ } Collections.sort(stationBean.entries, new Comparator() { @Override public int compare(StationEntry arg0, StationEntry arg1) { return arg0.getName().compareTo( arg1.getName() ); } }); return stationBean; } @SuppressWarnings("unchecked") public List getAllStations() { final String key = "allstations"; List result = (List) cache.get(key); if (result == null) { logger.info("getAllStations Cache miss"); PersistenceManager pm = null; try { pm = PMF.get().getPersistenceManager(); Extent all = pm.getExtent(JdoStationBean.class, false); result = new ArrayList(); for (JdoStationBean station : all) { result.add(station); } cache.put(key, result); } finally { pm.close(); } } else { logger.info("getAllStations Cache hit"); } return result; } //String limitExpression = (geolimit == true) ? "AND abs(latitude-?)<0.4 AND abs(longitude-?)<0.75 " : ""; /* public List getByLocationList(double latitude, double longitude, boolean geolimit) { PersistenceManager pm = null; final double LAT = 0.4; final double LNG = 0.75; try { pm = PMF.get().getPersistenceManager(); Query q = pm.newQuery(JdoStationBean.class); if (geolimit == true) { double minLat = latitude - LAT; double maxLat = latitude + LAT; //DAMN JDO implementation only allows us to compare on one parameter String filter = String.format("latitude > %f && latitude < %f", minLat, maxLat); q.setFilter( filter ); } List beanList = (List) q.execute(); logger.info("beanList size " + beanList.size()); return beanList; } finally { pm.close(); } }*/ public StationBean getByLocation(double latitude, double longitude) { List beanList = getAllStations(); StationBean stationBean = new StationBean(); Geo location = new Geo(latitude,longitude); for(JdoStationBean bean : beanList) { double meter = Geo.distanceKM( location, new Geo(bean.getLatitude(), bean.getLongitude() )) * 1000.0; bean.distance = (int) meter; } Collections.sort(beanList, new Comparator() { @Override public int compare(JdoStationBean o1, JdoStationBean o2) { if (o1.distance < o2.distance) { return -1; } else if (o1.distance > o2.distance) { return 1; } else { return 0; } } }); for (int i=0; i 0) { filter.append( " || " ); } filter.append("id == ").append(part); } pm = PMF.get().getPersistenceManager(); Query q = pm.newQuery(JdoStationBean.class); q.setFilter( filter.toString() ); q.setOrdering("name"); List beanList = (List) q.execute(); StationBean stationBean = new StationBean(); for(JdoStationBean bean : beanList) { stationBean.entries.add( bean.toStationEntry() ); } return stationBean; } finally { pm.close(); } } @SuppressWarnings("unchecked") public int getIdByName(String name) { List beanList = null; PersistenceManager pm = null; try { String filter = " name == '" + name + "'"; pm = PMF.get().getPersistenceManager(); Query q = pm.newQuery(JdoStationBean.class); q.setFilter(filter); beanList = (List) q.execute(); StationBean stationBean = new StationBean(); for(JdoStationBean bean : beanList) { stationBean.entries.add( bean.toStationEntry() ); } } finally { pm.close(); } if ( beanList != null && beanList.size() == 1) { return (int) beanList.get(0).getId(); } else { return -1; } } @SuppressWarnings("unchecked") public int saveStations(StationBean stationBean) throws IOException { PersistenceManager pm = null; try { pm = PMF.get().getPersistenceManager(); List oldEntries = (List) pm.newQuery(JdoStationBean.class).execute(); pm.deletePersistentAll(oldEntries); List jdoList = new ArrayList(); for (StationEntry station : stationBean.entries) { JdoStationBean jdoBean = JdoStationBean.fromStationEntry(station); jdoList.add(jdoBean); } pm.makePersistentAll(jdoList); return jdoList.size(); } finally { pm.close(); } } }