applying ABox update to all graphs

This commit is contained in:
brianjlowe 2013-09-12 10:37:24 -04:00
parent f7d03b6de8
commit d5c032f33e
4 changed files with 334 additions and 256 deletions

View file

@ -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);
Iterator<String> graphIt = dataset.listNames();
try { while(graphIt.hasNext()) {
String graph = graphIt.next();
Model additions = ModelFactory.createDefaultModel(); if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
Model retractions = ModelFactory.createDefaultModel(); continue;
}
//TODO - look for these in the models and log error if not found Model aboxModel = dataset.getNamedModel(graph);
Resource oldClass = ResourceFactory.createResource(change.getSourceURI()); aboxModel.enterCriticalSection(Lock.WRITE);
Resource newClass = ResourceFactory.createResource(change.getDestinationURI()); try {
// Change class references in the subjects of statements Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
// BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads." //TODO - look for these in the models and log error if not found
// For now, the best behavior is to remove any remaining statements Resource oldClass = ResourceFactory.createResource(change.getSourceURI());
// where the old class is the subject, *unless* the statements Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
// is part of the new annotations file (see comment below) or the
// predicate is vitro:autolinkedToTab. In the latter case, // Change class references in the subjects of statements
// the autolinking annotation should be rewritten using the
// new class name. // BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads."
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null); // For now, the best behavior is to remove any remaining statements
// where the old class is the subject, *unless* the statements
int removeCount = 0; // is part of the new annotations file (see comment below) or the
while (iter.hasNext()) { // predicate is vitro:autolinkedToTab. In the latter case,
Statement oldStatement = iter.next(); // the autolinking annotation should be rewritten using the
removeCount++; // new class name.
retractions.add(oldStatement);
} StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
//log summary of changes int removeCount = 0;
if (removeCount > 0) { while (iter.hasNext()) {
logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class"); Statement oldStatement = iter.next();
} removeCount++;
retractions.add(oldStatement);
// Change class references in the objects of rdf:type statements }
iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
//log summary of changes
int renameCount = 0; if (removeCount > 0) {
while (iter.hasNext()) { logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
renameCount++; }
Statement oldStatement = iter.next();
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass); // Change class references in the objects of rdf:type statements
retractions.add(oldStatement); iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
additions.add(newStatement);
} int renameCount = 0;
while (iter.hasNext()) {
//log summary of changes renameCount++;
if (renameCount > 0) { Statement oldStatement = iter.next();
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI()); Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass);
} retractions.add(oldStatement);
additions.add(newStatement);
aboxModel.remove(retractions); }
record.recordRetractions(retractions);
aboxModel.add(additions); //log summary of changes
record.recordAdditions(additions); if (renameCount > 0) {
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI());
} finally { }
aboxModel.leaveCriticalSection();
} aboxModel.remove(retractions);
record.recordRetractions(retractions);
aboxModel.add(additions);
record.recordAdditions(additions);
} finally {
aboxModel.leaveCriticalSection();
}
}
} }
/** /**
@ -233,24 +245,26 @@ 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()) {
int count = stmtIter.toList().size(); String graph = graphIt.next();
if (count > 0) { if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
String indList = ""; }
while (stmtIter.hasNext()) { Model aboxModel = dataset.getNamedModel(graph);
Statement stmt = stmtIter.next();
indList += "\n\t" + stmt.getSubject().getURI(); StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass);
}
int count = stmtIter.toList().size();
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.
logger.log("There " + ((count > 1) ? "are" : "is") + " " + count + " individual" + ((count > 1) ? "s" : "") + " in the model that " + ((count > 1) ? "are" : "is") + " of type " + parentOfAddedClass.getURI() + "," + logger.log("There " + ((count > 1) ? "are" : "is") + " " + count + " individual" + ((count > 1) ? "s" : "") + " in the model that " + ((count > 1) ? "are" : "is") + " of type " + parentOfAddedClass.getURI() + "," +
" 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;
}
while (iter.hasNext()) { Model aboxModel = dataset.getNamedModel(graph);
count++; aboxModel.enterCriticalSection(Lock.WRITE);
Statement typeStmt = iter.next(); try {
refCount = deleteIndividual(typeStmt.getSubject()); int count = 0;
} int refCount = 0;
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass);
if (count > 0) {
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")"); while (iter.hasNext()) {
} count++;
Statement typeStmt = iter.next();
} finally { refCount = deleteIndividual(typeStmt.getSubject());
aboxModel.leaveCriticalSection(); }
}
if (count > 0) {
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")");
}
} finally {
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)){
while (iter.hasNext()) { continue;
Statement subjstmt = iter.next(); }
retractions.add(subjstmt); Model aboxModel = dataset.getNamedModel(graph);
} aboxModel.enterCriticalSection(Lock.WRITE);
try {
iter = aboxModel.listStatements((Resource) null, (Property) null, individual); StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null);
while (iter.hasNext()) { while (iter.hasNext()) {
Statement objstmt = iter.next(); Statement subjstmt = iter.next();
retractions.add(objstmt); retractions.add(subjstmt);
refCount++; }
}
iter = aboxModel.listStatements((Resource) null, (Property) null, individual);
aboxModel.remove(retractions);
record.recordRetractions(retractions); while (iter.hasNext()) {
Statement objstmt = iter.next();
} finally { retractions.add(objstmt);
aboxModel.leaveCriticalSection(); refCount++;
} }
aboxModel.remove(retractions);
record.recordRetractions(retractions);
} finally {
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()) {
try { String graph = graphIt.next();
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null); if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
while (iter.hasNext()) { }
Model aboxModel = dataset.getNamedModel(graph);
Statement stmt = iter.next(); aboxModel.enterCriticalSection(Lock.WRITE);
if (stmt.getObject().isResource()) { try {
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject()); StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
additions.add(newStmt);
} else { while (iter.hasNext()) {
logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
} Statement stmt = iter.next();
}
if (stmt.getObject().isResource()) {
aboxModel.add(additions); Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
record.recordAdditions(additions); additions.add(newStmt);
} else {
if (additions.size() > 0) { 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("Added " + additions.size() + " statement" + }
((additions.size() > 1) ? "s" : "") + }
" with predicate " + addedProperty.getURI() +
" (as an inverse to existing " + inverseOfAddedProperty.getURI() + aboxModel.add(additions);
" statement" + ((additions.size() > 1) ? "s" : "") + ")"); record.recordAdditions(additions);
}
if (additions.size() > 0) {
} finally { logger.log("Added " + additions.size() + " statement" +
aboxModel.leaveCriticalSection(); ((additions.size() > 1) ? "s" : "") +
} " with predicate " + addedProperty.getURI() +
" (as an inverse to existing " + inverseOfAddedProperty.getURI() +
" statement" + ((additions.size() > 1) ? "s" : "") + ")");
}
} finally {
aboxModel.leaveCriticalSection();
}
}
} }
} }
@ -507,27 +545,35 @@ public class ABoxUpdater {
} }
} }
Model deletePropModel = ModelFactory.createDefaultModel(); Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
if (replacementProperty == null) { String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
aboxModel.enterCriticalSection(Lock.WRITE); continue;
try { }
deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null)); Model aboxModel = dataset.getNamedModel(graph);
aboxModel.remove(deletePropModel); Model deletePropModel = ModelFactory.createDefaultModel();
} finally {
aboxModel.leaveCriticalSection(); if (replacementProperty == null) {
}
record.recordRetractions(deletePropModel); aboxModel.enterCriticalSection(Lock.WRITE);
boolean plural = (deletePropModel.size() > 1); try {
if (deletePropModel.size() > 0) { deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null));
logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " + aboxModel.remove(deletePropModel);
propObj.getSourceURI()); } finally {
} aboxModel.leaveCriticalSection();
} else { }
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes()); record.recordRetractions(deletePropModel);
renameProperty(chg); boolean plural = (deletePropModel.size() > 1);
} if (deletePropModel.size() > 0) {
logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " +
propObj.getSourceURI());
}
} else {
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes());
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)); aboxModel.enterCriticalSection(Lock.WRITE);
StmtIterator stmItr = renamePropRetractModel.listStatements(); try {
while(stmItr.hasNext()) { renamePropRetractModel.add( aboxModel.listStatements(
Statement tempStatement = stmItr.nextStatement(); (Resource) null, oldProperty, (RDFNode) null));
renamePropAddModel.add( tempStatement.getSubject(), StmtIterator stmItr = renamePropRetractModel.listStatements();
newProperty, while(stmItr.hasNext()) {
tempStatement.getObject() ); Statement tempStatement = stmItr.nextStatement();
} renamePropAddModel.add( tempStatement.getSubject(),
aboxModel.remove(renamePropRetractModel); newProperty,
aboxModel.add(renamePropAddModel); tempStatement.getObject() );
} finally { }
aboxModel.leaveCriticalSection(); aboxModel.remove(renamePropRetractModel);
} aboxModel.add(renamePropAddModel);
} finally {
record.recordAdditions(renamePropAddModel); aboxModel.leaveCriticalSection();
record.recordRetractions(renamePropRetractModel); }
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 {

View file

@ -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()) {
Statement stmt = stmtIt.nextStatement();
if (!writeModel.contains(stmt)) {
actualAdditions.add(stmt);
} }
} Model writeModel = dataset.getNamedModel(graph);
writeModel.add(actualAdditions); if (writeModel.contains(stmt)) {
//log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs"); writeModel.remove(stmt);
record.recordAdditions(actualAdditions); }
} }
} finally { }
writeModel.leaveCriticalSection(); record.recordRetractions(anonModel);
//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());
} }
@ -366,8 +372,10 @@ public class KnowledgeBaseUpdater {
" update to new ontology version: ", e); " update to new ontology version: ", e);
} }
} }
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;
} }
} }
} }

View file

@ -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;
}
} }

View file

@ -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 {