From 90b7ead4808f89c7e5f779e5fa75b2aa8966023f Mon Sep 17 00:00:00 2001 From: deepakkoni Date: Wed, 13 Jul 2011 22:07:17 +0000 Subject: [PATCH] NIHVIVO-2834 - Modify incremental indexing to account for changes to individuals linked through context nodes --- .../AdditionalURIsForContextNodes.java | 159 +++++++++++++++++- .../webapp/search/indexing/IndexBuilder.java | 34 +++- 2 files changed, 182 insertions(+), 11 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForContextNodes.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForContextNodes.java index c05bbdbc1..9e3046884 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForContextNodes.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForContextNodes.java @@ -2,23 +2,172 @@ package edu.cornell.mannlib.vitro.webapp.search.indexing; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +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.QuerySolutionMap; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.Syntax; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.shared.Lock; public class AdditionalURIsForContextNodes implements AdditionalURIsToIndex { private OntModel model; - + private static final List multiValuedQueriesForAgent = new ArrayList(); + private static final String multiValuedQueryForInformationResource; + private Log log = LogFactory.getLog(AdditionalURIsForContextNodes.class); + + public AdditionalURIsForContextNodes( OntModel jenaOntModel){ this.model = jenaOntModel; } @Override public List findAdditionalURIsToIndex(String uri) { - // TODO Auto-generated method stub - return Collections.emptyList(); - } + + List queryList = new ArrayList(); + queryList.add(multiValuedQueryForInformationResource); + queryList.addAll(multiValuedQueriesForAgent); + + List uriList = new ArrayList(); + for(String query : queryList){ + + //log.info("Executing query: "+ query); + + QuerySolutionMap initialBinding = new QuerySolutionMap(); + Resource uriResource = ResourceFactory.createResource(uri); + initialBinding.add("uri", uriResource); + + Query sparqlQuery = QueryFactory.create( query, Syntax.syntaxARQ); + model.getLock().enterCriticalSection(Lock.READ); + try{ + QueryExecution qExec = QueryExecutionFactory.create(sparqlQuery, model, initialBinding); + try{ + ResultSet results = qExec.execSelect(); + while(results.hasNext()){ + QuerySolution soln = results.nextSolution(); + Iterator iter = soln.varNames() ; + while( iter.hasNext()){ + String name = iter.next(); + RDFNode node = soln.get( name ); + if( node != null ){ + uriList.add("" + node.toString()); + }else{ + log.debug(name + " is null"); + } + } + } + }catch(Throwable t){ + log.error(t,t); + } finally{ + qExec.close(); + } + }finally{ + model.getLock().leaveCriticalSection(); + } + } + + return uriList; + } + + + private static final String prefix = "prefix owl: " + + " prefix vitroDisplay: " + + " prefix rdf: " + + " prefix core: " + + " prefix foaf: " + + " prefix rdfs: " + + " prefix localNav: " + + " prefix bibo: "; + + static{ + multiValuedQueriesForAgent.add(prefix + + "SELECT " + + " (str(?f) as ?positionForPerson) (str(?i) as ?positionInOrganization) " + + " WHERE {" + + + "?uri rdf:type foaf:Agent ; ?b ?c . " + + " ?c rdf:type core:Position . " + + + " OPTIONAL { ?c core:positionForPerson ?f . } . " + + " OPTIONAL { ?c core:positionInOrganization ?i . } . " + + " }"); + + multiValuedQueriesForAgent.add(prefix + + "SELECT (str(?d) as ?advisee) " + + " (str(?f) as ?linkedAuthor) (str(?h) as ?linkedInformationResource) WHERE {" + + + "?uri rdf:type foaf:Agent ; ?b ?c . " + + " ?c rdf:type core:Relationship . " + + + " OPTIONAL { ?c core:advisee ?d . } . " + + " OPTIONAL { ?c core:linkedAuthor ?f . } . " + + " OPTIONAL { ?c core:linkedInformationResource ?h . } . " + + + " } "); + + multiValuedQueriesForAgent.add(prefix + + "SELECT (str(?d) as ?awardConferredBy) (str(?e) as ?awardOrHonorFor) " + + "WHERE {" + + + "?uri rdf:type foaf:Agent ; ?b ?c . " + + " ?c rdf:type core:AwardReceipt . " + + + " OPTIONAL { ?c core:awardConferredBy ?d . } . " + + " OPTIONAL { ?c core:awardOrHonorFor ?e . } ." + + " }"); + + multiValuedQueriesForAgent.add(prefix + + "SELECT (str(?Organization) as ?organization) WHERE {" + + "?uri rdf:type foaf:Agent ; ?b ?c . " + + " ?c rdf:type core:Role ; core:roleIn ?Organization ." + + " }"); + + multiValuedQueriesForAgent.add(prefix + + "SELECT " + + "(str(?e) as ?trainingAtOrganization) WHERE {" + + + " ?uri rdf:type foaf:Agent ; ?b ?c . " + + " ?c rdf:type core:EducationalTraining . " + + + " OPTIONAL { ?c core:trainingAtOrganization ?e . } . " + + +"}"); + + } + + //multivalued query for core:InformationResource + static { + + multiValuedQueryForInformationResource = prefix + + "SELECT (str(?b) as ?linkedAuthor) (str(?d) as ?linkedInformationResource) " + + "(str(?e) as ?editor) " + + "(str(?i) as ?features) WHERE {" + + + " ?uri rdf:type core:InformationResource . " + + + "OPTIONAL { ?uri core:informationResourceInAuthorship ?a . ?a core:linkedAuthor ?b ; core:linkedInformationResource ?d ." + + "} . " + + "OPTIONAL { ?uri bibo:editor ?e . } ." + + " OPTIONAL { ?uri core:features ?i . } . " + + +"}" ; + + } + + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/IndexBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/IndexBuilder.java index a6c7928ad..71cce8857 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/IndexBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/IndexBuilder.java @@ -8,12 +8,15 @@ import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.query.QueryParseException; + import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -171,23 +174,42 @@ public class IndexBuilder extends Thread { * Sets updatedUris and deletedUris lists. */ private void makeAddAndDeleteLists( Collection uris){ + + uris.addAll(getAdditionalURIsToIndex(uris)); + /* clear updateInds and deletedUris. This is the only method that should set these. */ this.updatedInds = new ArrayList(); this.deletedInds = new ArrayList(); for( String uri: uris){ if( uri != null ){ - Individual ind = wdf.getIndividualDao().getIndividualByURI(uri); - if( ind != null) - this.updatedInds.add(uri); - else{ - log.debug("found delete in changed uris"); - this.deletedInds.add(uri); + try{ + Individual ind = wdf.getIndividualDao().getIndividualByURI(uri); + if( ind != null) + this.updatedInds.add(uri); + else{ + log.debug("found delete in changed uris"); + this.deletedInds.add(uri); + } + } catch(QueryParseException ex){ + log.error("could not get Individual "+ uri,ex); } } } } + private Set getAdditionalURIsToIndex(Collection uris) { + + Set listOfAdditionalURIs = new HashSet(); + + for(String uri: uris){ + //grab the uris from AdditionalURIsToIndex + listOfAdditionalURIs.addAll(additionalURIsFinders.get(0).findAdditionalURIsToIndex(uri)); + } + + return listOfAdditionalURIs; + } + /** * This rebuilds the whole index. */