package esl.cuenet.source.accessors; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.ontology.OntModel; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.util.JSON; import esl.cuenet.query.IResultIterator; import esl.cuenet.query.IResultSet; import esl.cuenet.query.ResultIterator; import esl.cuenet.query.drivers.webjson.HttpDownloader; import esl.cuenet.source.AccesorInitializationException; import esl.cuenet.source.Attribute; import esl.cuenet.source.IAccessor; import esl.cuenet.source.SourceQueryException; import esl.datastructures.Location; import esl.datastructures.TimeInterval; import org.apache.log4j.Logger; import java.io.IOException; import java.util.List; public class YahooPlaceFinderAPI implements IAccessor { private Logger logger = Logger.getLogger(YahooPlaceFinderAPI.class); private Attribute[] attributes = null; private boolean[] setFlags = new boolean[3]; private OntModel model = null; public YahooPlaceFinderAPI() {} public YahooPlaceFinderAPI(OntModel model) { this.model = model; } Double lat, lon; String address; public BasicDBObject findAddress() throws IOException { StringBuilder urlBuilder = new StringBuilder("http://where.yahooapis.com/geocode?q="); urlBuilder.append(lat).append(',').append(lon); urlBuilder.append("&gflags=R&flags=J&appid=UmMtXR7c"); HttpDownloader downloader = new HttpDownloader(); byte[] bResult = downloader.get(urlBuilder.substring(0)); BasicDBObject resultJsonObject = (BasicDBObject) JSON.parse(new String(bResult)); BasicDBObject yahooResultSet = (BasicDBObject) resultJsonObject.get("ResultSet"); if (yahooResultSet == null) return null; if (yahooResultSet.getInt("Error") != 0) { logger.info("No valid response from Yahoo Place Finder"); return null; } BasicDBList results = (BasicDBList) yahooResultSet.get("Results"); if (results == null) return null; if (results.size() > 1) logger.info("LocationFetcher got more than one location"); if (results.size() == 0) return null; return (BasicDBObject) results.get(0); } public BasicDBObject findLatLon() throws IOException { StringBuilder urlBuilder = new StringBuilder("http://where.yahooapis.com/geocode?q="); urlBuilder.append(address.replaceAll(" ", "+")); urlBuilder.append("&flags=J&appid=UmMtXR7c"); HttpDownloader downloader = new HttpDownloader(); byte[] bResult = downloader.get(urlBuilder.substring(0)); BasicDBObject resultJsonObject = (BasicDBObject) JSON.parse(new String(bResult)); BasicDBObject yahooResultSet = (BasicDBObject) resultJsonObject.get("ResultSet"); if (yahooResultSet == null) return null; if (yahooResultSet.getInt("Error") != 0) { logger.info("No valid response from Yahoo Place Finder"); return null; } BasicDBList results = (BasicDBList) yahooResultSet.get("Results"); if (results == null) return null; if (results.size() > 1) logger.info("LocationFetcher got more than one location"); if (results.size() == 0) return null; return (BasicDBObject) results.get(0); } @Override public void setAttributeNames(Attribute[] attributes) throws AccesorInitializationException { if (attributes.length != 3) throw new AccesorInitializationException("Invalid number of attributes for " + YahooPlaceFinderAPI.class.getName()); this.attributes = attributes; } @Override public void start() { for (int i=0; i<setFlags.length; i++) setFlags[i] = false; } @Override public void associateTimeInterval(Attribute attribute, TimeInterval timeInterval) throws AccesorInitializationException { throw new AccesorInitializationException("Incorrect Assignment: No time interval attributes in " + YahooPlaceFinderAPI.class.getName()); } @Override public void associateLocation(Attribute attribute, Location timeInterval) throws AccesorInitializationException { throw new AccesorInitializationException("Incorrect Assignment: No Location attributes in " + YahooPlaceFinderAPI.class.getName() + ". Use associateLong() instead."); } @Override public void associateLong(Attribute attribute, long value) throws AccesorInitializationException { throw new AccesorInitializationException("Incorrect Assignment: No integer attributes in " + YahooPlaceFinderAPI.class.getName()); } @Override public void associateString(Attribute attribute, String value) throws AccesorInitializationException { if (attribute.compareTo(attributes[2]) != 0) throw new AccesorInitializationException("String value being initialized for wrong attribute " + YahooPlaceFinderAPI.class.getName()); address = value; setFlags[2] = true; } @Override public void associateDouble(Attribute attribute, double value) throws AccesorInitializationException { if (attribute.compareTo(attributes[0]) == 0) { setFlags[0] = true; this.lat = value; } else if (attribute.compareTo(attributes[1])==0) { setFlags[1] = true; this.lon = value; } else throw new AccesorInitializationException("Double value being initialized for wrong attribute " + YahooPlaceFinderAPI.class.getName()); } @Override public IResultSet executeQuery() throws SourceQueryException { boolean areParamsAvailable = false; for (boolean b: setFlags) if (b) areParamsAvailable = true; if ( !areParamsAvailable ) throw new SourceQueryException("No parameters set"); BasicDBObject result = null; if (setFlags[0] && setFlags[1] && !setFlags[2]) try { result = findAddress(); } catch (IOException e) { throw new SourceQueryException("Internal IOException: " + e.getMessage()); } else if (!setFlags[0] && !setFlags[1] && setFlags[2]) try { result = findLatLon(); } catch (IOException e) { throw new SourceQueryException("Internal IOException: " + e.getMessage()); } else throw new SourceQueryException("Invalid Combination of Parameters"); return new ResultSetImpl(result.toString(), model); } public BasicDBObject findAddress(double lat, double lon) throws IOException { this.lat = lat; this.lon = lon; return findAddress(); } public BasicDBObject findLatLon(String address) throws IOException { this.address = address; return findLatLon(); } }