plugin infrastructure unit test
This commit is contained in:
parent
cb9a6e1902
commit
e0c5be5c42
3 changed files with 299 additions and 0 deletions
|
@ -0,0 +1,145 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.reasoner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mindswap.pellet.jena.PelletReasonerFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
|
import com.hp.hpl.jena.ontology.OntProperty;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
|
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.Resource;
|
||||||
|
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.testing.AbstractTestClass;
|
||||||
|
|
||||||
|
public class SimpleReasonerPluginTest extends AbstractTestClass {
|
||||||
|
long delay = 50;
|
||||||
|
|
||||||
|
private final static String DEFAULT_NS = "http://vivoweb.org/individual/";
|
||||||
|
|
||||||
|
private final static String DCTERMS_NS = "http://purl.org/dc/terms/";
|
||||||
|
private final static String VIVOCORE_NS = "http://vivoweb.org/ontology/core#";
|
||||||
|
|
||||||
|
private final static String creator_URI = DCTERMS_NS + "creator";
|
||||||
|
private final static String authorInAuthorship_URI = VIVOCORE_NS + "authorInAuthorship";
|
||||||
|
private final static String linkedAuthor_URI = VIVOCORE_NS + "linkedAuthor";
|
||||||
|
private final static String informationResourceInAuthorship_URI = VIVOCORE_NS + "informationResourceInAuthorship";
|
||||||
|
private final static String linkedInformationResource_URI = VIVOCORE_NS + "linkedInformationResource";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void suppressErrorOutput() {
|
||||||
|
//suppressSyserr();
|
||||||
|
//Turn off log messages to console
|
||||||
|
setLoggerLevel(SimpleReasoner.class, Level.DEBUG);
|
||||||
|
setLoggerLevel(SimpleReasonerTBoxListener.class, Level.DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testing samplePlugin - based on dcterms:creator plugin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
|
||||||
|
|
||||||
|
OntProperty authorInAuthorship = tBox.createObjectProperty(authorInAuthorship_URI);
|
||||||
|
OntProperty linkedAuthor = tBox.createObjectProperty(linkedAuthor_URI);
|
||||||
|
OntProperty informationResourceInAuthorship = tBox.createObjectProperty(informationResourceInAuthorship_URI);
|
||||||
|
OntProperty linkedInformationResource = tBox.createObjectProperty(linkedInformationResource_URI);
|
||||||
|
|
||||||
|
authorInAuthorship.addInverseOf(linkedAuthor);
|
||||||
|
informationResourceInAuthorship.addInverseOf(linkedInformationResource);
|
||||||
|
|
||||||
|
Literal title1 = tBox.createLiteral("My Findings");
|
||||||
|
Literal name1 = tBox.createLiteral("Priscilla Powers");
|
||||||
|
|
||||||
|
// this is the model to receive inferences
|
||||||
|
Model inf = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
|
// create an ABox and register the SimpleReasoner listener with it
|
||||||
|
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
|
||||||
|
aBox.register(simpleReasoner);
|
||||||
|
|
||||||
|
// register plugin with SimpleReasoner
|
||||||
|
List<ReasonerPlugin> pluginList = new ArrayList<ReasonerPlugin>();
|
||||||
|
String pluginClassName = "edu.cornell.mannlib.vitro.webapp.reasoner.plugin.SamplePlugin";
|
||||||
|
|
||||||
|
try {
|
||||||
|
ReasonerPlugin plugin = (ReasonerPlugin) Class.forName(pluginClassName).getConstructors()[0].newInstance();
|
||||||
|
plugin.setSimpleReasoner(simpleReasoner);
|
||||||
|
pluginList.add(plugin);
|
||||||
|
simpleReasoner.setPluginList(pluginList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Exception trying to instantiate plugin: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Property dctermsCreator = ResourceFactory.createProperty(creator_URI);
|
||||||
|
|
||||||
|
// add abox data for person, authorship and article.
|
||||||
|
// note, they aren't actually typed in this test tbox
|
||||||
|
Resource prissy = aBox.createResource(DEFAULT_NS + "prissy");
|
||||||
|
|
||||||
|
// assert same as
|
||||||
|
|
||||||
|
Resource authorship1 = aBox.createResource(DEFAULT_NS + "authorship1");
|
||||||
|
Resource article1 = aBox.createResource(DEFAULT_NS + "article1");
|
||||||
|
Resource article100 = aBox.createResource(DEFAULT_NS + "article100");
|
||||||
|
|
||||||
|
aBox.add(prissy,RDFS.label,name1);
|
||||||
|
aBox.add(prissy,authorInAuthorship,authorship1);
|
||||||
|
|
||||||
|
aBox.add(authorship1,linkedAuthor,prissy);
|
||||||
|
aBox.add(authorship1,linkedInformationResource,article1);
|
||||||
|
|
||||||
|
aBox.add(article1,RDFS.label,title1);
|
||||||
|
aBox.add(article1,informationResourceInAuthorship,authorship1);
|
||||||
|
aBox.add(article1, OWL.sameAs, article100);
|
||||||
|
|
||||||
|
Assert.assertTrue(inf.contains(article1,dctermsCreator,prissy));
|
||||||
|
Assert.assertTrue(inf.contains(article100,dctermsCreator,prissy));
|
||||||
|
|
||||||
|
aBox.remove(authorship1,linkedAuthor,prissy);
|
||||||
|
|
||||||
|
Assert.assertFalse(inf.contains(article1,dctermsCreator,prissy));
|
||||||
|
Assert.assertFalse(inf.contains(article100,dctermsCreator,prissy));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==================================== Utility methods ====================
|
||||||
|
SimpleReasonerTBoxListener getTBoxListener(SimpleReasoner simpleReasoner) {
|
||||||
|
return new SimpleReasonerTBoxListener(simpleReasoner, new Exception().getStackTrace()[1].getMethodName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// To help in debugging the unit test
|
||||||
|
void printModel(Model model, String modelName) {
|
||||||
|
|
||||||
|
System.out.println("\nThe " + modelName + " model has " + model.size() + " statements:");
|
||||||
|
System.out.println("---------------------------------------------------------------------");
|
||||||
|
model.write(System.out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To help in debugging the unit test
|
||||||
|
void printModel(OntModel ontModel, String modelName) {
|
||||||
|
|
||||||
|
System.out.println("\nThe " + modelName + " model has " + ontModel.size() + " statements:");
|
||||||
|
System.out.println("---------------------------------------------------------------------");
|
||||||
|
ontModel.writeAll(System.out,"N3",null);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.reasoner.plugin;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin;
|
||||||
|
|
||||||
|
public class SamplePlugin extends SimpleBridgingRule implements ReasonerPlugin {
|
||||||
|
|
||||||
|
private final static String DCTERMS = "http://purl.org/dc/terms/";
|
||||||
|
private final static String VIVOCORE = "http://vivoweb.org/ontology/core#";
|
||||||
|
|
||||||
|
public SamplePlugin() {
|
||||||
|
super(VIVOCORE + "informationResourceInAuthorship",
|
||||||
|
VIVOCORE + "linkedAuthor",
|
||||||
|
DCTERMS + "creator");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.reasoner.plugin;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
import com.hp.hpl.jena.query.Query;
|
||||||
|
import com.hp.hpl.jena.query.QueryExecution;
|
||||||
|
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||||
|
import com.hp.hpl.jena.query.QueryFactory;
|
||||||
|
import com.hp.hpl.jena.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.Resource;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handles rules of the form
|
||||||
|
* assertedProp1(?x, ?y) ^ assertedProp2(?y, ?z) -> inferredProp(?x, ?z)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class SimpleBridgingRule implements ReasonerPlugin {
|
||||||
|
|
||||||
|
private Property assertedProp1;
|
||||||
|
private Property assertedProp2;
|
||||||
|
private String queryStr;
|
||||||
|
private SimpleReasoner simpleReasoner;
|
||||||
|
|
||||||
|
protected SimpleBridgingRule(String assertedProp1, String assertedProp2, String inferredProp) {
|
||||||
|
this.assertedProp1 = ResourceFactory.createProperty(assertedProp1);
|
||||||
|
this.assertedProp2 = ResourceFactory.createProperty(assertedProp2);
|
||||||
|
|
||||||
|
this.queryStr = "CONSTRUCT { \n" +
|
||||||
|
" ?x <" + inferredProp + "> ?z \n" +
|
||||||
|
"} WHERE { \n" +
|
||||||
|
" ?x <" + assertedProp1 + "> ?y . \n" +
|
||||||
|
" ?y <" + assertedProp2 + "> ?z \n" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInterestedInAddedStatement(Statement stmt) {
|
||||||
|
return isRelevantPredicate(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInterestedInRemovedStatement(Statement stmt) {
|
||||||
|
return isRelevantPredicate(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addedABoxStatement(Statement stmt,
|
||||||
|
Model aboxAssertionsModel,
|
||||||
|
Model aboxInferencesModel,
|
||||||
|
OntModel TBoxInferencesModel) {
|
||||||
|
if (ignore(stmt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Model inf = constructInferences(stmt, aboxAssertionsModel);
|
||||||
|
StmtIterator sit = inf.listStatements();
|
||||||
|
while(sit.hasNext()) {
|
||||||
|
Statement s = sit.nextStatement();
|
||||||
|
if (simpleReasoner != null) simpleReasoner.addInference(s,aboxInferencesModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ignore(Statement stmt) {
|
||||||
|
return (
|
||||||
|
(stmt.getSubject().isAnon() || stmt.getObject().isAnon())
|
||||||
|
// can't deal with blank nodes
|
||||||
|
||
|
||||||
|
(!stmt.getObject().isResource())
|
||||||
|
// don't deal with literal values
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Model constructInferences(Statement stmt, Model aboxAssertionsModel) {
|
||||||
|
String queryStr = new String(this.queryStr);
|
||||||
|
if (stmt.getPredicate().equals(assertedProp1)) {
|
||||||
|
queryStr = queryStr.replace(
|
||||||
|
"?x", "<" + stmt.getSubject().getURI() + ">");
|
||||||
|
queryStr = queryStr.replace(
|
||||||
|
"?y", "<" + ((Resource) stmt.getObject()).getURI() + ">");
|
||||||
|
} else if (stmt.getPredicate().equals(assertedProp2)) {
|
||||||
|
queryStr = queryStr.replace(
|
||||||
|
"?y", "<" + stmt.getSubject().getURI() + ">");
|
||||||
|
queryStr = queryStr.replace(
|
||||||
|
"?z", "<" + ((Resource) stmt.getObject()).getURI() + ">");
|
||||||
|
} else {
|
||||||
|
// should never be here
|
||||||
|
return ModelFactory.createDefaultModel();
|
||||||
|
}
|
||||||
|
Query query = QueryFactory.create(queryStr);
|
||||||
|
QueryExecution qe = QueryExecutionFactory.create(query, aboxAssertionsModel);
|
||||||
|
try {
|
||||||
|
return qe.execConstruct();
|
||||||
|
} finally {
|
||||||
|
qe.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removedABoxStatement(Statement stmt,
|
||||||
|
Model aboxAssertionsModel,
|
||||||
|
Model aboxInferencesModel,
|
||||||
|
OntModel TBoxInferencesModel) {
|
||||||
|
if (ignore(stmt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Model m = ModelFactory.createDefaultModel();
|
||||||
|
m.add(stmt);
|
||||||
|
Model union = ModelFactory.createUnion(m, aboxAssertionsModel);
|
||||||
|
|
||||||
|
Model inf = constructInferences(stmt, union);
|
||||||
|
StmtIterator sit = inf.listStatements();
|
||||||
|
while(sit.hasNext()) {
|
||||||
|
Statement s = sit.nextStatement();
|
||||||
|
if (simpleReasoner != null) simpleReasoner.removeInference(s,aboxInferencesModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRelevantPredicate(Statement stmt) {
|
||||||
|
return (assertedProp1.equals(stmt.getPredicate())
|
||||||
|
|| assertedProp2.equals(stmt.getPredicate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSimpleReasoner(SimpleReasoner simpleReasoner) {
|
||||||
|
this.simpleReasoner = simpleReasoner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleReasoner getSimpleReasoner() {
|
||||||
|
return this.simpleReasoner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue