diff --git a/rdf/display/everytime/searchIndexerConfigurationVivo.n3 b/rdf/display/everytime/searchIndexerConfigurationVivo.n3 index 904d3457..b085807c 100644 --- a/rdf/display/everytime/searchIndexerConfigurationVivo.n3 +++ b/rdf/display/everytime/searchIndexerConfigurationVivo.n3 @@ -15,13 +15,10 @@ # ------------------------------------ -:uriFinder_forContextNodes +:extension_forContextNodes a , - . - -:uriFinder_forVCards - a , - . + , + . # ------------------------------------ @@ -29,14 +26,43 @@ a , . +# ------------------------------------ + +:vivoUriFinder_VCard + a , + ; + rdfs:label "Preferred title" ; + :hasPredicateRestriction "http://www.w3.org/2006/vcard/ns#title" ; + :hasPredicateRestriction "http://www.w3.org/2006/vcard/ns#email" ; + :hasSelectQuery """ + PREFIX vcard: + PREFIX obo: + SELECT ?uri + WHERE { + ?uri obo:ARG_2000028 ?card . + ?card a vcard:Individual . + ?card vcard:hasTitle ?subject . + } + """ ; + :hasSelectQuery """ + PREFIX vcard: + PREFIX obo: + SELECT ?uri + WHERE { + ?uri obo:ARG_2000028 ?card . + ?card a vcard:Individual . + ?card vcard:hasEmail ?subject . + } + """ . + :vivodocumentModifier_PreferredTitle - a , + a , ; rdfs:label "Preferred title" ; :hasTargetField "ALLTEXT" ; :hasTargetField "ALLTEXTUNSTEMMED" ; :hasTargetField "PREFERRED_TITLE" ; - :hasSparqlQuery """ + :hasSelectQuery """ PREFIX vcard: PREFIX obo: SELECT ?title @@ -49,10 +75,10 @@ """ . :vivodocumentModifier_EmailAddress - a , + a , ; rdfs:label "Email address" ; - :hasSparqlQuery """ + :hasSelectQuery """ PREFIX vcard: PREFIX obo: SELECT ?email @@ -63,483 +89,4 @@ ?emailHolder vcard:email ?email . } """ . -:vivodocumentModifier_NamesAcrossContextNodes - a , - ; - rdfs:label "Names of objects across context nodes" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri core:relatedBy ?rel . - ?rel rdf:type ?type . - ?rel core:relates ?other . - ?other rdfs:label ?rawresult . - FILTER ( ?type IN ( core:Position, core:Authorship, core:Collaboration, core:Affiliation ) ) - } - """ . -:vivodocumentModifier_AgentContextNodeFields - a , - ; - rdfs:label "Add many fields to agents." ; - :hasTypeRestriction "http://xmlns.com/foaf/0.1/foaf:Agent" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:Position . - ?c core:hrJobTitle ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:Position . - ?c core:relates ?i . - ?i rdf:type foaf:Organization . - ?i rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:Position . - ?c core:titleOrRole ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - SELECT (str(?HRJobTitle) as ?hrJobTitle) - (str(?PositionInOrganization) as ?positionInOrganization) - (str(?TitleOrRole) as ?titleOrRole) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:Position . - OPTIONAL { ?c core:hrJobTitle ?HRJobTitle . } . - OPTIONAL { ?c core:relates ?i . - ?i rdf:type foaf:Organization . - ?i rdfs:label ?PositionInOrganization . } . - OPTIONAL { ?c core:titleOrRole ?TitleOrRole . } . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:AdvisingRelationship . - ?c rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:AdvisingRelationship . - ?c core:degreeCandidacy ?e . - ?e rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?label) as ?adviseeLabel) - WHERE { - ?c rdf:type core:AdvisingRelationship . - ?c core:relates ?uri . - ?uri obo:RO_0000053 ?advisorRole . - ?advisorRole rdf:type core:AdvisorRole . - ?c core:relates ?d . - ?d rdf:type foaf:Person . - ?d obo:RO_0000053 ?adviseeRole . - ?adviseeRole rdf:type core:AdviseeRole . - ?d rdfs:label ?label . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?label) as ?advisorLabel) - WHERE { - ?c rdf:type core:AdvisingRelationship . - ?c core:relates ?uri . - ?uri obo:RO_0000053 ?adviseeRole . - ?adviseeRole rdf:type core:AdviseeRole . - ?c core:relates ?d . - ?d rdf:type foaf:Person . - ?d obo:RO_0000053 ?advisorRole . - ?advisorRole rdf:type core:AdvisorRole . - ?d rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:Authorship . - ?c core:relates ?f . - ?f rdf:type foaf:Person . - ?f rdfs:label ?ContextNodeProperty . - FILTER( ?f != ?uri ) - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:Authorship . - ?c core:relates ?h . - ?h rdf:type obo:IAO_0000030 . - ?h rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?AwardLabel) as ?awardLabel) - (str(?AwardConferredBy) as ?awardConferredBy) - (str(?Description) as ?description) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:AwardReceipt . - OPTIONAL { ?c core:relates ?e . ?e rdf:type core:Award . ?e rdfs:label ?AwardLabel . } . - OPTIONAL { ?c core:assignedBy ?d . ?d rdf:type foaf:Organization . ?d rdfs:label ?AwardConferredBy . } . - OPTIONAL { ?c core:description ?Description . } . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?OrganizationLabel) as ?organizationLabel) - WHERE { - ?uri ?b ?c . - ?c rdf:type obo:BFO_0000023 ; - core:roleContributesTo ?Organization . - ?Organization rdf:type core:Organization . - ?Organization rdfs:label ?OrganizationLabel . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?AcademicDegreeLabel) as ?academicDegreeLabel) - (str(?MajorField) as ?majorField) - (str(?DepartmentOrSchool) as ?departmentOrSchool) - (str(?TrainingAtOrganizationLabel) as ?trainingAtOrganizationLabel) - WHERE { - ?uri ?b ?c . - ?c rdf:type core:EducationalProcess . - OPTIONAL { ?c core:relates ?d . - ?d rdf:type core:AwardedDegree . - ?d core:relates ?e . - ?e rdf:type core:AcademicDegree . - ?e rdfs:label ?AcademicDegreeLabel . } . - OPTIONAL { ?c core:majorField ?MajorField .} . - OPTIONAL { ?c core:departmentOrSchool ?DepartmentOrSchool . } - OPTIONAL { ?c obo:RO_0000057 ?f . - ?f rdf:type foaf:organization . - ?f rdfs:label ?TrainingAtOrganizationLabel . } . - } - """ . - - -:vivodocumentModifier_MembershipFields - a , - ; - rdfs:label "Add people to organization and vice versa." ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri rdf:type foaf:Organization . - ?role core:roleContributesTo ?uri . - ?person obo:RO_0000053 ?role . - ?person rdfs:label ?rawresult . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri rdf:type foaf:Person . - ?uri obo:RO_0000053 / core:roleContributesTo / rdfs:label ?rawresult . - } - """ . - -:vivodocumentModifier_EducationFields - a , - ; - rdfs:label "Labels for a degree and the granting organization." ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri core:relates ?deg . - ?deg rdf:type core:AwardedDegree . - ?deg rdfs:label ?rawresult . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri core:relates ?deg . - ?deg rdf:type core:AwardedDegree . - ?deg core:assignedBy ?org . - ?org rdfs:label ?rawresult . - } - """ . - -:vivodocumentModifier_AdvisingFields - a , - ; - rdfs:label "Labels for people in an advising relationship." ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri core:relatedBy ?rel . - ?rel rdf:type core:AdvisingRelationship . - ?rel core:relates ?other . - ?other rdfs:label ?rawresult . - FILTER( ?other != ?uri ) - } - """ . - -:vivodocumentModifier_Grants_Projects_ForPerson - a , - ; - rdfs:label "Grants and projects for person" ; - :hasTypeRestriction "http://xmlns.com/foaf/0.1/Person" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - SELECT (str(?rawresult) as ?result) - WHERE { - ?grant core:relates ?uri . - ?grant rdf:type core:Grant . - ?grant rdfs:label ?rawresult . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) WHERE { - ?uri obo:RO_0000053 ?role . - ?role obo:BFO_0000054 ?project . - ?project rdf:type core:Project . - ?project rdfs:label ?rawresult . - } - """ . - -:vivodocumentModifier_People_Organizations_Projects_ForGrant - a , - ; - rdfs:label "People, organizations, and projects for grant" ; - :hasTypeRestriction "http://vivoweb.org/ontology/core#Grant" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - SELECT (str(?rawresult) as ?result) - WHERE { - ?uri core:relates ?person . - ?person rdf:type foaf:Person . - ?person rdfs:label ?rawresult . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - SELECT (str(?rawresult) as ?result) WHERE { - ?uri core:relates ?org . - ?org rdf:type foaf:Organization . - ?org rdfs:label ?rawresult . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) WHERE { - ?uri core:relates ?role . - ?role obo:BFO_0000054 ?project . - ?project rdf:type core:Project . - ?project rdfs:label ?rawresult . - } - """ . - -:vivodocumentModifier_Grants_People_ForProject - a , - ; - rdfs:label "Grants and people for project" ; - :hasTypeRestriction "http://vivoweb.org/ontology/core#Project" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) WHERE { - ?role obo:BFO_0000054 ?uri . - ?grant core:relates ?role . - ?grant rdf:type core:Grant . - ?grant rdfs:label ?rawresult . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX foaf: - PREFIX rdfs: - PREFIX obo: - SELECT (str(?rawresult) as ?result) WHERE { - ?role obo:BFO_0000054 ?uri . - ?role obo:RO_0000053 ?person . - ?person rdf:type foaf:Person . - ?person rdfs:label ?rawresult . - } - """ . - -:vivodocumentModifier_GrantsForOrganization - a , - ; - rdfs:label "Grants for organization" ; - :hasTypeRestriction "http://xmlns.com/foaf/0.1/Organization" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX rdfs: - SELECT (str(?rawresult) as ?result) WHERE { - ?grant core:relates ?uri . - ?grant rdf:type core:Grant . - ?grant rdfs:label ?rawresult . - } - """ . - -:vivodocumentModifier_InformationResources - a , - ; - rdfs:label "Authors, featured, editors, and subject area for InformationResource" ; - :hasTypeRestriction "http://purl.obolibrary.org/IAO_0000030" ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) WHERE { - ?uri core:relatedBy ?a . - ?a rdf:type core:Authorship . - ?a core:relates ?b . - ?b rdf:type foaf:Agent . - ?b rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX core: - PREFIX rdfs: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) WHERE { - ?uri core:features ?i . - ?i rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX rdfs: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) WHERE { - ?uri core:relatedBy ?e . - ?e rdf:type core:Editorship . - ?e core:relates ?i . - ?i rdf:type foaf:Agent . - ?i rdfs:label ?ContextNodeProperty . - } - """ ; - :hasSparqlQuery """ - PREFIX owl: - PREFIX vitroDisplay: - PREFIX rdf: - PREFIX core: - PREFIX foaf: - PREFIX obo: - PREFIX rdfs: - PREFIX localNav: - PREFIX bibo: - SELECT (str(?ContextNodeProperty) as ?contextNodeProperty) WHERE { - ?uri core:hasSubjectArea ?f . - ?f rdfs:label ?ContextNodeProperty . - } - """ . diff --git a/src/edu/cornell/mannlib/vitro/webapp/searchindex/extensions/LabelsAcrossContextNodes.java b/src/edu/cornell/mannlib/vitro/webapp/searchindex/extensions/LabelsAcrossContextNodes.java new file mode 100644 index 00000000..35e983d0 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/searchindex/extensions/LabelsAcrossContextNodes.java @@ -0,0 +1,388 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.searchindex.extensions; + +import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.ALLTEXT; +import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.ALLTEXTUNSTEMMED; +import static edu.cornell.mannlib.vitro.webapp.utils.sparql.SelectQueryRunner.createQueryContext; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.vocabulary.RDFS; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; +import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.DocumentModifier; +import edu.cornell.mannlib.vitro.webapp.searchindex.indexing.IndexingUriFinder; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.ContextModelsUser; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property; +import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation; + +/** + * If an individual has context nodes then the search document for that + * individual should include the labels of the partners across those nodes. The + * labels will be added to the ALLTEXT and ALLTEXTUNSTEMMED fields. + * + * We can add restrictions to say that this only applies to individuals of + * certain types. We can also restrict the type of the applicable context nodes. + * + * An instance of this class acts as both a DocumentModifier and an + * IndexingUriFinder: + * + * As a DocumentModifier, it looks across approved context nodes to fetch the + * labels of the partners. + * + * As an IndexingUriFinder, it recognizes that this relationship can be changed + * by a change to a "label" statement, or to a "relates" property, and finds all + * partners as candidates for reindexing. + * + *
+ * Configuration:
+ *     rdfs:label -- Optional. Appears in the timings and debug statements.
+ *     :hasTypeRestriction -- Optional. Match any. If none, then no restriction.
+ *     :appliesToContextNodeType -- Optional. Match any. If none, then no restriction.
+ * 
+ */ +public class LabelsAcrossContextNodes implements IndexingUriFinder, + DocumentModifier, ContextModelsUser { + private static final Log log = LogFactory + .getLog(LabelsAcrossContextNodes.class); + + private RDFService rdfService; + + /** + * A name to be used in logging, to identify this instance. If not provided, + * then a descriptive label will be created. + */ + private String label; + + /** + * URIs of the types of individuals to whom this instance applies. + * + * If this is not empty and an individual does not have any of these types, + * then skip that individual. + */ + private Set typeRestrictions = new HashSet<>(); + + /** + * URIs of the types of acceptable context nodes. + * + * If this is not empty and a context node does not have any of these types, + * then skip that context node's label. + */ + private Set contextNodeClasses = new HashSet<>(); + + @Override + public void setContextModels(ContextModelAccess models) { + this.rdfService = models.getRDFService(); + } + + @Property(uri = "http://www.w3.org/2000/01/rdf-schema#label") + public void setLabel(String l) { + label = l; + } + + @Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasTypeRestriction") + public void addTypeRestriction(String typeUri) { + typeRestrictions.add(typeUri); + } + + @Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#appliesToContextNodeType") + public void addContextNodeClass(String cnc) { + contextNodeClasses.add(cnc); + } + + @Validation + public void validate() { + if (label == null) { + label = String.format("%s[types=%s, contextNodeTypes=%s]", this + .getClass().getSimpleName(), + formatRestrictions(typeRestrictions), + formatRestrictions(contextNodeClasses)); + } + } + + private String formatRestrictions(Set uris) { + if (uris.isEmpty()) { + return "ALL"; + } else { + return localNames(uris).toString(); + } + } + + private Set localNames(Set uris) { + Set names = new HashSet<>(); + for (String uri : uris) { + try { + names.add(ResourceFactory.createResource(uri).getLocalName()); + } catch (Exception e) { + log.warn("Failed to parse URI: " + uri, e); + names.add(uri); + } + } + return names; + } + + @Override + public String toString() { + return (label == null) ? super.toString() : label; + } + + // ---------------------------------------------------------------------- + // DocumentModifier + // ---------------------------------------------------------------------- + + private static final String LABELS_WITHOUT_RESTRICTION = "" + + "PREFIX vivo: \n" + + "PREFIX rdfs: \n" + + "SELECT ?label \n" // + + "WHERE { \n" // + + " ?uri vivo:relatedBy ?contextNode . \n" // + + " ?contextNode vivo:relates ?partner . \n" // + + " ?partner rdfs:label ?label . \n" // + + " FILTER( ?uri != ?partner ) \n" // + + "} \n"; + private static final String LABELS_FOR_SPECIFIC_CONTEXT_NODE_TYPE = "" + + "PREFIX vivo: \n" + + "PREFIX rdfs: \n" + + "SELECT ?label \n" // + + "WHERE { \n" // + + " ?uri vivo:relatedBy ?contextNode . \n" // + + " ?contextNode a ?nodeType . \n" // + + " ?contextNode vivo:relates ?partner . \n" // + + " ?partner rdfs:label ?label . \n" // + + " FILTER( ?uri != ?partner ) \n" // + + "} \n"; + + /** + * If this individual is acceptable, locate the labels of any context + * partners across acceptable context nodes. Add those labels to the text + * fields of the search document. + */ + @Override + public void modifyDocument(Individual ind, SearchInputDocument doc) { + if (passesTypeRestriction(ind)) { + if (contextNodeClasses.isEmpty()) { + addLabelsFromAllContextNodeClasses(ind, doc); + } else { + for (String contextNodeClass : contextNodeClasses) { + addLabelsFromContextNodeClass(ind, doc, contextNodeClass); + } + } + } + } + + private boolean passesTypeRestriction(Individual ind) { + if (typeRestrictions.isEmpty()) { + return true; + } else { + for (VClass type : ind.getVClasses()) { + if (typeRestrictions.contains(type.getURI())) { + return true; + } + } + } + return false; + } + + private void addLabelsFromAllContextNodeClasses(Individual ind, + SearchInputDocument doc) { + addValuesToTextFields(doc, + createQueryContext(rdfService, LABELS_WITHOUT_RESTRICTION) + .bindVariableToUri("uri", ind.getURI()).execute() + .getStringFields("label").flatten()); + } + + private void addLabelsFromContextNodeClass(Individual ind, + SearchInputDocument doc, String contextNodeClass) { + addValuesToTextFields( + doc, + createQueryContext(rdfService, + LABELS_FOR_SPECIFIC_CONTEXT_NODE_TYPE) + .bindVariableToUri("uri", ind.getURI()) + .bindVariableToUri("nodeType", contextNodeClass) + .execute().getStringFields("label").flatten()); + } + + private void addValuesToTextFields(SearchInputDocument doc, + List values) { + for (String value : values) { + doc.addField(ALLTEXT, value); + doc.addField(ALLTEXTUNSTEMMED, value); + } + } + + @Override + public void shutdown() { + // Nothing to shut down. + } + + // ---------------------------------------------------------------------- + // IndexingUriFinder + // ---------------------------------------------------------------------- + + private static final String URI_VIVO_RELATES = "http://vivoweb.org/ontology/core#relates"; + + private static final String LOCATE_PARTNERS_WITHOUT_RESTRICTION = "" + + "PREFIX vivo: \n" + + "SELECT ?partner \n" // + + "WHERE { \n" // + + " ?uri vivo:relatedBy ?contextNode . \n" // + + " ?contextNode vivo:relates ?partner . \n" // + + " FILTER( ?uri != ?partner ) \n" // + + "} \n"; + private static final String LOCATE_PARTNERS_ON_CONTEXT_NODE_TYPE = "" + + "PREFIX vivo: \n" + + "SELECT ?partner \n" // + + "WHERE { \n" // + + " ?uri vivo:relatedBy ?contextNode . \n" // + + " ?contextNode vivo:relates ?partner . \n" // + + " ?contextNode a ?nodeType . \n" // + + " FILTER( ?uri != ?partner ) \n" // + + "} \n"; + private static final String LOCATE_OTHER_PARTNERS_ON_THIS_NODE = "" + + "PREFIX vivo: \n" + + "SELECT ?partner \n" // + + "WHERE { \n" // + + " ?contextNode vivo:relates ?partner . \n" // + + " FILTER( ?uri != ?partner ) \n" // + + "} \n"; + private static final String GET_TYPES = "" // + + "SELECT ?type \n" // + + "WHERE { \n" // + + " ?uri a ?type . \n" // + + "} \n"; + + @Override + public void startIndexing() { + // Nothing to do. + } + + /** + * If this is a "label" statement, check to see if the subject has any + * acceptable partners across acceptable context nodes. + * + * If this is a "relates" statement on an acceptable context node, check to + * see if there are any other acceptable partners on this node. + * + * We could also check for "relatedBy" statements, but they should happen in + * pairs with the "relates" statements. + */ + @Override + public List findAdditionalURIsToIndex(Statement stmt) { + if (isLabelStatement(stmt)) { + return filterByType(locatePartners(stmt)); + } else if (isRelatesStatementOnAcceptableContextNode(stmt)) { + return filterByType(locateOtherPartners(stmt)); + } + return Collections.emptyList(); + } + + private boolean isLabelStatement(Statement stmt) { + return RDFS.label.getURI().equals(stmt.getPredicate().getURI()); + } + + private Set locatePartners(Statement stmt) { + String uri = stmt.getSubject().getURI(); + if (contextNodeClasses.isEmpty()) { + return locatePartnersWithoutRestriction(uri); + } else { + Set uris = new HashSet<>(); + for (String contextNodeClass : contextNodeClasses) { + uris.addAll(locatePartnersAcrossContextNodeClass(uri, + contextNodeClass)); + } + return uris; + } + } + + private Set locatePartnersWithoutRestriction(String uri) { + return createQueryContext(rdfService, + LOCATE_PARTNERS_WITHOUT_RESTRICTION) + .bindVariableToUri("uri", uri).execute() + .getStringFields("partner").flattenToSet(); + } + + private Collection locatePartnersAcrossContextNodeClass( + String uri, String contextNodeClass) { + return createQueryContext(rdfService, + LOCATE_PARTNERS_ON_CONTEXT_NODE_TYPE) + .bindVariableToUri("uri", uri) + .bindVariableToUri("nodeType", contextNodeClass).execute() + .getStringFields("partner").flattenToSet(); + } + + private boolean isRelatesStatementOnAcceptableContextNode(Statement stmt) { + String subjectUri = stmt.getSubject().getURI(); + String predicateUri = stmt.getPredicate().getURI(); + + if (URI_VIVO_RELATES.equals(predicateUri) + && (contextNodeClasses.isEmpty() || isAnyMatch( + contextNodeClasses, getTypes(subjectUri)))) { + return true; + } else { + return false; + } + } + + private boolean isAnyMatch(Set set1, Set set2) { + Set matches = new HashSet<>(set1); + matches.retainAll(set2); + return !matches.isEmpty(); + } + + private Set getTypes(String uri) { + return createQueryContext(rdfService, GET_TYPES) + .bindVariableToUri("uri", uri).execute() + .getStringFields("type").flattenToSet(); + } + + private Set locateOtherPartners(Statement stmt) { + if (!stmt.getSubject().isURIResource()) { + return Collections.emptySet(); + } + + String nodeUri = stmt.getSubject().getURI(); + String objectUri = (stmt.getObject().isURIResource()) ? stmt + .getObject().asResource().getURI() : "NO_MATCH"; + + return createQueryContext(rdfService, + LOCATE_OTHER_PARTNERS_ON_THIS_NODE) + .bindVariableToUri("contextNode", nodeUri) + .bindVariableToUri("uri", objectUri).execute() + .getStringFields("partner").flattenToSet(); + } + + private List filterByType(Collection uris) { + if (typeRestrictions.isEmpty()) { + return new ArrayList<>(uris); + } else { + List filtered = new ArrayList<>(); + for (String uri : uris) { + if (isAnyMatch(typeRestrictions, getTypes(uri))) { + filtered.add(uri); + } + } + return filtered; + } + } + + @Override + public void endIndexing() { + // Nothing to do. + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalURIsForContextNodes.java b/src/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalURIsForContextNodes.java deleted file mode 100644 index 507dac17..00000000 --- a/src/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalURIsForContextNodes.java +++ /dev/null @@ -1,769 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.searchindex.indexing; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -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.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.Statement; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.utils.configuration.ContextModelsUser; - -public class AdditionalURIsForContextNodes implements IndexingUriFinder, ContextModelsUser { - private Log log = LogFactory.getLog(AdditionalURIsForContextNodes.class); - - private static final List multiValuedQueriesForAgent = new ArrayList(); - private static final String multiValuedQueryForInformationContentEntity; - private static final List multiValuedQueriesForRole = new ArrayList(); - private static final ListqueryList; - - private final Set alreadyChecked = Collections.synchronizedSet(new HashSet()); - private volatile RDFService rdfService; - - - @Override - public void setContextModels(ContextModelAccess models) { - this.rdfService = models.getRDFService(); - } - - @Override - public List findAdditionalURIsToIndex(Statement stmt) { - - if( stmt != null ){ - ListurisToIndex = new ArrayList(); - if(stmt.getSubject() != null && stmt.getSubject().isURIResource() ){ - String subjUri = stmt.getSubject().getURI(); - if( subjUri != null && ! alreadyChecked.contains( subjUri )){ - urisToIndex.addAll( findAdditionalURIsToIndex(subjUri)); - alreadyChecked.add(subjUri); - } - } - - if( stmt.getObject() != null && stmt.getObject().isURIResource() ){ - String objUri = stmt.getSubject().getURI(); - if( objUri != null && ! alreadyChecked.contains(objUri)){ - urisToIndex.addAll( findAdditionalURIsToIndex(objUri)); - alreadyChecked.add(objUri); - } - } - - return urisToIndex; - }else{ - return Collections.emptyList(); - } - } - - @Override - public void startIndexing() { - alreadyChecked.clear(); - } - - @Override - public void endIndexing() { - // Nothing to clear - } - - protected List findAdditionalURIsToIndex(String uri) { - - List uriList = new ArrayList(); - - for (String query : queryList) { - QuerySolutionMap initialBinding = new QuerySolutionMap(); - Resource uriResource = ResourceFactory.createResource(uri); - initialBinding.add("uri", uriResource); - - ResultSet results = QueryUtils.getQueryResults(query, - initialBinding, rdfService); - 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"); - } - } - } - } - - if( log.isDebugEnabled() ) - log.debug( "additional uris for " + uri + " are " + uriList); - - return uriList; - } - - - private static final String prefix = "prefix owl: \n" - + " prefix vitroDisplay: \n" - + " prefix rdf: \n" - + " prefix core: \n" - + " prefix foaf: \n" - + " prefix obo: \n" - + " prefix vcard: \n" - + " prefix event: \n" - + " prefix rdfs: \n" - + " prefix localNav: \n" - + " prefix bibo: \n"; - - static{ - - // If a person changes then update - // organizations for positions - multiValuedQueriesForAgent.add(prefix + - "SELECT DISTINCT \n" + - " (str(?i) as ?positionInOrganization) \n" + - " WHERE {\n" - - + "?uri rdf:type foaf:Agent ; core:relatedBy ?c . \n" - + " ?c rdf:type core:Position . \n" - - + " OPTIONAL { ?c core:relates ?i . ?i rdf:type foaf:Organization } . \n" - + " }"); - - // If a person changes then update - // advisee, linkedAuthor and informationResource - multiValuedQueriesForAgent.add(prefix + - "SELECT (str(?d) as ?advisee) \n" + - " (str(?f) as ?linkedAuthor) (str(?h) as ?linkedInformationResource) WHERE { {\n" - - + "?uri rdf:type foaf:Agent . \n" - + "?uri core:relatedBy ?c . \n" - + "?c rdf:type core:AdvisingRelationship . \n" - + "?c core:relates ?d . \n" - + "?d rdf:type core:AdviseeRole . \n" - + "?d obo:RO_0000052 ?e . \n" - + "?e rdf:type foaf:Person . \n" - + "} \n" - + "UNION { \n" - + " ?uri rdf:type foaf:Agent . \n" - + " ?uri core:relatedBy ?c . \n" - + " ?c rdf:type core:Authorship . \n" - + " OPTIONAL {?c core:relates ?f . \n" - + " ?f rdf:type foaf:Person . } \n" - + " OPTIONAL { ?c core:relates ?h . \n" - + " ?h rdf:type obo:IAO_0000030 . } \n" - + " } } "); - - // If a person changes then update - // award giver - multiValuedQueriesForAgent.add(prefix + - "SELECT (str(?d) as ?awardConferredBy) \n" + - "WHERE {\n" - - + "?uri rdf:type foaf:Agent ; ?b ?c . \n" - + " ?c rdf:type core:AwardReceipt . \n" - - + " OPTIONAL { ?c core:assignedBy ?d . } . \n" - + " }"); - - // If a person changes then update - // organization for role - multiValuedQueriesForAgent.add(prefix + - "SELECT (str(?Organization) as ?organization) \n" + - "WHERE {\n" - - + "?uri rdf:type foaf:Agent ; ?b ?c . \n" - + " ?c rdf:type obo:BFO_0000023 ; obo:BFO_0000054 ?Organization .\n" - + " }"); - - // If a person changes then update - // organization in educational training - multiValuedQueriesForAgent.add(prefix + - "SELECT \n" + - "(str(?e) as ?trainingAtOrganization) WHERE {\n" - - + " ?uri rdf:type foaf:Agent ; ?b ?c . \n" - + " ?c rdf:type core:EducationalProcess . \n" - - + " OPTIONAL { ?c obo:RO_0000057 ?e . \n" - + " ?e rdf:type foaf:Organization . } . " - +"}"); - - // If an organization changes then update - // people in head of relations - multiValuedQueriesForAgent.add( - " # for organization, get leader \n" + - prefix + - "SELECT \n" + - "(str(?e) as ?LeaderPerson ) WHERE {\n" - - + " ?uri rdf:type foaf:Agent . \n" - + " ?uri core:contributingRole ?c . \n" - + " ?c rdf:type core:LeaderRole . \n" - - + " OPTIONAL { ?c obo:RO_0000052 ?e . \n" - + " ?e rdf:type foaf:Person . } . " - +"}"); - - } - - //multivalued query for obo:IAO_0000030 (Information Content Entity) - static { - - multiValuedQueryForInformationContentEntity = prefix + - "SELECT (str(?b) as ?linkedAuthor) (str(?d) as ?linkedInformationResource) \n" - + "(str(?f) as ?editor) \n" + - "(str(?i) as ?features) WHERE {\n" - - + " ?uri rdf:type obo:IAO_0000030 . \n" - - + " OPTIONAL { ?uri core:relatedBy ?a . \n" - + " ?a rdf:type core:Authorship . \n" - + " ?a core:relates ?b . ?b rdf:type foaf:Person .\n" - + " ?a core:relates ?d . ?d rdf:type obo:IAO_0000030 .\n" - + "} . " - - + " OPTIONAL { ?uri core:relatedBy ?e . \n" - + " ?e rdf:type core:Editorship . \n" - + " ?e core:relates ?f . ?f rdf:type foaf:Person .\n" - + "} . " - + " OPTIONAL { ?uri core:features ?i . } . \n" - - +"}" ; - - } - - protected static List queriesForAuthorship(){ - List queries = new ArrayList(); - - //get additional URIs of information resources from author side - queries.add( - prefix - + "SELECT (str(?a) as ?infoResource) WHERE {\n" - - + " ?uri rdf:type foaf:Person . \n" - + " ?uri core:relatedBy ?aship .\n" - + " ?aship rdf:type core:Authorship .\n" - + "OPTIONAL { ?aship core:relates ?a . ?a rdf:type obo:IAO_0000030 } .\n" - +"}" ); - - //get additional URIs of authors from information resource side - queries.add( - prefix - + "SELECT (str(?a) as ?author ) WHERE {\n" - - + " ?uri rdf:type obo:IAO_0000030 . \n" - + " ?uri core:relatedBy ?aship . ?aship rdf:type core:Authorship . \n" - + "OPTIONAL { ?aship core:relates ?a . ?a rdf:type foaf:Person } .\n" - +"}" ); - return queries; - } - - protected static List queriesForURLLink(){ - List queries = new ArrayList(); - - //get additional URIs when URLLink is changed - queries.add( - prefix - + "SELECT (str(?x) as ?individual) WHERE {\n" - - + " ?i rdf:type vcard:Individual . \n" - + " ?i vcard:hasURL ?uri . \n" - + " ?i obo:ARG_2000029 ?x . \n" - +"}" ); - - return queries; - } - - protected static List queriesForEducationalTraining(){ - List queries = new ArrayList(); - - //if person changes, no additional URIs need to be - //changed because the person is not displayed on the - //degree individual or on the degree granting organization - - //if the degree changes, the person needs to be updated - //since the degree name is shown on the person page. - queries.add( - prefix - + " SELECT (str(?person) as ?personUri) WHERE {\n" - - + " ?uri rdf:type core:AcademicDegree . \n" - + " ?uri core:relatedBy ?awardedDegree .\n" - + " ?awardedDegree rdf:type core:AwardedDegree .\n" - + " ?awardedDegree core:relates ?person .\n" - + " ?person rdf:type foaf:Person .\n" - +"}" ); - - //if the organization changes the person needs to be updated - //since the organization name is shown on the person page. - queries.add( - prefix - + " SELECT (str(?person) as ?personUri) WHERE {\n" - - + " ?uri rdf:type foaf:Organization . \n" - + " ?uri obo:RO_0000056 ?edTrainingNode .\n" - + " ?edTrainingNode rdf:type core:EducationalProcess . \n" - + " ?edTrainingNode obo:RO_0000057 ?person . \n" - + " ?person rdf:type foaf:Person ." - +"}" ); - return queries; - } - - protected static List queriesForPosition(){ - List queries = new ArrayList(); - - //If an organization changes, update people - queries.add( - prefix - + " SELECT (str(?person) as ?personUri) WHERE {\n" - - + " ?uri rdf:type foaf:Organization . \n" - + " ?uri core:relatedBy ?positionNode .\n" - + " ?positionNode rdf:type core:Position .\n" - + " ?positionNode core:relates ?person . \n" - + " ?person rdf:type foaf:Person .\n" - +"}" ); - - - //if people change, update organizations - queries.add( - prefix - + " SELECT (str(?org) as ?orgUri) WHERE {\n" - - + " ?uri rdf:type foaf:Person . \n" - + " ?uri core:relatedBy ?positionNode .\n" - + " ?positionNode rdf:type core:Position .\n" - + " ?positionNode core:relates ?org . \n" - + " ?org rdf:type foaf:Organization .\n" - +"}" ); - return queries; - } - - static{ - // core:AttendeeRole - // If the person changes, update the attendee role in organization - // core:AttendeeRole applies to events, not organizations; updating accordingly - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?event) \n " + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:AttendeeRole . \n" - + "?c obo:BFO_0000054 ?d . \n" - + "?d rdf:type event:Event .\n" - + " }"); - - // If the organization changes, update the attendee role of person - // core:AttendeeRole applies to events, not organizations; updating accordingly - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - - + "?uri rdf:type event:Event . \n" - + "?uri obo:BFO_0000055 ?c . \n" - + "?c rdf:type core:AttendeeRole . \n" - + "?c obo:RO_0000052 ?d . \n" - + "?d rdf:type foaf:Person .\n" - + " }"); - - // core:ClinicalRole -- core:clinicalRoleOf - - // If the person changes, update the clinical role in project - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?project) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:ClinicalRole . \n" - + "?c obo:BFO_0000054 ?d .\n" - + "?d rdf:type core:Project .\n" - + " }"); - - - // If the person changes, update the clinical role in service - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?service) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:ClinicalRole . \n" - + "?c core:roleContributesTo ?d .\n" - + "?d rdf:type obo:ERO_0000005 .\n" - + " }"); - - // If the project changes, update the clinical role of person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Project . \n" - + "?uri obo:BFO_0000055 ?c . \n" - + "?c rdf:type core:ClinicalRole . \n" - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // If the service changes, update the clinical role of person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type obo:ERO_0000005 . \n" - + "?uri core:contributingRole ?c . \n" - + "?c rdf:type core:ClinicalRole . \n" - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // If the person changes, update the leader role in organization - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?organization) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:LeaderRole . \n" - + "?c core:roleContributesTo ?d .\n" - + "?d rdf:type foaf:Organization .\n " - + " }"); - - // If the organization changes, update the leader role of person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Organization . \n" - + "?uri core:contributingRole ?c . \n" - + "?c rdf:type core:LeaderRole . \n" - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // core:MemberRole -- core:memberRoleOf - - // If the person changes, update the member role in organization - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?organization) \n" + - "WHERE \n{" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:MemberRole . \n" - + "?c core:roleContributesTo ?d .\n" - + "?d rdf:type foaf:Organization .\n " - + " }"); - - // If the organization changes, update the member role of person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {" - + "?uri rdf:type foaf:Organization . \n" - + "?uri core:contributingRole ?c . \n" - + "?c rdf:type core:MemberRole . \n" - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // core:OrganizerRole -- core:organizerRoleOf - - // If the person changes, update the organizer role in organization - // organizerRole appplies to events not organizations; updating accordingly - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?event) \n" + - "WHERE {" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:OrganizerRole .\n" - + "?c obo:BFO_0000054 ?d .\n" - + "?d rdf:type event:Event .\n " - + " }"); - - // If the organization changes, update the organizer role of person - // organizerRole appplies to events not organizations; updating accordingly - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type event:Event . \n" - + "?uri obo:BFO_0000055 ?c . \n" - + "?c rdf:type core:OrganizerRole . \n" - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // core:OutreachProviderRole -- core:outreachProviderRoleOf - - // If the person changes, update the outreach provider role in organization - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?organization) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + "?c rdf:type core:OutreachProviderRole .\n" - + "?c core:roleContributesTo ?d .\n" - + "?d rdf:type foaf:Organization .\n " - + " }"); - - // If the organization changes, update the outreach provider role of person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Organization . \n" - + "?uri core:contributingRole ?c . \n" - + "?c rdf:type core:OutreachProviderRole . \n" - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // core:PresenterRole -- core:presenterRoleOf - - // If the person changes, update the presentation - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?presentation) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type core:PresenterRole . \n" - + " ?c obo:BFO_0000054 ?d .\n" - + " ?d rdf:type core:Presentation . \n" - + " }"); - - // If the presentation changes, update the person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Presentation . \n" - + "?uri obo:BFO_0000055 ?c . \n" - + " ?c rdf:type core:PresenterRole . \n " - + "?c obo:RO_0000052 ?d .\n " - + "?d rdf:type foaf:Person .\n " - + " }"); - - // core:ResearcherRole -- core:researcherRoleOf - - // If the person changes, update the grant - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?grant) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type core:ResearcherRole . \n " - + " ?c core:relatedBy ?d .\n" - + " ?d rdf:type core:Grant . \n" - + " }"); - - // If the grant changes, update the researcher - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Grant . \n" - + "?uri core:relates ?c . \n" - + " ?c rdf:type core:ResearcherRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - // If the grant changes, update the principal investigator - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Grant . \n" - + " ?uri core:relates ?c . \n" - + " ?c rdf:type core:PrincipalInvestigatorRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - // If the grant changes, update the co-principal investigator - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Grant . \n" - + " ?uri core:relates ?c . \n" - + " ?c rdf:type core:CoPrincipalInvestigatorRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - - // If the grant changes, update the investigator - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Grant . \n" - + " ?uri core:relates ?c . \n" - + " ?c rdf:type core:InvestigatorRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - // If the person changes, update the project - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?project) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type core:ResearcherRole . \n " - + " ?c obo:BFO_0000054 ?d .\n" - + " ?d rdf:type core:Project . \n" - + " }"); - - // If the project changes, update the researcher - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type core:Project . \n" - + " ?uri obo:BFO_0000055 ?c .\n" - + " ?c rdf:type core:ResearcherRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - // core:EditorRole -- core:editorRoleOf, core:forInformationResource (person, informationresource) - - // If the person changes, update the editor role of the info resource - // changing foaf:Organization to info content entity. Org no longer applies here - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?informationResource) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type core:EditorRole . \n " - + " ?c core:roleContributesTo ?d .\n" - + "?d rdf:type obo:IAO_0000030 .\n " - + " }"); - - - // If the info respource changes, update the editor role of person - // changing foaf:Organization to info content entity. Org no longer applies here - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type obo:IAO_0000030 . \n" - + "?uri core:contributingRole ?c . \n" - + " ?c rdf:type core:EditorRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - // Next two queries are covered by the previous two. Commenting them out - tlw72 - // If the person changes, update the information resource associated with editor role -/* multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?informationResource) \n" + - "WHERE {\n" - - + "?uri rdf:type foaf:Person ; ?b ?c . \n" - + " ?c rdf:type core:EditorRole ; core:forInformationResource ?d .\n" - + " }"); - - // If the organization changes, update the information resource associated with editor role - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?informationResource) \n" + - "WHERE {\n" - - + "?uri rdf:type foaf:Organization ; ?b ?c . \n" - + " ?c rdf:type core:EditorRole ; core:forInformationResource ?d .\n" - + " }"); -*/ - // core:ServiceProviderRole -- core:serviceProviderRoleOf - - // If the person changes, update the service provider role in organization - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?organization) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type obo:ERO_0000012 . \n" - + " ?c core:roleContributesTo ?d .\n" - + " ?d rdf:type foaf:Organization .\n " - + " }"); - - // If the organization changes, update the service provider role of person - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Organization . \n" - + "?uri core:contributingRole ?c . \n" - + " ?c rdf:type obo:ERO_0000012 . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - - // core:TeacherRole -- core:teacherRoleOf - - // If the person changes, update the teacher role in organization - // updated to make this an Event (e.g., a course) not an organization - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?event) \n" + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type core:TeacherRole . \n" - + " ?c obo:BFO_0000054 ?d .\n" - + " ?d rdf:type event:Event .\n " - + " }"); - - // If the organization changes, update the teacher role of person - // updated to make this an Event (e.g., a course) not an organization - tlw72 - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?person) \n" + - "WHERE {\n" - + "?uri rdf:type event:Event . \n" - + "?uri obo:BFO_0000055 ?c . \n" - + " ?c rdf:type core:TeacherRole . \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - - // core:ReviewerRole -- core:forInformationResource, core:reviewerRoleOf -// core:PeerReviewerRole -- core:forInformationResource, core:reviewerRoleOf - - // If the person changes, update the information resource associated with reviewer role - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?informationResource) \n " + - "WHERE {\n" - + "?uri rdf:type foaf:Person . \n" - + "?uri obo:RO_0000053 ?c . \n" - + " ?c rdf:type core:ReviewerRole . \n" - + " ?c core:roleContributesTo ?d .\n" - + " ?d rdf:type obo:IAO_0000030 .\n " - + " }"); - - // If the organization changes, update the information resource associated with reviewer role - multiValuedQueriesForRole.add(prefix + - "SELECT (str(?d) as ?informationResource) \n" + - "WHERE {\n" - + "?uri rdf:type obo:IAO_0000030 . \n" - + "?uri core:contributingRole ?c . \n" - + " ?c rdf:type core:ReviewerRole. \n " - + " ?c obo:RO_0000052 ?d .\n" - + "?d rdf:type foaf:Person .\n " - + " }"); - - } - - static{ - List tmpList = new ArrayList(); - tmpList.add(multiValuedQueryForInformationContentEntity); - tmpList.addAll(multiValuedQueriesForAgent); - tmpList.addAll(multiValuedQueriesForRole); - tmpList.addAll( queriesForAuthorship()); - tmpList.addAll(queriesForURLLink()); - tmpList.addAll(queriesForEducationalTraining()); - tmpList.addAll(queriesForPosition()); - - queryList = Collections.unmodifiableList(tmpList); - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/src/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalUrisForVCards.java b/src/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalUrisForVCards.java deleted file mode 100644 index 69d4c30a..00000000 --- a/src/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalUrisForVCards.java +++ /dev/null @@ -1,128 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.searchindex.indexing; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -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.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.Statement; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.utils.configuration.ContextModelsUser; - -/** - * If the property of a VCard object is changed, we should re-index the owner of - * that VCard. - */ -public class AdditionalUrisForVCards implements IndexingUriFinder, ContextModelsUser { - private static final Log log = LogFactory - .getLog(AdditionalUrisForVCards.class); - - private final String QUERY_FOR_RELATED = "" // - + "prefix vcard: \n" - + "prefix obo: \n" - + "SELECT ?uri WHERE { \n" - + " ?subject a vcard:Identification . \n " - + " ?contactInfo ?p ?subject . \n " - + " ?uri obo:ARG_2000028 ?contactInfo . \n " // - + "}"; - - private volatile RDFService rdfService; - - @Override - public void setContextModels(ContextModelAccess models) { - this.rdfService = models.getRDFService(); - } - - @Override - public void startIndexing() { - // Nothing to set up. - } - - @Override - public List findAdditionalURIsToIndex(Statement stmt) { - if (stmt == null) { - return Collections.emptyList(); - } - - RDFNode sNode = stmt.getSubject(); - if (sNode == null) { - log.warn("subject of modified statement was null."); - return Collections.emptyList(); - } - - if (!sNode.isURIResource()) { - return Collections.emptyList(); - } - - Resource subject = sNode.asResource(); - String uri = subject.getURI(); - if (uri == null) { - log.warn("subject of modified statement had a null URI."); - return Collections.emptyList(); - } - - return ownersOfVCard(uri); - } - - /** - * If the subject of the statement is a vcard:Identification, then we also - * want to index the owner of the vcard:ContactInfo that references this - * vcard:Identification. - * - * vcard:Identification is a superclass of vcard:Name, vcard:Email, - * vcard:Telephone, vcard:Address, and vcard:URL. - * - * @see https://wiki.duraspace.org/display/VIVO/VCard+usage+diagram - */ - private List ownersOfVCard(String subjectUri) { - List additionalUris = new ArrayList<>(); - - QuerySolutionMap initialBinding = new QuerySolutionMap(); - Resource subjectResource = ResourceFactory.createResource(subjectUri); - initialBinding.add("subject", subjectResource); - - ResultSet results = QueryUtils.getQueryResults(QUERY_FOR_RELATED, - initialBinding, rdfService); - - while (results.hasNext()) { - QuerySolution soln = results.nextSolution(); - RDFNode node = soln.get("uri"); - if (node != null) { - if (node.isURIResource()) { - additionalUris.add(node.asResource().getURI()); - } else { - log.warn("value from query for 'uri'" - + " was not a URIResource, it was " + node); - } - } else { - log.warn("value for query for 'uri' was null"); - } - } - - return additionalUris; - } - - @Override - public void endIndexing() { - // Nothing to tear down. - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/test/edu/cornell/mannlib/vitro/webapp/searchindex/extensions/LabelsAcrossContextNodesTest.java b/test/edu/cornell/mannlib/vitro/webapp/searchindex/extensions/LabelsAcrossContextNodesTest.java new file mode 100644 index 00000000..f3a20c33 --- /dev/null +++ b/test/edu/cornell/mannlib/vitro/webapp/searchindex/extensions/LabelsAcrossContextNodesTest.java @@ -0,0 +1,492 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.searchindex.extensions; + +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createPlainLiteral; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; +import static com.hp.hpl.jena.rdf.model.ResourceFactory.createStatement; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; +import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.ALLTEXT; +import static edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames.ALLTEXTUNSTEMMED; +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccessStub; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.vocabulary.RDF; +import com.hp.hpl.jena.vocabulary.RDFS; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument; +import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; + +/** + * TODO + */ +public class LabelsAcrossContextNodesTest extends AbstractTestClass { + // Types + private static final String CORE_ACADEMIC_DEGREE = "http://vivoweb.org/ontology/core#AcademicDegree"; + private static final String CORE_ADVISING_RELATIONSHIP = "http://vivoweb.org/ontology/core#AdvisingRelationship"; + private static final String CORE_POSITION = "http://vivoweb.org/ontology/core#Position"; + private static final String FOAF_PERSON = "http://xmlns.com/foaf/0.1/#Person"; + private static final String FOAF_ORGANIZATION = "http://xmlns.com/foaf/0.1/#Organization"; + + // Individuals + // Note: Person3 has no label and so no effect, but doesn't cause a problem. + private static final String URI_PERSON1 = "http://ns#Person1"; + private static final String NAME_PERSON1 = "Person1"; + private static final String URI_PERSON2 = "http://ns#Person2"; + private static final String NAME_PERSON2 = "Person2"; + private static final String URI_PERSON3 = "http://ns#Person3"; + private static final String NAME_PERSON3 = null; + private static final String URI_PERSON4 = "http://ns#Person4"; + private static final String NAME_PERSON4 = "Person4"; + private static final String URI_ORGANIZATION1 = "http://ns#Organization1"; + private static final String NAME_ORGANIZATION1 = "Organization1"; + + // Context nodes + private static final String URI_POSITION1 = "http://ns#Position1"; + private static final String NAME_POSITION1 = "Position1"; + private static final String URI_POSITION2 = "http://ns#Position2"; + private static final String NAME_POSITION2 = "Position2"; + private static final String URI_ADVISING1 = "http://ns#Advising1"; + private static final String NAME_ADVISING1 = "Advising1"; + private static final String URI_ADVISING2 = "http://ns#Advising2"; + private static final String NAME_ADVISING2 = "Advising2"; + + // Properties + private static final String CORE_RELATED_BY = "http://vivoweb.org/ontology/core#relatedBy"; + private static final String CORE_RELATES = "http://vivoweb.org/ontology/core#relates"; + private static final String CORE_ASSIGNED_BY = "http://vivoweb.org/ontology/core#assignedBy"; + + private Model m; + private RDFService rdfService; + private LabelsAcrossContextNodes lacn; + private MockSearchInputDocument doc; + private List foundUris; + + /** + * Create these relationships (where "r/r" denotes "relatedBy/relates" + * combination. + * + *
+	 * Person1 r/r Position1 r/r Organization1
+	 * Person1 r/r AdvisingRelationship1 r/r Person2
+	 * Person1 r/r AdvisingRelationship2 r/r Person3(no label!)
+	 * Person2 r/r Position2 r/r Organization1
+	 * Person4
+	 * 
+ */ + @Before + public void populateModel() { + m = ModelFactory.createDefaultModel(); + addIndividual(URI_PERSON1, NAME_PERSON1, FOAF_PERSON); + addIndividual(URI_PERSON2, NAME_PERSON2, FOAF_PERSON); + addIndividual(URI_PERSON3, NAME_PERSON3, FOAF_PERSON); + addIndividual(URI_PERSON4, NAME_PERSON4, FOAF_PERSON); + addIndividual(URI_ORGANIZATION1, NAME_ORGANIZATION1, FOAF_ORGANIZATION); + addIndividual(URI_POSITION1, NAME_POSITION1, CORE_POSITION); + addIndividual(URI_POSITION2, NAME_POSITION2, CORE_POSITION); + addIndividual(URI_ADVISING1, NAME_ADVISING1, CORE_ADVISING_RELATIONSHIP); + addIndividual(URI_ADVISING2, NAME_ADVISING2, CORE_ADVISING_RELATIONSHIP); + + addRelationship(URI_PERSON1, URI_POSITION1, URI_ORGANIZATION1); + addRelationship(URI_PERSON1, URI_ADVISING1, URI_PERSON2); + addRelationship(URI_PERSON1, URI_ADVISING2, URI_PERSON3); + addRelationship(URI_PERSON2, URI_POSITION2, URI_ORGANIZATION1); + + rdfService = new RDFServiceModel(m); + + ContextModelAccessStub models = new ContextModelAccessStub(); + models.setRDFService(CONTENT, rdfService); + + lacn = new LabelsAcrossContextNodes(); + lacn.setContextModels(models); + } + + // ---------------------------------------------------------------------- + // Test DocumentModifier + // ---------------------------------------------------------------------- + + /* + * If there is a type restriction and the individual does not meet it, no + * change. + * + * If contextNodeClasses are not specified, get labels from all context + * nodes. note that a partner without a label should just be a no-op. + * + * If contextNodeClasses are specified, accept some and ignore others. + * + * Confirm that the expected data is written to the text fields. + */ + + @Test + public void noRestrictions_returnLabelsOfAllPartners() { + setTypeRestrictions(); + setContextNodeTypes(); + exerciseDocumentModifier(URI_PERSON1); + assertExpectedFieldValues(NAME_ORGANIZATION1, NAME_PERSON2); + } + + @Test + public void typeRestrictionOnCorrectType_returnAll() { + setTypeRestrictions(FOAF_PERSON); + setContextNodeTypes(); + exerciseDocumentModifier(URI_PERSON1); + assertExpectedFieldValues(NAME_ORGANIZATION1, NAME_PERSON2); + } + + @Test + public void typeRestrictionOnWrongType_returnNothing() { + setTypeRestrictions(FOAF_ORGANIZATION); + setContextNodeTypes(); + exerciseDocumentModifier(URI_PERSON1); + assertExpectedFieldValues(); + } + + @Test + public void limitByContextNodeType_returnLimited() { + setTypeRestrictions(); + setContextNodeTypes(CORE_POSITION); + exerciseDocumentModifier(URI_PERSON1); + assertExpectedFieldValues(NAME_ORGANIZATION1); + } + + @Test + public void inclusiveContextNodeTypes_returnAll() { + setTypeRestrictions(); + setContextNodeTypes(CORE_POSITION, CORE_ADVISING_RELATIONSHIP); + exerciseDocumentModifier(URI_PERSON1); + assertExpectedFieldValues(NAME_ORGANIZATION1, NAME_PERSON2); + } + + @Test + public void noContextNodes_noResultsNoProblem() { + setTypeRestrictions(); + setContextNodeTypes(); + exerciseDocumentModifier(URI_PERSON4); + assertExpectedFieldValues(); + } + + // ---------------------------------------------------------------------- + // Test IndexingUriFinder + // ---------------------------------------------------------------------- + + /** + *
+	 * If neither a label nor a relates, ignore it.
+	 * 
+	 * If label, test if no partners, if some partners, if some partners restricted by type.
+	 *   test with both contextNodeClasses and not.
+	 * Test with typeRestrictions or without.
+	 * 
+	 * If relates, and fails contextNodeClasses, ignore it.
+	 * Test with contextNodeClasses and without.
+	 * Find partners, both with typeRestrictions and without.
+	 * 
+ */ + + @Test + public void irrelevantStatement_returnsNothing() { + setTypeRestrictions(); + setContextNodeTypes(); + exerciseUriFinder(stmt(URI_POSITION1, CORE_ASSIGNED_BY, URI_PERSON4)); + assertExpectedUris(); + } + + @Test + public void label_noPartners_returnsNothing() { + setTypeRestrictions(); + setContextNodeTypes(); + exerciseUriFinder(labelStmt(URI_PERSON4, "New Name")); + assertExpectedUris(); + } + + @Test + public void label_returnsAllPartners() { + setTypeRestrictions(); + setContextNodeTypes(); + exerciseUriFinder(labelStmt(URI_PERSON1, "New Name")); + assertExpectedUris(URI_PERSON2, URI_PERSON3, URI_ORGANIZATION1); + } + + @Test + public void label_restrictByContextNode_returnEligiblePartners() { + setTypeRestrictions(); + setContextNodeTypes(CORE_ADVISING_RELATIONSHIP); + exerciseUriFinder(labelStmt(URI_PERSON1, "New Name")); + assertExpectedUris(URI_PERSON2, URI_PERSON3); + } + + @Test + public void label_restrictByContextNodes_returnEligiblePartners() { + setTypeRestrictions(); + setContextNodeTypes(CORE_ADVISING_RELATIONSHIP, CORE_POSITION); + exerciseUriFinder(labelStmt(URI_PERSON1, "New Name")); + assertExpectedUris(URI_PERSON2, URI_PERSON3, URI_ORGANIZATION1); + } + + @Test + public void label_typeRestriction_limitsResults() { + setTypeRestrictions(FOAF_PERSON); + setContextNodeTypes(); + exerciseUriFinder(labelStmt(URI_PERSON1, "New Name")); + assertExpectedUris(URI_PERSON2, URI_PERSON3); + } + + @Test + public void label_inclusiveTypeRestrictions_allResults() { + setTypeRestrictions(FOAF_PERSON, FOAF_ORGANIZATION); + setContextNodeTypes(); + exerciseUriFinder(labelStmt(URI_PERSON1, "New Name")); + assertExpectedUris(URI_PERSON2, URI_PERSON3, URI_ORGANIZATION1); + } + + @Test + public void label_prohibitiveTypeRestrictions_nothing() { + setTypeRestrictions(CORE_ACADEMIC_DEGREE); + setContextNodeTypes(); + exerciseUriFinder(labelStmt(URI_PERSON1, "New Name")); + assertExpectedUris(); + } + + @Test + public void relates_returnsPartner() { + setTypeRestrictions(); + setContextNodeTypes(); + exerciseUriFinder(stmt(URI_POSITION1, CORE_RELATES, URI_PERSON1)); + assertExpectedUris(URI_ORGANIZATION1); + } + + @Test + public void relates_inclusiveTypeRestriction_returnsPartner() { + setTypeRestrictions(FOAF_ORGANIZATION); + setContextNodeTypes(); + exerciseUriFinder(stmt(URI_POSITION1, CORE_RELATES, URI_PERSON1)); + assertExpectedUris(URI_ORGANIZATION1); + } + + @Test + public void relates_exclusiveTypeRestriction_returnsNothing() { + setTypeRestrictions(CORE_ADVISING_RELATIONSHIP); + setContextNodeTypes(); + exerciseUriFinder(stmt(URI_POSITION1, CORE_RELATES, URI_PERSON1)); + assertExpectedUris(); + } + + @Test + public void relates_inclusiveContextType_returnsPartner() { + setTypeRestrictions(); + setContextNodeTypes(CORE_POSITION); + exerciseUriFinder(stmt(URI_POSITION1, CORE_RELATES, URI_PERSON1)); + assertExpectedUris(URI_ORGANIZATION1); + } + + @Test + public void relates_exclusiveContextType_returnsNothing() { + setTypeRestrictions(); + setContextNodeTypes(CORE_ADVISING_RELATIONSHIP); + exerciseUriFinder(stmt(URI_POSITION1, CORE_RELATES, URI_PERSON1)); + assertExpectedUris(); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void addIndividual(String uri, String label, String... types) { + Resource subject = createResource(uri); + if (label != null) { + m.add(subject, RDFS.label, label); + } + for (String type : types) { + m.add(subject, RDF.type, createResource(type)); + } + } + + private void addRelationship(String ind1Uri, String contextNodeUri, + String ind2Uri) { + Resource ind1 = createResource(ind1Uri); + Resource contextNode = createResource(contextNodeUri); + Resource ind2 = createResource(ind2Uri); + Property relatedBy = createProperty(CORE_RELATED_BY); + Property relates = createProperty(CORE_RELATES); + m.add(ind1, relatedBy, contextNode); + m.add(contextNode, relates, ind1); + m.add(ind2, relatedBy, contextNode); + m.add(contextNode, relates, ind2); + } + + private void setTypeRestrictions(String... uris) { + for (String uri : uris) { + lacn.addTypeRestriction(uri); + } + } + + private void setContextNodeTypes(String... uris) { + for (String uri : uris) { + lacn.addContextNodeClass(uri); + } + } + + private void exerciseDocumentModifier(String individualUri) { + Individual ind = createIndividual(individualUri); + doc = new MockSearchInputDocument(); + lacn.modifyDocument(ind, doc); + } + + private Individual createIndividual(String individualUri) { + Individual ind = new IndividualImpl(individualUri); + List vclasses = new ArrayList<>(); + for (RDFNode node : m.listObjectsOfProperty( + createResource(individualUri), RDF.type).toList()) { + if (node.isURIResource()) { + vclasses.add(new VClass(node.asResource().getURI())); + } + } + ind.setVClasses(vclasses, false); + return ind; + } + + private void assertExpectedFieldValues(String... values) { + List expected = new ArrayList<>(Arrays.asList(values)); + Collections.sort(expected); + + List actual1 = doc.getValues(ALLTEXT); + Collections.sort(actual1); + assertEquals("ALLTEXT", expected, actual1); + + List actual2 = doc.getValues(ALLTEXTUNSTEMMED); + Collections.sort(actual2); + assertEquals("ALLTEXTUNSTEMMED", expected, actual2); + } + + private void exerciseUriFinder(Statement stmt) { + foundUris = lacn.findAdditionalURIsToIndex(stmt); + } + + private Statement stmt(String subjectUri, String predicateUri, + String objectUri) { + return createStatement(createResource(subjectUri), + createProperty(predicateUri), createResource(objectUri)); + } + + private Statement labelStmt(String subjectUri, String labelText) { + return createStatement(createResource(subjectUri), RDFS.label, + createPlainLiteral(labelText)); + } + + private void assertExpectedUris(String... expectedArray) { + Set expected = new HashSet<>(Arrays.asList(expectedArray)); + Set actual = new HashSet<>(foundUris); + assertEquals("found URIs", expected, actual); + } + + // ---------------------------------------------------------------------- + // Helper classes + // ---------------------------------------------------------------------- + + private static class MockSearchInputDocument implements SearchInputDocument { + // ---------------------------------------------------------------------- + // Stub infrastructure + // ---------------------------------------------------------------------- + + private Map> fieldValues = new HashMap<>(); + + public List getValues(String fieldName) { + if (fieldValues.containsKey(fieldName)) { + return new ArrayList<>(fieldValues.get(fieldName)); + } else { + return new ArrayList<>(); + } + } + + // ---------------------------------------------------------------------- + // Stub methods + // ---------------------------------------------------------------------- + + // ---------------------------------------------------------------------- + // Un-implemented methods + // ---------------------------------------------------------------------- + + @Override + public void addField(SearchInputField arg0) { + throw new RuntimeException("addField() not implemented."); + } + + @Override + public void addField(String name, Object... values) { + List stringValues = getValues(name); + for (Object value : values) { + stringValues.add(String.valueOf(value)); + } + fieldValues.put(name, stringValues); + } + + @Override + public void addField(String arg0, Collection arg1) { + throw new RuntimeException("addField() not implemented."); + } + + @Override + public void addField(String arg0, float arg1, Object... arg2) { + throw new RuntimeException("addField() not implemented."); + } + + @Override + public void addField(String arg0, float arg1, Collection arg2) { + throw new RuntimeException("addField() not implemented."); + } + + @Override + public SearchInputField createField(String arg0) { + throw new RuntimeException("createField() not implemented."); + } + + @Override + public float getDocumentBoost() { + throw new RuntimeException("getDocumentBoost() not implemented."); + } + + @Override + public SearchInputField getField(String arg0) { + throw new RuntimeException("getField() not implemented."); + } + + @Override + public Map getFieldMap() { + throw new RuntimeException("getFieldMap() not implemented."); + } + + @Override + public void setDocumentBoost(float arg0) { + throw new RuntimeException("setDocumentBoost() not implemented."); + } + + } + +} diff --git a/test/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalURIsForContextNodesTest.java b/test/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalURIsForContextNodesTest.java deleted file mode 100644 index c06c9e14..00000000 --- a/test/edu/cornell/mannlib/vitro/webapp/searchindex/indexing/AdditionalURIsForContextNodesTest.java +++ /dev/null @@ -1,611 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.searchindex.indexing; - -import static org.junit.Assert.assertTrue; - -import java.io.StringReader; -import java.util.List; - -import org.junit.Test; - -import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccessStub; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.ModelFactory; - -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; - - -public class AdditionalURIsForContextNodesTest { - - private AdditionalURIsForContextNodes uriFinder; - - @Test - public void testPositionChanges(){ - String n3 = - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the org needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://caruso-laptop.mannlib.cornell.edu:8090/vivo/individual/n932"); - assertTrue("did not find org for context node", uris.contains("http://caruso-laptop.mannlib.cornell.edu:8090/vivo/individual/n5423" )); - - //if the org changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://caruso-laptop.mannlib.cornell.edu:8090/vivo/individual/n5423"); - assertTrue("did not find person for context node", uris.contains("http://caruso-laptop.mannlib.cornell.edu:8090/vivo/individual/n932" )); - } - - @Test - public void testPersonOnOrgChange() { - - String n3 ="@prefix dc: . \n" + - "@prefix rdfs: . \n" + - "@prefix swrl: . \n" + - "@prefix vitro: . \n" + - "@prefix xsd: . \n" + - "@prefix swrlb: . \n" + - "@prefix owl: . \n" + - "@prefix rdf: . \n" + - "@prefix core: . \n" + - "@prefix vivo: . \n" + - "@prefix obo: . \n" + - " " + - " \n" + - " a owl:Thing , core:Role , core:LeaderRole ; \n" + - " rdfs:label \"head\"^^xsd:string ; \n" + - " vitro:mostSpecificType \n" + - " core:LeaderRole ; \n" + - " core:dateTimeInterval \n" + - " ; \n" + - " obo:RO_0000052 ; \n" + - " core:roleContributesTo . \n" + - " \n" + - " a , owl:Thing , , core:ClinicalOrganization ; \n" + - " rdfs:label \"Organization XYZ\"^^xsd:string ; \n" + - " vitro:mostSpecificType \n" + - " core:ClinicalOrganization ; \n" + - " core:contributingRole . \n" + - " a , owl:Thing , . \n"; - - //make a test model with an person, an authorship context node and a book - populateModelAndCreateUriFinder(n3); - - //get additional uris for org - List uris = uriFinder.findAdditionalURIsToIndex( "http://caruso-laptop.mannlib.cornell.edu:8090/vivo/individual/n2592"); - - assertTrue("did not find person for context node", uris.contains("http://vivo.scripps.edu/individual/n14979" )); - } - - - @Test - public void testLeaderRoleChanges(){ - String n3= - - " \"1, Test\" . \n " + -// " \"1\"^^ . \n " + -// " \"Test\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - - " \"Leader Role\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - " \"University1\"^^ . \n " + - " . \n " + - " .\n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the university needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n2027"); - assertTrue("did not find org for context node", uris.contains("http://vivo.scripps.edu/individual/n7080" )); - - //if the university changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n7080"); - assertTrue("did not find person for context node", uris.contains("http://vivo.scripps.edu/individual/n2027" )); - } - - - @Test - public void testMemberRoleChanges(){ - String n3 = - - " . \n " + - " \"2, Test\" . \n " + -// " \"2\"^^ . \n " + -// " \"Test\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - " \"Member Role\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - - " \"University2\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the university needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4519"); - assertTrue("did not find org for context node", uris.contains("http://vivo.scripps.edu/individual/n6004" )); - - //if the university changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n6004"); - assertTrue("did not find person for context node", uris.contains("http://vivo.scripps.edu/individual/n4519" )); - - - } - - - @Test - public void testClinicalRoleChangesForProject(){ - - String n3 = - - " \"3, Test\" . \n" + -// " \"3\"^^ .\n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " \"Clinical Role\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Project1\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the project needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4858"); - assertTrue("did not find project for clinical role", uris.contains("http://vivo.scripps.edu/individual/n5177" )); - - //if the project changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n5177"); - assertTrue("did not find person for clinical role", uris.contains("http://vivo.scripps.edu/individual/n4858" )); - - } - - @Test - public void testClinicalRoleChangesForService(){ - - String n3 = - - " \"4, Test\" . \n" + -// " \"4\"^^ . \n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " \"Clinical Role 2\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Service1\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the service needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n5651"); - assertTrue("did not find service for clinical role", uris.contains("http://vivo.scripps.edu/individual/n4442" )); - - //if the service changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4442"); - assertTrue("did not find person for clinical role", uris.contains("http://vivo.scripps.edu/individual/n5651" )); - - - } - - - @Test - public void testPresenterRoleChangesForPresentation(){ - String n3 = - " . \n" + - " \"5, Test\" . \n" + -// " \"5\"^^ . \n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " \"Presenter Role\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Presentation 1\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the presentation needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n5596"); - assertTrue("did not find service for clinical role", uris.contains("http://vivo.scripps.edu/individual/n1305" )); - - //if the presentation changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n1305"); - assertTrue("did not find person for clinical role", uris.contains("http://vivo.scripps.edu/individual/n5596" )); - - } - - - @Test - public void testPresenterRoleChangesForInvitedTalk(){ - String n3 = - - " . \n " + - " \"6, Test\" . \n " + -// " \"6\"^^ . \n " + -// " \"Test\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - " . \n " + - " \"Presenter Role 2\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - " \"Invited Talk 1\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the invited talk needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4112"); - assertTrue("did not find invited talk for person", uris.contains("http://vivo.scripps.edu/individual/n4107" )); - - //if the invited talk changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4107"); - assertTrue("did not find person for invited talk", uris.contains("http://vivo.scripps.edu/individual/n4112" )); - - } - - - @Test - public void testResearcherRoleForGrant(){ - - String n3 = - - " \"7, Test\" . \n" + -// " \"7\"^^ . \n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Researcher Role\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Grant1\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the grant needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4957"); - assertTrue("did not find service for clinical role", uris.contains("http://vivo.scripps.edu/individual/n4252" )); - - //if the grant changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4252"); - assertTrue("did not find person for clinical role", uris.contains("http://vivo.scripps.edu/individual/n4957" )); - - - } - - @Test - public void testResearcherRoleForProject(){ - - String n3 = - - " \"8, Test\" . \n " + -// " \"8\"^^ . \n " + -// " \"Test\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - " \"Researcher Role 2\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - - - " \"Project2\"^^ . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " + - " . \n " ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the project needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n2029"); - assertTrue("did not find service for clinical role", uris.contains("http://vivo.scripps.edu/individual/n564" )); - - //if the project changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n564"); - assertTrue("did not find person for clinical role", uris.contains("http://vivo.scripps.edu/individual/n2029" )); - - - } - - @Test - public void testPrincipalInvestigatorRoleChanges(){ - - String n3 = - - " . \n" + - " \"8, Test\" . \n" + -// " \"8\"^^ . \n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Grant 2\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the person changes then the grant needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n2368"); - assertTrue("did not find grant for pi", uris.contains("http://vivo.scripps.edu/individual/n1742" )); - - //if the grant changes then the person needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n1742"); - assertTrue("did not find pi for grant", uris.contains("http://vivo.scripps.edu/individual/n2368" )); - - - } - - @Test - public void testCoPrincipalInvestigatorRoleChanges(){ - - String n3 = - - " \"9, Test\" . \n" + -// " \"9\"^^ . \n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Grant 3\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the copi changes then the grant needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n1373"); - assertTrue("did not find grant for co-pi", uris.contains("http://vivo.scripps.edu/individual/n4931" )); - - //if the grant changes then the copi needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n4931"); - assertTrue("did not find co-pi for grant", uris.contains("http://vivo.scripps.edu/individual/n1373" )); - - } - - - @Test - public void testInvestigatorRoleChanges(){ - - String n3 = - - " \"10, Test\" . \n" + -// " \"10\"^^ . \n" + -// " \"Test\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - - " \"Grant 4\"^^ . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" + - " . \n" ; - - populateModelAndCreateUriFinder(n3); - - //if the investigator changes then the grant needs to be updated - List uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n5282"); - assertTrue("did not find grant for investigator", uris.contains("http://vivo.scripps.edu/individual/n160" )); - - //if the grant changes then the investigator needs to be updated - uris = uriFinder.findAdditionalURIsToIndex( "http://vivo.scripps.edu/individual/n160"); - assertTrue("did not find investigator for grant", uris.contains("http://vivo.scripps.edu/individual/n5282" )); - - } - - // ---------------------------------------------------------------------- - // Helper methods - // ---------------------------------------------------------------------- - - /** - * Build a Model from this N3 string, and create a URI Finder based on that - * Model. - */ - private void populateModelAndCreateUriFinder(String n3String) { - OntModel model = ModelFactory.createOntologyModel(); - model.read(new StringReader(n3String), null, "N3"); - - ContextModelAccessStub cmas = new ContextModelAccessStub(); - cmas.setRDFService(WhichService.CONTENT, new RDFServiceModel(model)); - - uriFinder = new AdditionalURIsForContextNodes(); - uriFinder.setContextModels(cmas); - } -}