From b9cd04f0fab57b385f198678a08bc9d7baa8ee07 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 27 Sep 2012 20:55:18 +0000 Subject: [PATCH] NIHVIVO-3974 preventing reproduction of axioms with blank nodes in filegraphs and NIHVIVO-3958 applying query syntax leniency to RDFServiceSparql --- .../rdfservice/impl/RDFServiceImpl.java | 27 ++++++++++++++++++- .../rdfservice/impl/jena/RDFServiceJena.java | 19 ------------- .../impl/sparql/RDFServiceSparql.java | 17 ++++++------ .../webapp/servlet/setup/FileGraphSetup.java | 17 ++++++------ .../webapp/utils/jena/JenaOutputUtils.java | 4 +++ 5 files changed, 47 insertions(+), 37 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java index 64d05f844..30e9502c7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java @@ -3,6 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.rdfservice.impl; import java.io.ByteArrayInputStream; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -13,7 +14,11 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QueryParseException; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Statement; @@ -31,7 +36,7 @@ public abstract class RDFServiceImpl implements RDFService { private static final Log log = LogFactory.getLog(RDFServiceImpl.class); protected static final String BNODE_ROOT_QUERY = - "SELECT ?s WHERE { ?s ?p ?o OPTIONAL { ?ss ?pp ?s } FILTER (!isBlank(?s) || !bound(?ss)) }"; + "SELECT DISTINCT ?s WHERE { ?s ?p ?o OPTIONAL { ?ss ?pp ?s } FILTER (!isBlank(?s) || !bound(?ss)) }"; protected String defaultWriteGraphURI; protected List registeredListeners = new CopyOnWriteArrayList(); @@ -261,4 +266,24 @@ public abstract class RDFServiceImpl implements RDFService { result[1] = nonBlankNodeModel; return result; } + + protected Query createQuery(String queryString) { + List syntaxes = Arrays.asList( + Syntax.defaultQuerySyntax, Syntax.syntaxSPARQL_11, + Syntax.syntaxSPARQL_10, Syntax.syntaxSPARQL, Syntax.syntaxARQ); + Query q = null; + Iterator syntaxIt = syntaxes.iterator(); + while (q == null) { + Syntax syntax = syntaxIt.next(); + try { + q = QueryFactory.create(queryString, syntax); + } catch (QueryParseException e) { + if (!syntaxIt.hasNext()) { + throw(e); + } + } + } + return q; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java index fbf6f9453..ddf192b84 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java @@ -359,25 +359,6 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic super.notifyListeners(triple, operation, graphURI); } - protected Query createQuery(String queryString) { - List syntaxes = Arrays.asList( - Syntax.defaultQuerySyntax, Syntax.syntaxSPARQL_11, - Syntax.syntaxSPARQL_10, Syntax.syntaxSPARQL, Syntax.syntaxARQ); - Query q = null; - Iterator syntaxIt = syntaxes.iterator(); - while (q == null) { - Syntax syntax = syntaxIt.next(); - try { - q = QueryFactory.create(queryString, syntax); - } catch (QueryParseException e) { - if (!syntaxIt.hasNext()) { - throw(e); - } - } - } - return q; - } - protected QueryExecution createQueryExecution(String queryString, Query q, Dataset d) { return QueryExecutionFactory.create(q, d); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java index 113a3d3b3..929303d4a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java @@ -13,9 +13,7 @@ import java.util.List; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.NameValuePair; -import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -49,7 +47,6 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.ChangeSetImpl; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.ListeningGraph; -import edu.cornell.mannlib.vitro.webapp.web.URLEncoder; /* * API to write, read, and update Vitro's RDF store, with support @@ -223,7 +220,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { RDFServiceImpl.ModelSerializationFormat resultFormat) throws RDFServiceException { Model model = ModelFactory.createDefaultModel(); - Query query = QueryFactory.create(queryStr); + Query query = createQuery(queryStr); QueryExecution qe = QueryExecutionFactory.sparqlService(readEndpointURI, query); try { @@ -253,7 +250,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { RDFServiceImpl.ModelSerializationFormat resultFormat) throws RDFServiceException { Model model = ModelFactory.createDefaultModel(); - Query query = QueryFactory.create(queryStr); + Query query = createQuery(queryStr); QueryExecution qe = QueryExecutionFactory.sparqlService(readEndpointURI, query); try { @@ -281,7 +278,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { @Override public InputStream sparqlSelectQuery(String queryStr, RDFService.ResultFormat resultFormat) throws RDFServiceException { - Query query = QueryFactory.create(queryStr); + Query query = createQuery(queryStr); QueryExecution qe = QueryExecutionFactory.sparqlService(readEndpointURI, query); try { @@ -323,7 +320,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { @Override public boolean sparqlAskQuery(String queryStr) throws RDFServiceException { - Query query = QueryFactory.create(queryStr); + Query query = createQuery(queryStr); QueryExecution qe = QueryExecutionFactory.sparqlService(readEndpointURI, query); try { @@ -465,7 +462,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { } } - protected void executeUpdate(String updateString) throws RDFServiceException { + protected void executeUpdate(String updateString) throws RDFServiceException { try { PostMethod meth = new PostMethod(updateEndpointURI); try { @@ -582,7 +579,7 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { @Override protected boolean sparqlSelectQueryHasResults(String queryStr) throws RDFServiceException { - Query query = QueryFactory.create(queryStr); + Query query = createQuery(queryStr); QueryExecution qe = QueryExecutionFactory.sparqlService(readEndpointURI, query); try { @@ -638,6 +635,8 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { Model blankNodeModel = ModelFactory.createDefaultModel(); blankNodeModel.add(blankNodeStatements); + + log.debug("update model size " + model.size()); log.debug("blank node model size " + blankNodeModel.size()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index dac4bd858..cbd3e77d9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -19,7 +19,6 @@ import javax.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.ontology.OntDocumentManager; import com.hp.hpl.jena.ontology.OntDocumentManager; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; @@ -29,7 +28,8 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; // This ContextListener must run after the JenaDataSourceSetup ContextListener @@ -50,9 +50,11 @@ public class FileGraphSetup implements ServletContextListener { try { + ServletContext ctx = sce.getServletContext(); OntDocumentManager.getInstance().setProcessImports(true); baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); Dataset dataset = JenaDataSourceSetupBase.getStartupDataset(sce.getServletContext()); + RDFServiceModelMaker maker = new RDFServiceModelMaker(RDFServiceUtils.getRDFServiceFactory(ctx)); // ABox files Set pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + ABOX); @@ -61,7 +63,7 @@ public class FileGraphSetup implements ServletContextListener { if (pathSet != null) { OntModel aboxBaseModel = baseOms.getABoxModel(); - aboxChanged = readGraphs(sce, pathSet, dataset, ABOX, aboxBaseModel); + aboxChanged = readGraphs(sce, pathSet, maker, ABOX, aboxBaseModel); } // TBox files @@ -71,7 +73,7 @@ public class FileGraphSetup implements ServletContextListener { if (pathSet != null) { OntModel tboxBaseModel = baseOms.getTBoxModel(); - tboxChanged = readGraphs(sce, pathSet, dataset, TBOX, tboxBaseModel); + tboxChanged = readGraphs(sce, pathSet, maker, TBOX, tboxBaseModel); } } catch (ClassCastException cce) { String errMsg = "Unable to cast servlet context attribute to the appropriate type " + cce.getLocalizedMessage(); @@ -105,7 +107,7 @@ public class FileGraphSetup implements ServletContextListener { * Note: no connection needs to be maintained between the in-memory copy of the * graph and the DB copy. */ - public boolean readGraphs(ServletContextEvent sce, Set pathSet, Dataset dataset, String type, OntModel baseModel) { + public boolean readGraphs(ServletContextEvent sce, Set pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel) { int count = 0; @@ -169,10 +171,9 @@ public class FileGraphSetup implements ServletContextListener { * Otherwise, if a graph with the given name is in the DB and is isomorphic with * the graph that was read from the files system, then do nothing. */ - public boolean updateGraphInDB(Dataset dataset, Model fileModel, String type, String path) { - + public boolean updateGraphInDB(RDFServiceModelMaker dataset, Model fileModel, String type, String path) { String graphURI = pathToURI(path,type); - Model dbModel = dataset.getNamedModel(graphURI); + Model dbModel = dataset.getModel(graphURI); boolean modelChanged = false; boolean isIsomorphic = dbModel.isIsomorphicWith(fileModel); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/JenaOutputUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/JenaOutputUtils.java index 6da2183ef..82ec60b2a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/JenaOutputUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/JenaOutputUtils.java @@ -28,6 +28,10 @@ public class JenaOutputUtils { Map prefixes = new HashMap(); List ontologies = wadf.getOntologyDao().getAllOntologies(); + // apparently this is null if empty + if (ontologies == null) { + return; + } Iterator iter = ontologies.iterator(); String namespace = null; String prefix = null;