/** * Copyright (c) 2011 Ontology Engineering Group, * Departamento de Inteligencia Artificial, * Facultad de Informetica, Universidad * Politecnica de Madrid, Spain * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package es.upm.fi.dia.oeg.map4rdf.server.dao.impl; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import com.google.inject.Inject; import com.google.inject.name.Named; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.vocabulary.RDFS; import es.upm.fi.dia.oeg.map4rdf.share.conf.ParameterNames; import es.upm.fi.dia.oeg.map4rdf.server.dao.DaoException; import es.upm.fi.dia.oeg.map4rdf.server.dao.Map4rdfDao; import es.upm.fi.dia.oeg.map4rdf.server.vocabulary.Geo; import es.upm.fi.dia.oeg.map4rdf.share.BoundingBox; import es.upm.fi.dia.oeg.map4rdf.share.Facet; import es.upm.fi.dia.oeg.map4rdf.share.FacetConstraint; import es.upm.fi.dia.oeg.map4rdf.share.GeoResource; import es.upm.fi.dia.oeg.map4rdf.share.GeoResourceOverlay; import es.upm.fi.dia.oeg.map4rdf.share.PointBean; import es.upm.fi.dia.oeg.map4rdf.share.Resource; import es.upm.fi.dia.oeg.map4rdf.share.StatisticDefinition; import es.upm.fi.dia.oeg.map4rdf.share.Year; /** * @author Alexander De Leon */ public class DbPediaDaoImpl extends CommonDaoImpl implements Map4rdfDao { private static final Logger LOG = Logger.getLogger(DbPediaDaoImpl.class); @Inject public DbPediaDaoImpl(@Named(ParameterNames.ENDPOINT_URL) String endpointUri,String defaultProjection) { super(endpointUri,defaultProjection); } @Override public GeoResource getGeoResource(String uri) throws DaoException { QueryExecution execution = QueryExecutionFactory.sparqlService(endpointUri, createGetResourceQuery(uri)); try { ResultSet queryResult = execution.execSelect(); GeoResource resource = null; while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); try { double lat = solution.getLiteral("lat").getDouble(); double lng = solution.getLiteral("lng").getDouble(); if (resource == null) { resource = new GeoResource(uri, new PointBean(uri, lng, lat,defaultProjection)); } if (solution.contains("label")) { Literal labelLiteral = solution.getLiteral("label"); resource.addLabel(labelLiteral.getLanguage(), labelLiteral.getString()); } } catch (NumberFormatException e) { LOG.warn("Invalid Latitud or Longitud value: " + e.getMessage()); } } return resource; } catch (Exception e) { LOG.error(e); throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } @Override public List<GeoResource> getGeoResources(BoundingBox boundingBox, Set<FacetConstraint> constraints) throws DaoException { return getGeoResources(boundingBox, constraints, null); } @Override public List<GeoResource> getGeoResources(BoundingBox boundingBox, Set<FacetConstraint> constraints, int max) throws DaoException { return getGeoResources(boundingBox, constraints, new Integer(max)); } @Override public List<GeoResourceOverlay> getGeoResourceOverlays(StatisticDefinition statisticDefinition, BoundingBox boundingBox, Set<FacetConstraint> constraints) throws DaoException { // TODO What can be done here? return Collections.emptyList(); } @Override public List<Facet> getFacets(String predicateUri, BoundingBox boundingBox) throws DaoException { Map<String, Facet> result = new HashMap<String, Facet>(); StringBuilder queryBuffer = new StringBuilder(); queryBuffer.append("select distinct ?class ?label where { "); queryBuffer.append("?x <" + Geo.lat + "> _:lat. "); queryBuffer.append("?x <" + Geo.lng + "> _:lng. "); queryBuffer.append("?x <" + predicateUri + "> ?class . "); queryBuffer.append("optional {?class <" + RDFS.label + "> ?label . }}"); QueryExecution execution = QueryExecutionFactory.sparqlService(endpointUri, queryBuffer.toString()); try { ResultSet queryResult = execution.execSelect(); while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); String uri = solution.getResource("class").getURI(); Facet value = null; if (result.containsKey(uri)) { value = result.get(uri); } else { value = new Facet(uri); result.put(uri, value); } if (solution.contains("label")) { Literal label = solution.getLiteral("label"); value.addLabel(label.getLanguage(), label.getString()); } } return new ArrayList<Facet>(result.values()); } catch (Exception e) { LOG.error(e); throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } @Override public List<Year> getYears(String datasetUri) throws DaoException { // TODO not applicable return Collections.emptyList(); } @Override public List<Resource> getStatisticDatasets() throws DaoException { // TODO What can be done here? return Collections.emptyList(); } /* --------------------- helper methods --- */ @Override public List<GeoResource> getNextPoints(BoundingBox boundingBox, int max) throws DaoException { HashMap<String, GeoResource> result = new HashMap<String, GeoResource>(); QueryExecution execution = QueryExecutionFactory.sparqlService(endpointUri, createGetNextPointsQuery(boundingBox, max)); try { ResultSet queryResult = execution.execSelect(); while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); try { String uri = solution.getResource("r").getURI(); double lat = solution.getLiteral("lat").getDouble(); double lng = solution.getLiteral("lng").getDouble(); GeoResource resource = result.get(uri); if (resource == null) { resource = new GeoResource(uri, new PointBean(uri, lng, lat,defaultProjection)); result.put(uri, resource); } if (solution.contains("label")) { Literal labelLiteral = solution.getLiteral("label"); resource.addLabel(labelLiteral.getLanguage(), labelLiteral.getString()); } } catch (NumberFormatException e) { LOG.warn("Invalid Latitud or Longitud value: " + e.getMessage()); } } return new ArrayList<GeoResource>(result.values()); } catch (Exception e) { LOG.error(e); throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } //TODO implement Wikipedia link in DBPedia Dao(ALL METHODS) private List<GeoResource> getGeoResources(BoundingBox boundingBox, Set<FacetConstraint> constraints, Integer max) throws DaoException { HashMap<String, GeoResource> result = new HashMap<String, GeoResource>(); QueryExecution execution = QueryExecutionFactory.sparqlService(endpointUri, createGetResourcesQuery(boundingBox, constraints, max)); if(constraints!=null && constraints.isEmpty()){ return new ArrayList<GeoResource>(); } try { ResultSet queryResult = execution.execSelect(); while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); try { String uri = solution.getResource("r").getURI(); double lat = solution.getLiteral("lat").getDouble(); double lng = solution.getLiteral("lng").getDouble(); GeoResource resource = result.get(uri); if (resource == null) { resource = new GeoResource(uri, new PointBean(uri, lng, lat,defaultProjection)); result.put(uri, resource); } if (solution.contains("label")) { Literal labelLiteral = solution.getLiteral("label"); if(!resource.getLangs().contains(labelLiteral.getLanguage())){ resource.addLabel(labelLiteral.getLanguage(), labelLiteral.getString()); } } if(solution.contains("facetID") && solution.contains("facetValueID")){ String facetID=solution.getResource("facetID").getURI(); String facetValueID=solution.getResource("facetValueID").getURI(); resource.setFacetConstraint(new FacetConstraint(facetID, facetValueID)); } } catch (NumberFormatException e) { LOG.warn("Invalid Latitud or Longitud value: " + e.getMessage()); } } return new ArrayList<GeoResource>(result.values()); } catch (Exception e) { LOG.error(e); throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } /** * @param boundingBox * @param constraints * @param max * @return */ private String createGetResourcesQuery(BoundingBox boundingBox, Set<FacetConstraint> constraints, Integer limit) { StringBuilder query = new StringBuilder("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT distinct ?r ?label ?lat ?lng ?facetID ?facetValueID "); query.append("WHERE { "); query.append("?r <" + Geo.lat + "> ?lat. "); query.append("?r <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { ?r <" + RDFS.label + "> ?label } ."); if (constraints != null && !constraints.isEmpty()) { query.append("?r ?facetID ?facetValueID. "); query.append("FILTER("); for (FacetConstraint constraint : constraints) { query.append("(?facetID IN("); query.append("<"+constraint.getFacetId()+">)"); query.append(" && ?facetValueID IN("); query.append("<"+constraint.getFacetValueId()+">)) || "); } query.delete(query.length() - 3, query.length()); query.append(")."); } //filters if (boundingBox!=null) { query = addBoundingBoxFilter(query, boundingBox); } query.append("}"); if (limit != null) { query.append(" LIMIT " + limit); } return query.toString(); } private String createGetResourceQuery(String uri) { StringBuilder query = new StringBuilder("SELECT distinct ?lat ?lng ?label "); query.append("WHERE { "); query.append("<" + uri + "> <" + Geo.lat + "> ?lat. "); query.append("<" + uri + "> <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { <" + uri + "> <" + RDFS.label + "> ?label } ."); query.append("}"); return query.toString(); } private String createGetNextPointsQuery(BoundingBox boundingBox, int max){ StringBuilder query = new StringBuilder("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT distinct ?r ?label ?lat ?lng "); query.append("WHERE { "); query.append("?r <" + Geo.lat + "> ?lat. "); query.append("?r <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { ?r <" + RDFS.label + "> ?label } ."); //filters if (boundingBox!=null) { query = addBoundingBoxFilter(query, boundingBox); } query.append("}"); if (max > 0) { query.append(" LIMIT " + max); } return query.toString(); } }