diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForClassGroupChanges.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForClassGroupChanges.java new file mode 100644 index 000000000..1f3aaac19 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForClassGroupChanges.java @@ -0,0 +1,66 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ +/** + * + */ +package edu.cornell.mannlib.vitro.webapp.search.indexing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.vocabulary.RDF; + +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.search.beans.AdditionalURIsToIndex; + +/** + * If a class changes classgroups, then all members of that class + * will have to be update in the search since the serach include + * the clasgroup membership of all individuals. + * + * Ex. when a statement like: + * sub='http://vivoweb.org/ontology/core#Summer' + * pred='http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inClassGroup' + * obj='http://vivoweb.org/ontology#vitroClassGrouppeople' + * changes, all members of the class core:Summer need to be update so they get the new classgroup values. + */ +public class AdditionalURIsForClassGroupChanges implements + AdditionalURIsToIndex { + + private OntModel model; + + public AdditionalURIsForClassGroupChanges(OntModel model) { + this.model = model; + } + + @Override + public List findAdditionalURIsToIndex(Statement stmt) { + if( stmt != null + && VitroVocabulary.IN_CLASSGROUP.equals( stmt.getPredicate().getURI() ) + && stmt.getSubject() != null ){ + // its a classgroup membership change for a class, + // update all individuals from the class. + List uris = new ArrayList(); + model.enterCriticalSection(Lock.READ); + try{ + StmtIterator iter = model.listStatements(null, RDF.type, stmt.getSubject()); + while( iter.hasNext() ){ + Statement typeStmt = iter.nextStatement(); + if( typeStmt != null && typeStmt.getSubject().isURIResource() ){ + uris.add(typeStmt.getSubject().getURI()); + } + } + }finally{ + model.leaveCriticalSection(); + } + return uris; + }else{ + return Collections.emptyList(); + } + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForClassGroupChangesTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForClassGroupChangesTest.java new file mode 100644 index 000000000..965b615ec --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/search/indexing/AdditionalURIsForClassGroupChangesTest.java @@ -0,0 +1,151 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ +/** + * + */ +package edu.cornell.mannlib.vitro.webapp.search.indexing; + +import static org.junit.Assert.*; + +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.vocabulary.OWL; +import com.hp.hpl.jena.vocabulary.RDFS; + +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.search.beans.AdditionalURIsToIndex; + +/** + * @author bdc34 + * + */ +public class AdditionalURIsForClassGroupChangesTest { + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + } + + /** + * Test method for {@link edu.cornell.mannlib.vitro.webapp.search.indexing.AdditionalURIsForClassGroupChanges#findAdditionalURIsToIndex(com.hp.hpl.jena.rdf.model.Statement)}. + */ + @Test + public void testFindAdditionalURIsToIndex() { + OntModel model = ModelFactory.createOntologyModel(); + model.read( new StringReader(n3ForPresentationClass), null, "N3"); + + AdditionalURIsToIndex uriFinder = new AdditionalURIsForClassGroupChanges( model ); + List uris = uriFinder.findAdditionalURIsToIndex( + ResourceFactory.createStatement( + ResourceFactory.createResource("http://vivoweb.org/ontology/core#Presentation"), + ResourceFactory.createProperty(VitroVocabulary.IN_CLASSGROUP), + ResourceFactory.createResource("http://example.com/someClassGroup"))); + + Assert.assertNotNull(uris); + Assert.assertTrue("uris list is empty", uris.size() > 0 ); + + Assert.assertTrue(uris.contains("http://vivo.scripps.edu/individual/n400")); + Assert.assertTrue(uris.contains("http://vivo.scripps.edu/individual/n12400")); + Assert.assertTrue(uris.contains("http://vivo.scripps.edu/individual/n210")); + Assert.assertTrue(uris.contains("http://vivo.scripps.edu/individual/n264")); + Assert.assertTrue(uris.contains("http://vivo.scripps.edu/individual/n25031")); + Assert.assertTrue(uris.contains("http://vivo.scripps.edu/individual/n2486")); + + Assert.assertTrue("uris list should not contain n9999",!uris.contains("http://vivo.scripps.edu/individual/n9999")); + Assert.assertTrue("uris list should not contain n9998",!uris.contains("http://vivo.scripps.edu/individual/n9998")); + +// Assert.assertTrue("uris didn't not contain test:onions", uris.contains(testNS+"onions")); +// Assert.assertTrue("uris didn't not contain test:cheese", uris.contains(testNS+"cheese")); +// Assert.assertTrue("uris didn't not contain test:icecream", uris.contains(testNS+"icecream")); +// +// Assert.assertTrue("uris contained test:Person", !uris.contains(testNS+"Person")); +// Assert.assertTrue("uris contained owl:Thing", !uris.contains( OWL.Thing.getURI() )); + } +String n3ForPresentationClass = + "@prefix dc: . \n" + + "@prefix pvs: . \n" + + "@prefix geo: . \n" + + "@prefix foaf: . \n" + + "@prefix scires: . \n" + + "@prefix scripps: . \n" + + "@prefix dcterms: . \n" + + "@prefix rdfs: . \n" + + "@prefix swrl: . \n" + + "@prefix vitro: . \n" + + "@prefix event: . \n" + + "@prefix bibo: . \n" + + "@prefix xsd: . \n" + + "@prefix owl: . \n" + + "@prefix swrlb: . \n" + + "@prefix rdf: . \n" + + "@prefix core: . \n" + + "@prefix skos: . \n" + + "@prefix vivo: . \n" + + "@prefix dcelem: . \n" + + "@prefix ero: . \n" + + " \n" + + "core:Presentation \n" + + " a owl:Class ; \n" + + " rdfs:label \"Presentation\"@en-US ; \n" + + " rdfs:subClassOf event:Event , owl:Thing ; \n" + + " vitro:displayLimitAnnot \n" + + " \"-1\"^^xsd:int ; \n" + + " vitro:displayRankAnnot \n" + + " \"-1\"^^xsd:int ; \n" + + " vitro:hiddenFromDisplayBelowRoleLevelAnnot \n" + + " ; \n" + + " vitro:inClassGroup ; \n" + + " vitro:prohibitedFromUpdateBelowRoleLevelAnnot \n" + + " ; \n" + + " vitro:shortDef \"Encompasses talk, speech, lecture, slide lecture, conference presentation\"^^xsd:string ; \n" + + " owl:equivalentClass core:Presentation . \n" + + " \n" + + " \n" + + "core:Presentation \n" + + " owl:equivalentClass core:Presentation . \n" + + " \n" + + " \n" + + " a core:Presentation . \n" + + " \n" + + " \n" + + " a core:Presentation . \n" + + " \n" + + " \n" + + " a core:Presentation . \n" + + " \n" + + " \n" + + " a core:Presentation ; \n" + + " vitro:mostSpecificType \n" + + " core:Presentation . \n" + + " \n" + + " \n" + + " a core:Presentation ; \n" + + " vitro:mostSpecificType \n" + + " core:Presentation . \n" + + " \n" + + " \n" + + " a core:Presentation ; \n" + + " vitro:mostSpecificType \n" + + " core:Presentation . \n" + + " \n " + + " \n" + + " a core:BogusClass . \n" + + " \n" + + " a core:BogusClass . \n" + + " \n" + + "core:InvitedTalk \n" + + " rdfs:subClassOf core:Presentation . \n" + + " \n" ; + + + +} \ No newline at end of file