From 2c83351eb6be01457ba6497ebfb5f9011ea94546 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 12 Sep 2012 20:03:21 +0000 Subject: [PATCH] NIHVIVO-3956 SPARQL-based implementations of getMostSpecificTypeURIs() getDataValue() and isVClass() to shorten render time of short views --- .../vitro/webapp/beans/Individual.java | 4 +- .../vitro/webapp/beans/IndividualImpl.java | 15 ++ .../dao/filtering/IndividualFiltering.java | 5 + .../vitro/webapp/dao/jena/IndividualSDB.java | 145 ++++++++++++++++-- .../shortview/ShortViewServiceImpl.java | 6 +- .../vitro/webapp/beans/IndividualStub.java | 5 + 6 files changed, 157 insertions(+), 23 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Individual.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Individual.java index c2674513f..e9892ba4b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Individual.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Individual.java @@ -66,7 +66,9 @@ public interface Individual extends ResourceBean, Comparable { void setVClasses(List vClassList, boolean direct); /** Does the individual belong to this class? */ - boolean isVClass(String uri); + boolean isVClass(String uri); + + List getMostSpecificTypeURIs(); void setObjectPropertyStatements(List list); List getObjectPropertyStatements(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java index b96dbfedc..5cd873bdf 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java @@ -18,6 +18,7 @@ import java.util.TreeSet; import org.json.JSONException; import org.json.JSONObject; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; @@ -208,6 +209,20 @@ public class IndividualImpl extends BaseResourceBean implements Individual, Comp this.allVClasses = vClassList; } } + + @Override + public List getMostSpecificTypeURIs() { + List typeURIs = new ArrayList(); + List stmts = getObjectPropertyStatements( + VitroVocabulary.MOST_SPECIFIC_TYPE); + for (ObjectPropertyStatement stmt : stmts) { + String objURI = stmt.getObjectURI(); + if (objURI != null) { + typeURIs.add(objURI); + } + } + return typeURIs; + } public void setObjectPropertyStatements(List list) { objectPropertyStatements = list; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java index f17f0f171..376445742 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java @@ -369,6 +369,11 @@ public class IndividualFiltering implements Individual { return _innerIndividual.isVClass(uri); } + @Override + public List getMostSpecificTypeURIs() { + return _innerIndividual.getMostSpecificTypeURIs(); + } + @Override public void setDataPropertyMap(Map propertyMap) { _innerIndividual.setDataPropertyMap(propertyMap); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java index fed8a1b39..c2467f412 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; +import java.io.InputStream; import java.sql.Timestamp; import java.text.Collator; import java.util.ArrayList; @@ -28,6 +29,7 @@ import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.ResultSetFactory; import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; @@ -43,6 +45,7 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; @@ -269,6 +272,32 @@ public class IndividualSDB extends IndividualImpl implements Individual { return (clist.size() > 0) ? clist.get(0) : null ; } } + + @Override + public List getMostSpecificTypeURIs() { + List typeURIs = new ArrayList(); + if (this.getURI() == null) { + return typeURIs; + } else { + String queryStr = "SELECT ?type WHERE { <" + this.getURI() + "> <" + + VitroVocabulary.MOST_SPECIFIC_TYPE + "> ?type }"; + try { + InputStream json = webappDaoFactory.getRDFService().sparqlSelectQuery( + queryStr, RDFService.ResultFormat.JSON); + ResultSet rs = ResultSetFactory.fromJSON(json); + while (rs.hasNext()) { + QuerySolution qsoln = rs.nextSolution(); + RDFNode node = qsoln.get("type"); + if (node.isURIResource()) { + typeURIs.add(node.asResource().getURI()); + } + } + return typeURIs; + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + } public Timestamp getModTime() { if (modTime != null) { @@ -676,7 +705,98 @@ public class IndividualSDB extends IndividualImpl implements Individual { return map; } } + + @Override + public List getDataPropertyStatements(String propertyUri) { + List stmts = this.dataPropertyStatements; + if (stmts == null) { + return sparqlForDataPropertyStatements(propertyUri); + } else { + List stmtsForProp = new ArrayList(); + for (DataPropertyStatement stmt : stmts) { + if (stmt.getDatapropURI().equals(propertyUri)) { + stmtsForProp.add(stmt); + } + } + return stmtsForProp; + } + } + + @Override + public String getDataValue(String propertyUri) { + if (propertyUri == null) { + log.error("Cannot retrieve value for null property"); + return null; + } else if (this.getURI() == null) { + log.error("Cannot retrieve value of property " + propertyUri + + " for anonymous individual"); + return null; + } else { + List stmts = sparqlForDataPropertyStatements( + propertyUri); + if (stmts != null && stmts.size() > 0) { + return stmts.get(0).getData(); + } + } + return null; // not found + } + + @Override + public List getDataValues(String propertyUri) { + List values = new ArrayList(); + if (propertyUri == null) { + log.error("Cannot retrieve value for null property"); + return null; + } else if (this.getURI() == null) { + log.error("Cannot retrieve value of property " + propertyUri + + " for anonymous individual"); + return null; + } else { + List stmts = sparqlForDataPropertyStatements( + propertyUri); + if (stmts != null) { + for (DataPropertyStatement stmt : stmts) { + values.add(stmt.getData()); + } + } + return values; + } + } + private List sparqlForDataPropertyStatements(String propertyUri) { + List stmts = new ArrayList(); + String queryStr = "SELECT (str(?value) as ?valueString) WHERE { <" + + this.getURI() + "> <" + propertyUri + "> ?value }"; + try { + InputStream json = webappDaoFactory.getRDFService().sparqlSelectQuery( + queryStr, RDFService.ResultFormat.JSON); + ResultSet rs = ResultSetFactory.fromJSON(json); + while (rs.hasNext()) { + QuerySolution qsoln = rs.nextSolution(); + RDFNode node = qsoln.get("valueString"); + if (!node.isLiteral()) { + log.debug("Ignoring non-literal value for " + node + + " for property " + propertyUri); + } else { + Literal lit = node.asLiteral(); + DataPropertyStatement stmt = new DataPropertyStatementImpl(); + + stmt.setData(lit.getLexicalForm()); + stmt.setDatatypeURI(lit.getDatatypeURI()); + stmt.setLanguage(lit.getLanguage()); + stmt.setDatapropURI(propertyUri); + stmt.setIndividualURI(this.getURI()); + stmt.setIndividual(this); + stmts.add(stmt); + } + } + } catch (RDFServiceException e) { + log.error(e,e); + throw new RuntimeException(e); + } + return stmts; + } + public List getExternalIds() { if (this.externalIds != null) { return this.externalIds; @@ -830,25 +950,16 @@ public class IndividualSDB extends IndividualImpl implements Individual { * any of the super classes of the direct classes will satisfy this request. */ @Override - public boolean isVClass(String uri) { - if (uri == null) { + public boolean isVClass(String uri) { + if (uri == null || this.getURI() == null) { return false; } - - if (super.isVClass(uri)) { - return true; - } - - VClassDao vclassDao = webappDaoFactory.getVClassDao(); - for (VClass vClass : getVClasses(true)) { - for (String superClassUri: vclassDao.getAllSuperClassURIs( - vClass.getURI())) { - if (uri.equals(superClassUri)) { - return true; - } - } - } - return false; + String queryString = "ASK { <" + this.getURI() + "> a <" + uri + "> }"; + try { + return webappDaoFactory.getRDFService().sparqlAskQuery(queryString); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/services/shortview/ShortViewServiceImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/services/shortview/ShortViewServiceImpl.java index d8223d70f..8e18208a0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/services/shortview/ShortViewServiceImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/services/shortview/ShortViewServiceImpl.java @@ -102,11 +102,7 @@ public class ShortViewServiceImpl implements ShortViewService { /** Get most specific classes from Individual, sorted by alpha. */ private SortedSet figureMostSpecificClassUris(Individual individual) { SortedSet classUris = new TreeSet(); - List stmts = individual - .getObjectPropertyStatements(VitroVocabulary.MOST_SPECIFIC_TYPE); - for (ObjectPropertyStatement stmt : stmts) { - classUris.add(stmt.getObjectURI()); - } + classUris.addAll(individual.getMostSpecificTypeURIs()); return classUris; } diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/beans/IndividualStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/beans/IndividualStub.java index 1a80f30e2..07ab426c3 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/beans/IndividualStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/beans/IndividualStub.java @@ -259,6 +259,11 @@ public class IndividualStub implements Individual { "Comparable.compareTo() not implemented."); } + @Override + public List getMostSpecificTypeURIs() { + throw new RuntimeException("Individual.getMostSpecificTypeURIs() not implemented."); + } + @Override public String getRdfsLabel() { throw new RuntimeException("Individual.getRdfsLabel() not implemented.");