applying ABox update to all graphs
This commit is contained in:
parent
f7d03b6de8
commit
d5c032f33e
4 changed files with 334 additions and 256 deletions
|
@ -14,6 +14,7 @@ import com.hp.hpl.jena.ontology.OntClass;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
import com.hp.hpl.jena.ontology.OntProperty;
|
import com.hp.hpl.jena.ontology.OntProperty;
|
||||||
|
import com.hp.hpl.jena.query.Dataset;
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
@ -27,7 +28,9 @@ import com.hp.hpl.jena.shared.Lock;
|
||||||
import com.hp.hpl.jena.vocabulary.OWL;
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
import com.hp.hpl.jena.vocabulary.RDF;
|
import com.hp.hpl.jena.vocabulary.RDF;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
|
||||||
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
|
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs knowledge base updates to the abox to align with a new ontology version
|
* Performs knowledge base updates to the abox to align with a new ontology version
|
||||||
|
@ -38,7 +41,8 @@ public class ABoxUpdater {
|
||||||
private final Log log = LogFactory.getLog(ABoxUpdater.class);
|
private final Log log = LogFactory.getLog(ABoxUpdater.class);
|
||||||
private OntModel oldTboxModel;
|
private OntModel oldTboxModel;
|
||||||
private OntModel newTboxModel;
|
private OntModel newTboxModel;
|
||||||
private OntModel aboxModel;
|
private Dataset dataset;
|
||||||
|
private RDFService rdfService;
|
||||||
private OntModel newTBoxAnnotationsModel;
|
private OntModel newTBoxAnnotationsModel;
|
||||||
private ChangeLogger logger;
|
private ChangeLogger logger;
|
||||||
private ChangeRecord record;
|
private ChangeRecord record;
|
||||||
|
@ -59,14 +63,15 @@ public class ABoxUpdater {
|
||||||
*/
|
*/
|
||||||
public ABoxUpdater(OntModel oldTboxModel,
|
public ABoxUpdater(OntModel oldTboxModel,
|
||||||
OntModel newTboxModel,
|
OntModel newTboxModel,
|
||||||
OntModel aboxModel,
|
RDFService rdfService,
|
||||||
OntModel newAnnotationsModel,
|
OntModel newAnnotationsModel,
|
||||||
ChangeLogger logger,
|
ChangeLogger logger,
|
||||||
ChangeRecord record) {
|
ChangeRecord record) {
|
||||||
|
|
||||||
this.oldTboxModel = oldTboxModel;
|
this.oldTboxModel = oldTboxModel;
|
||||||
this.newTboxModel = newTboxModel;
|
this.newTboxModel = newTboxModel;
|
||||||
this.aboxModel = aboxModel;
|
this.dataset = new RDFServiceDataset(rdfService);
|
||||||
|
this.rdfService = rdfService;
|
||||||
this.newTBoxAnnotationsModel = newAnnotationsModel;
|
this.newTBoxAnnotationsModel = newAnnotationsModel;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.record = record;
|
this.record = record;
|
||||||
|
@ -126,68 +131,75 @@ public class ABoxUpdater {
|
||||||
public void renameClass(AtomicOntologyChange change) throws IOException {
|
public void renameClass(AtomicOntologyChange change) throws IOException {
|
||||||
|
|
||||||
//logger.log("Processing a class rename from: " + change.getSourceURI() + " to " + change.getDestinationURI());
|
//logger.log("Processing a class rename from: " + change.getSourceURI() + " to " + change.getDestinationURI());
|
||||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
|
||||||
|
|
||||||
try {
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
|
while(graphIt.hasNext()) {
|
||||||
|
String graph = graphIt.next();
|
||||||
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
|
||||||
Model additions = ModelFactory.createDefaultModel();
|
Model additions = ModelFactory.createDefaultModel();
|
||||||
Model retractions = ModelFactory.createDefaultModel();
|
Model retractions = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
//TODO - look for these in the models and log error if not found
|
//TODO - look for these in the models and log error if not found
|
||||||
Resource oldClass = ResourceFactory.createResource(change.getSourceURI());
|
Resource oldClass = ResourceFactory.createResource(change.getSourceURI());
|
||||||
Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
|
Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
|
||||||
|
|
||||||
// Change class references in the subjects of statements
|
// Change class references in the subjects of statements
|
||||||
|
|
||||||
// BJL 2010-04-09 : In future versions we need to keep track of
|
// BJL 2010-04-09 : In future versions we need to keep track of
|
||||||
// the difference between true direct renamings and "use-insteads."
|
// the difference between true direct renamings and "use-insteads."
|
||||||
// For now, the best behavior is to remove any remaining statements
|
// For now, the best behavior is to remove any remaining statements
|
||||||
// where the old class is the subject, *unless* the statements
|
// where the old class is the subject, *unless* the statements
|
||||||
// is part of the new annotations file (see comment below) or the
|
// is part of the new annotations file (see comment below) or the
|
||||||
// predicate is vitro:autolinkedToTab. In the latter case,
|
// predicate is vitro:autolinkedToTab. In the latter case,
|
||||||
// the autolinking annotation should be rewritten using the
|
// the autolinking annotation should be rewritten using the
|
||||||
// new class name.
|
// new class name.
|
||||||
|
|
||||||
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
|
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
|
||||||
|
|
||||||
int removeCount = 0;
|
int removeCount = 0;
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement oldStatement = iter.next();
|
Statement oldStatement = iter.next();
|
||||||
removeCount++;
|
removeCount++;
|
||||||
retractions.add(oldStatement);
|
retractions.add(oldStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
//log summary of changes
|
//log summary of changes
|
||||||
if (removeCount > 0) {
|
if (removeCount > 0) {
|
||||||
logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
|
logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change class references in the objects of rdf:type statements
|
// Change class references in the objects of rdf:type statements
|
||||||
iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
|
iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
|
||||||
|
|
||||||
int renameCount = 0;
|
int renameCount = 0;
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
renameCount++;
|
renameCount++;
|
||||||
Statement oldStatement = iter.next();
|
Statement oldStatement = iter.next();
|
||||||
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass);
|
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass);
|
||||||
retractions.add(oldStatement);
|
retractions.add(oldStatement);
|
||||||
additions.add(newStatement);
|
additions.add(newStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
//log summary of changes
|
//log summary of changes
|
||||||
if (renameCount > 0) {
|
if (renameCount > 0) {
|
||||||
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI());
|
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
aboxModel.remove(retractions);
|
aboxModel.remove(retractions);
|
||||||
record.recordRetractions(retractions);
|
record.recordRetractions(retractions);
|
||||||
aboxModel.add(additions);
|
aboxModel.add(additions);
|
||||||
record.recordAdditions(additions);
|
record.recordAdditions(additions);
|
||||||
|
|
||||||
} finally {
|
|
||||||
aboxModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -233,16 +245,17 @@ public class ABoxUpdater {
|
||||||
|
|
||||||
if (!parentOfAddedClass.equals(OWL.Thing)) {
|
if (!parentOfAddedClass.equals(OWL.Thing)) {
|
||||||
|
|
||||||
StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass);
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
|
while(graphIt.hasNext()) {
|
||||||
|
String graph = graphIt.next();
|
||||||
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
|
||||||
int count = stmtIter.toList().size();
|
StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass);
|
||||||
if (count > 0) {
|
|
||||||
|
|
||||||
String indList = "";
|
int count = stmtIter.toList().size();
|
||||||
while (stmtIter.hasNext()) {
|
|
||||||
Statement stmt = stmtIter.next();
|
|
||||||
indList += "\n\t" + stmt.getSubject().getURI();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
//TODO - take out the detailed logging after our internal testing is completed.
|
//TODO - take out the detailed logging after our internal testing is completed.
|
||||||
|
@ -250,7 +263,8 @@ public class ABoxUpdater {
|
||||||
" and a new subclass of that class has been added: " + addedClass.getURI() + ". " +
|
" and a new subclass of that class has been added: " + addedClass.getURI() + ". " +
|
||||||
"Please review " + ((count > 1) ? "these" : "this") + " individual" + ((count > 1) ? "s" : "") + " to see whether " + ((count > 1) ? "they" : "it") + " should be of type: " + addedClass.getURI() );
|
"Please review " + ((count > 1) ? "these" : "this") + " individual" + ((count > 1) ? "s" : "") + " to see whether " + ((count > 1) ? "they" : "it") + " should be of type: " + addedClass.getURI() );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,25 +346,33 @@ public class ABoxUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove instances of the deleted class
|
// Remove instances of the deleted class
|
||||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
try {
|
while(graphIt.hasNext()) {
|
||||||
int count = 0;
|
String graph = graphIt.next();
|
||||||
int refCount = 0;
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass);
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
int count = 0;
|
||||||
|
int refCount = 0;
|
||||||
|
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
count++;
|
count++;
|
||||||
Statement typeStmt = iter.next();
|
Statement typeStmt = iter.next();
|
||||||
refCount = deleteIndividual(typeStmt.getSubject());
|
refCount = deleteIndividual(typeStmt.getSubject());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")");
|
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int deleteIndividual(Resource individual) throws IOException {
|
protected int deleteIndividual(Resource individual) throws IOException {
|
||||||
|
@ -358,29 +380,37 @@ public class ABoxUpdater {
|
||||||
Model retractions = ModelFactory.createDefaultModel();
|
Model retractions = ModelFactory.createDefaultModel();
|
||||||
int refCount = 0;
|
int refCount = 0;
|
||||||
|
|
||||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
try {
|
while(graphIt.hasNext()) {
|
||||||
StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null);
|
String graph = graphIt.next();
|
||||||
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement subjstmt = iter.next();
|
Statement subjstmt = iter.next();
|
||||||
retractions.add(subjstmt);
|
retractions.add(subjstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
iter = aboxModel.listStatements((Resource) null, (Property) null, individual);
|
iter = aboxModel.listStatements((Resource) null, (Property) null, individual);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Statement objstmt = iter.next();
|
Statement objstmt = iter.next();
|
||||||
retractions.add(objstmt);
|
retractions.add(objstmt);
|
||||||
refCount++;
|
refCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
aboxModel.remove(retractions);
|
aboxModel.remove(retractions);
|
||||||
record.recordRetractions(retractions);
|
record.recordRetractions(retractions);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
|
@ -439,37 +469,45 @@ public class ABoxUpdater {
|
||||||
|
|
||||||
if (inverseOfAddedProperty != null) {
|
if (inverseOfAddedProperty != null) {
|
||||||
Model additions = ModelFactory.createDefaultModel();
|
Model additions = ModelFactory.createDefaultModel();
|
||||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
|
while(graphIt.hasNext()) {
|
||||||
|
String graph = graphIt.next();
|
||||||
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
|
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
|
|
||||||
Statement stmt = iter.next();
|
Statement stmt = iter.next();
|
||||||
|
|
||||||
if (stmt.getObject().isResource()) {
|
if (stmt.getObject().isResource()) {
|
||||||
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
|
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
|
||||||
additions.add(newStmt);
|
additions.add(newStmt);
|
||||||
} else {
|
} else {
|
||||||
logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
|
logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aboxModel.add(additions);
|
aboxModel.add(additions);
|
||||||
record.recordAdditions(additions);
|
record.recordAdditions(additions);
|
||||||
|
|
||||||
if (additions.size() > 0) {
|
if (additions.size() > 0) {
|
||||||
logger.log("Added " + additions.size() + " statement" +
|
logger.log("Added " + additions.size() + " statement" +
|
||||||
((additions.size() > 1) ? "s" : "") +
|
((additions.size() > 1) ? "s" : "") +
|
||||||
" with predicate " + addedProperty.getURI() +
|
" with predicate " + addedProperty.getURI() +
|
||||||
" (as an inverse to existing " + inverseOfAddedProperty.getURI() +
|
" (as an inverse to existing " + inverseOfAddedProperty.getURI() +
|
||||||
" statement" + ((additions.size() > 1) ? "s" : "") + ")");
|
" statement" + ((additions.size() > 1) ? "s" : "") + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,27 +545,35 @@ public class ABoxUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Model deletePropModel = ModelFactory.createDefaultModel();
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
|
while(graphIt.hasNext()) {
|
||||||
|
String graph = graphIt.next();
|
||||||
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
Model deletePropModel = ModelFactory.createDefaultModel();
|
||||||
|
|
||||||
if (replacementProperty == null) {
|
if (replacementProperty == null) {
|
||||||
|
|
||||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null));
|
deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null));
|
||||||
aboxModel.remove(deletePropModel);
|
aboxModel.remove(deletePropModel);
|
||||||
} finally {
|
} finally {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
record.recordRetractions(deletePropModel);
|
record.recordRetractions(deletePropModel);
|
||||||
boolean plural = (deletePropModel.size() > 1);
|
boolean plural = (deletePropModel.size() > 1);
|
||||||
if (deletePropModel.size() > 0) {
|
if (deletePropModel.size() > 0) {
|
||||||
logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " +
|
logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " +
|
||||||
propObj.getSourceURI());
|
propObj.getSourceURI());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes());
|
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes());
|
||||||
renameProperty(chg);
|
renameProperty(chg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,35 +594,44 @@ public class ABoxUpdater {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model renamePropAddModel = ModelFactory.createDefaultModel();
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
Model renamePropRetractModel = ModelFactory.createDefaultModel();
|
while(graphIt.hasNext()) {
|
||||||
|
String graph = graphIt.next();
|
||||||
|
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Model aboxModel = dataset.getNamedModel(graph);
|
||||||
|
|
||||||
aboxModel.enterCriticalSection(Lock.WRITE);
|
Model renamePropAddModel = ModelFactory.createDefaultModel();
|
||||||
try {
|
Model renamePropRetractModel = ModelFactory.createDefaultModel();
|
||||||
renamePropRetractModel.add( aboxModel.listStatements(
|
|
||||||
(Resource) null, oldProperty, (RDFNode) null));
|
|
||||||
StmtIterator stmItr = renamePropRetractModel.listStatements();
|
|
||||||
while(stmItr.hasNext()) {
|
|
||||||
Statement tempStatement = stmItr.nextStatement();
|
|
||||||
renamePropAddModel.add( tempStatement.getSubject(),
|
|
||||||
newProperty,
|
|
||||||
tempStatement.getObject() );
|
|
||||||
}
|
|
||||||
aboxModel.remove(renamePropRetractModel);
|
|
||||||
aboxModel.add(renamePropAddModel);
|
|
||||||
} finally {
|
|
||||||
aboxModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
record.recordAdditions(renamePropAddModel);
|
aboxModel.enterCriticalSection(Lock.WRITE);
|
||||||
record.recordRetractions(renamePropRetractModel);
|
try {
|
||||||
|
renamePropRetractModel.add( aboxModel.listStatements(
|
||||||
|
(Resource) null, oldProperty, (RDFNode) null));
|
||||||
|
StmtIterator stmItr = renamePropRetractModel.listStatements();
|
||||||
|
while(stmItr.hasNext()) {
|
||||||
|
Statement tempStatement = stmItr.nextStatement();
|
||||||
|
renamePropAddModel.add( tempStatement.getSubject(),
|
||||||
|
newProperty,
|
||||||
|
tempStatement.getObject() );
|
||||||
|
}
|
||||||
|
aboxModel.remove(renamePropRetractModel);
|
||||||
|
aboxModel.add(renamePropAddModel);
|
||||||
|
} finally {
|
||||||
|
aboxModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
if (renamePropRetractModel.size() > 0) {
|
record.recordAdditions(renamePropAddModel);
|
||||||
logger.log("Changed " + renamePropRetractModel.size() + " statement" +
|
record.recordRetractions(renamePropRetractModel);
|
||||||
((renamePropRetractModel.size() > 1) ? "s" : "") +
|
|
||||||
" with predicate " + propObj.getSourceURI() + " to use " +
|
if (renamePropRetractModel.size() > 0) {
|
||||||
propObj.getDestinationURI() + " instead");
|
logger.log("Changed " + renamePropRetractModel.size() + " statement" +
|
||||||
}
|
((renamePropRetractModel.size() > 1) ? "s" : "") +
|
||||||
|
" with predicate " + propObj.getSourceURI() + " to use " +
|
||||||
|
propObj.getDestinationURI() + " instead");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logChanges(Statement oldStatement, Statement newStatement) throws IOException {
|
public void logChanges(Statement oldStatement, Statement newStatement) throws IOException {
|
||||||
|
|
|
@ -24,19 +24,16 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.query.Query;
|
import com.hp.hpl.jena.query.Dataset;
|
||||||
import com.hp.hpl.jena.query.QueryExecution;
|
|
||||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
|
||||||
import com.hp.hpl.jena.query.QueryFactory;
|
|
||||||
import com.hp.hpl.jena.query.Syntax;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
||||||
|
@ -123,10 +120,10 @@ public class KnowledgeBaseUpdater {
|
||||||
updateABox(changes);
|
updateABox(changes);
|
||||||
|
|
||||||
log.info("performing SPARQL CONSTRUCT additions");
|
log.info("performing SPARQL CONSTRUCT additions");
|
||||||
performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), readModel, writeModel, ADD);
|
performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD);
|
||||||
|
|
||||||
log.info("performing SPARQL CONSTRUCT retractions");
|
log.info("performing SPARQL CONSTRUCT retractions");
|
||||||
performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), readModel, writeModel, RETRACT);
|
performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,10 +141,11 @@ public class KnowledgeBaseUpdater {
|
||||||
* @param add (add = true; retract = false)
|
* @param add (add = true; retract = false)
|
||||||
*/
|
*/
|
||||||
private void performSparqlConstructs(String sparqlConstructDir,
|
private void performSparqlConstructs(String sparqlConstructDir,
|
||||||
OntModel readModel, OntModel writeModel,
|
RDFService rdfService,
|
||||||
boolean add) throws IOException {
|
boolean add) throws IOException {
|
||||||
|
Dataset dataset = new RDFServiceDataset(rdfService);
|
||||||
File sparqlConstructDirectory = new File(sparqlConstructDir);
|
File sparqlConstructDirectory = new File(sparqlConstructDir);
|
||||||
log.info("Using SPARQL CONSTRUCT director " + sparqlConstructDirectory);
|
log.info("Using SPARQL CONSTRUCT directory " + sparqlConstructDirectory);
|
||||||
if (!sparqlConstructDirectory.isDirectory()) {
|
if (!sparqlConstructDirectory.isDirectory()) {
|
||||||
String logMsg = this.getClass().getName() +
|
String logMsg = this.getClass().getName() +
|
||||||
"performSparqlConstructs() expected to find a directory " +
|
"performSparqlConstructs() expected to find a directory " +
|
||||||
|
@ -161,7 +159,6 @@ public class KnowledgeBaseUpdater {
|
||||||
Collections.sort(sparqlFiles); // queries may depend on being run in a certain order
|
Collections.sort(sparqlFiles); // queries may depend on being run in a certain order
|
||||||
JenaIngestUtils jiu = new JenaIngestUtils();
|
JenaIngestUtils jiu = new JenaIngestUtils();
|
||||||
for (File sparqlFile : sparqlFiles) {
|
for (File sparqlFile : sparqlFiles) {
|
||||||
Model anonModel = ModelFactory.createDefaultModel();
|
|
||||||
StringBuffer fileContents = new StringBuffer();
|
StringBuffer fileContents = new StringBuffer();
|
||||||
try {
|
try {
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(sparqlFile));
|
BufferedReader reader = new BufferedReader(new FileReader(sparqlFile));
|
||||||
|
@ -176,59 +173,68 @@ public class KnowledgeBaseUpdater {
|
||||||
log.info(logMsg);
|
log.info(logMsg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Model anonModel = ModelFactory.createDefaultModel();
|
||||||
try {
|
try {
|
||||||
log.info("\t\tprocessing SPARQL construct query from file " + sparqlFile.getName());
|
log.info("\t\tprocessing SPARQL construct query from file " + sparqlFile.getName());
|
||||||
Query q = QueryFactory.create(fileContents.toString(), Syntax.syntaxARQ);
|
|
||||||
readModel.enterCriticalSection(Lock.READ);
|
anonModel = RDFServiceUtils.parseModel(
|
||||||
try {
|
rdfService.sparqlConstructQuery(fileContents.toString(),
|
||||||
QueryExecution qe = QueryExecutionFactory.create(q, readModel);
|
RDFService.ModelSerializationFormat.NTRIPLE),
|
||||||
long numBefore = anonModel.size();
|
ModelSerializationFormat.NTRIPLE);
|
||||||
qe.execConstruct(anonModel);
|
|
||||||
long numAfter = anonModel.size();
|
long num = anonModel.size();
|
||||||
long num = numAfter - numBefore;
|
if (num > 0) {
|
||||||
if (num > 0) {
|
String logMsg = (add ? "Added " : "Removed ") + num +
|
||||||
String logMsg = (add ? "Added " : "Removed ") + num +
|
" statement" + ((num > 1) ? "s" : "") +
|
||||||
" statement" + ((num > 1) ? "s" : "") +
|
" using the SPARQL construct query from file " +
|
||||||
" using the SPARQL construct query from file " +
|
sparqlFile.getParentFile().getName() +
|
||||||
sparqlFile.getParentFile().getName() +
|
"/" + sparqlFile.getName();
|
||||||
"/" + sparqlFile.getName();
|
logger.log(logMsg);
|
||||||
logger.log(logMsg);
|
log.info(logMsg);
|
||||||
log.info(logMsg);
|
|
||||||
}
|
|
||||||
qe.close();
|
|
||||||
} finally {
|
|
||||||
readModel.leaveCriticalSection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.logError(this.getClass().getName() +
|
logger.logError(this.getClass().getName() +
|
||||||
".performSparqlConstructs() unable to execute " +
|
".performSparqlConstructs() unable to execute " +
|
||||||
"query at " + sparqlFile + ". Error message is: " + e.getMessage());
|
"query at " + sparqlFile + ". Error message is: " + e.getMessage());
|
||||||
log.error(e,e);
|
log.error(e,e);
|
||||||
}
|
}
|
||||||
writeModel.enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
if(!add) {
|
||||||
if(!add) {
|
StmtIterator sit = anonModel.listStatements();
|
||||||
writeModel.remove(anonModel);
|
while (sit.hasNext()) {
|
||||||
record.recordRetractions(anonModel);
|
Statement stmt = sit.nextStatement();
|
||||||
//log.info("removed " + anonModel.size() + " statements from SPARQL CONSTRUCTs");
|
Iterator<String> graphIt = dataset.listNames();
|
||||||
} else {
|
while(graphIt.hasNext()) {
|
||||||
Model additions = jiu.renameBNodes(
|
String graph = graphIt.next();
|
||||||
anonModel, settings.getDefaultNamespace() + "n", writeModel);
|
if(!isUpdatableABoxGraph(graph)) {
|
||||||
Model actualAdditions = ModelFactory.createDefaultModel();
|
continue;
|
||||||
StmtIterator stmtIt = additions.listStatements();
|
}
|
||||||
while (stmtIt.hasNext()) {
|
Model writeModel = dataset.getNamedModel(graph);
|
||||||
Statement stmt = stmtIt.nextStatement();
|
if (writeModel.contains(stmt)) {
|
||||||
if (!writeModel.contains(stmt)) {
|
writeModel.remove(stmt);
|
||||||
actualAdditions.add(stmt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeModel.add(actualAdditions);
|
|
||||||
//log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs");
|
|
||||||
record.recordAdditions(actualAdditions);
|
|
||||||
}
|
}
|
||||||
} finally {
|
record.recordRetractions(anonModel);
|
||||||
writeModel.leaveCriticalSection();
|
//log.info("removed " + anonModel.size() + " statements from SPARQL CONSTRUCTs");
|
||||||
|
} else {
|
||||||
|
Model writeModel = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL);
|
||||||
|
Model additions = jiu.renameBNodes(
|
||||||
|
anonModel, settings.getDefaultNamespace() + "n", writeModel);
|
||||||
|
Model actualAdditions = ModelFactory.createDefaultModel();
|
||||||
|
StmtIterator stmtIt = additions.listStatements();
|
||||||
|
while (stmtIt.hasNext()) {
|
||||||
|
Statement stmt = stmtIt.nextStatement();
|
||||||
|
if (!writeModel.contains(stmt)) {
|
||||||
|
actualAdditions.add(stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeModel.add(actualAdditions);
|
||||||
|
//log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs");
|
||||||
|
record.recordAdditions(actualAdditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +251,8 @@ public class KnowledgeBaseUpdater {
|
||||||
|
|
||||||
OntModel oldTBoxModel = settings.getOldTBoxModel();
|
OntModel oldTBoxModel = settings.getOldTBoxModel();
|
||||||
OntModel newTBoxModel = settings.getNewTBoxModel();
|
OntModel newTBoxModel = settings.getNewTBoxModel();
|
||||||
OntModel ABoxModel = settings.getAssertionOntModelSelector().getABoxModel();
|
RDFService rdfService = settings.getRDFService();
|
||||||
ABoxUpdater aboxUpdater = new ABoxUpdater(oldTBoxModel, newTBoxModel, ABoxModel,settings.getNewTBoxAnnotationsModel(), logger, record);
|
ABoxUpdater aboxUpdater = new ABoxUpdater(oldTBoxModel, newTBoxModel, rdfService, settings.getNewTBoxAnnotationsModel(), logger, record);
|
||||||
aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges());
|
aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges());
|
||||||
aboxUpdater.processClassChanges(changes.getAtomicClassChanges());
|
aboxUpdater.processClassChanges(changes.getAtomicClassChanges());
|
||||||
}
|
}
|
||||||
|
@ -367,7 +373,9 @@ public class KnowledgeBaseUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isUpdatableABoxGraph(String graphName) {
|
||||||
|
return (!graphName.contains("tbox") && !graphName.contains("filegraph"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that allows to access two different ontology change lists,
|
* A class that allows to access two different ontology change lists,
|
||||||
|
@ -434,5 +442,6 @@ public class KnowledgeBaseUpdater {
|
||||||
public List<AtomicOntologyChange> getAtomicPropertyChanges() {
|
public List<AtomicOntologyChange> getAtomicPropertyChanges() {
|
||||||
return atomicPropertyChanges;
|
return atomicPropertyChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.ontology.update;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
|
|
||||||
public class UpdateSettings {
|
public class UpdateSettings {
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ public class UpdateSettings {
|
||||||
private OntModel newDisplayModelFromFile;
|
private OntModel newDisplayModelFromFile;
|
||||||
private OntModel loadedAtStartupDisplayModel;
|
private OntModel loadedAtStartupDisplayModel;
|
||||||
private OntModel oldDisplayModelVivoListViewConfig;
|
private OntModel oldDisplayModelVivoListViewConfig;
|
||||||
|
private RDFService rdfService;
|
||||||
|
|
||||||
public String getDataDir() {
|
public String getDataDir() {
|
||||||
return dataDir;
|
return dataDir;
|
||||||
}
|
}
|
||||||
|
@ -223,6 +226,13 @@ public class UpdateSettings {
|
||||||
return this.oldDisplayModelVivoListViewConfig;
|
return this.oldDisplayModelVivoListViewConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RDFService getRDFService() {
|
||||||
|
return this.rdfService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRDFService(RDFService rdfService) {
|
||||||
|
this.rdfService = rdfService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;
|
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;
|
||||||
import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings;
|
import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +98,7 @@ public class UpdateKnowledgeBase implements ServletContextListener {
|
||||||
settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel);
|
settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel);
|
||||||
OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "everytime").toString());
|
OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "everytime").toString());
|
||||||
settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel);
|
settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel);
|
||||||
|
settings.setRDFService(RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService());
|
||||||
|
|
||||||
boolean tryMigrateDisplay = true;
|
boolean tryMigrateDisplay = true;
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue