package dk.thoerup.traininfoservice; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; import javax.jdo.PersistenceManager; import javax.jdo.Query; import dk.thoerup.android.traininfo.common.StationBean; import dk.thoerup.android.traininfo.common.StationBean.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()); 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) { PersistenceManager pm = null; try { pm = PMF.get().getPersistenceManager(); Query q = pm.newQuery(JdoStationBean.class); q.setOrdering("name"); List beanList = (List) q.execute(); 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() ); } } } } return stationBean; } finally { pm.close(); } } //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 = getByLocationList(latitude,longitude,true); if (beanList.size() < LOCATION_LIMIT ) { logger.info("getByLocation failover: " +latitude + "," + longitude); beanList = getByLocationList(latitude,longitude, false); } 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); } //String filter = "id == 10 || id == 82"; //TODO: build filter 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(); } } 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(); } } }