NIHVIVO-2830 (queue up retractions)
This commit is contained in:
parent
a3080709c2
commit
644e73b6ac
4 changed files with 153 additions and 6 deletions
|
@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSpecialModelMaker;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
||||
import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
|
||||
|
||||
|
@ -225,7 +226,18 @@ public class RDFUploadController extends BaseEditController {
|
|||
String userURI) {
|
||||
mainModel.enterCriticalSection(Lock.WRITE);
|
||||
try {
|
||||
mainModel.getBaseModel().notifyEvent(new EditEvent(userURI,true));
|
||||
|
||||
EditEvent startEvent = null, endEvent = null;
|
||||
|
||||
if (remove) {
|
||||
startEvent = new BulkUpdateEvent(userURI, true);
|
||||
endEvent = new BulkUpdateEvent(userURI, false);
|
||||
} else {
|
||||
startEvent = new EditEvent(userURI, true);
|
||||
endEvent = new EditEvent(userURI, false);
|
||||
}
|
||||
|
||||
mainModel.getBaseModel().notifyEvent(startEvent);
|
||||
try {
|
||||
if (makeClassgroups) {
|
||||
Model classgroupModel =
|
||||
|
@ -239,7 +251,7 @@ public class RDFUploadController extends BaseEditController {
|
|||
mainModel.add(changesModel);
|
||||
}
|
||||
} finally {
|
||||
mainModel.getBaseModel().notifyEvent(new EditEvent(userURI,false));
|
||||
mainModel.getBaseModel().notifyEvent(endEvent);
|
||||
}
|
||||
} finally {
|
||||
mainModel.leaveCriticalSection();
|
||||
|
|
|
@ -184,6 +184,7 @@ public class VitroVocabulary {
|
|||
public static final String EDIT_EVENT_AGENT = vitroURI+"editEventAgent";
|
||||
public static final String EDIT_EVENT_DATETIME = vitroURI+"editEventDateTime";
|
||||
|
||||
public static final String BULK_UPDATE_EVENT = vitroURI+"BulkUpdateEvent";
|
||||
public static final String INDIVIDUAL_EDIT_EVENT = vitroURI+"IndividualEditEvent";
|
||||
public static final String INDIVIDUAL_CREATION_EVENT = vitroURI+"IndividualCreationEvent";
|
||||
public static final String INDIVIDUAL_UPDATE_EVENT = vitroURI+"IndividualUpdateEvent";
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.dao.jena.event;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
|
||||
public class BulkUpdateEvent extends EditEvent {
|
||||
|
||||
private static final String BULK_UPDATE_EVENT = VitroVocabulary.BULK_UPDATE_EVENT;
|
||||
|
||||
public BulkUpdateEvent(String userURI, boolean begin) {
|
||||
super(userURI, begin);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,9 @@ import com.hp.hpl.jena.vocabulary.OWL;
|
|||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.CumulativeDeltaModeler;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
|
||||
|
||||
/**
|
||||
* Allows for real-time incremental materialization or retraction of RDFS-
|
||||
* style class and property subsumption based ABox inferences as statements
|
||||
|
@ -57,6 +60,10 @@ public class SimpleReasoner extends StatementListener {
|
|||
|
||||
private AnnotationProperty mostSpecificType = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createAnnotationProperty(mostSpecificTypePropertyURI);
|
||||
|
||||
private CumulativeDeltaModeler aBoxDeltaModeler1 = null;
|
||||
private CumulativeDeltaModeler aBoxDeltaModeler2 = null;
|
||||
private boolean batchMode1, batchMode2;
|
||||
|
||||
/**
|
||||
* @param tboxModel - input. This model contains both asserted and inferred TBox axioms
|
||||
* @param aboxModel - input. This model contains asserted ABox statements
|
||||
|
@ -70,9 +77,13 @@ public class SimpleReasoner extends StatementListener {
|
|||
this.aboxModel = aboxModel;
|
||||
this.inferenceModel = inferenceModel;
|
||||
this.inferenceRebuildModel = inferenceRebuildModel;
|
||||
this.scratchpadModel = scratchpadModel;
|
||||
this.scratchpadModel = scratchpadModel;
|
||||
this.batchMode1 = false;
|
||||
this.batchMode2 = false;
|
||||
aBoxDeltaModeler1 = new CumulativeDeltaModeler();
|
||||
aBoxDeltaModeler2 = new CumulativeDeltaModeler();
|
||||
|
||||
aboxModel.register(this);
|
||||
aboxModel.getBaseModel().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +99,10 @@ public class SimpleReasoner extends StatementListener {
|
|||
this.inferenceModel = inferenceModel;
|
||||
this.inferenceRebuildModel = ModelFactory.createDefaultModel();
|
||||
this.scratchpadModel = ModelFactory.createDefaultModel();
|
||||
aBoxDeltaModeler1 = new CumulativeDeltaModeler();
|
||||
aBoxDeltaModeler2 = new CumulativeDeltaModeler();
|
||||
this.batchMode1 = false;
|
||||
this.batchMode2 = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -124,14 +139,21 @@ public class SimpleReasoner extends StatementListener {
|
|||
|
||||
try {
|
||||
if (stmt.getPredicate().equals(RDF.type)) {
|
||||
removedABoxTypeAssertion(stmt, inferenceModel);
|
||||
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
|
||||
if (batchMode1) {
|
||||
aBoxDeltaModeler1.removedStatement(stmt);
|
||||
} else if (batchMode2) {
|
||||
aBoxDeltaModeler2.removedStatement(stmt);
|
||||
} else {
|
||||
removedABoxTypeAssertion(stmt, inferenceModel);
|
||||
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
|
||||
}
|
||||
}
|
||||
/* uncomment this to enable subproperty/equivalent property inferencing. sjm222 5/13/2011
|
||||
else {
|
||||
removedABoxAssertion(stmt, inferenceModel);
|
||||
}
|
||||
*/
|
||||
|
||||
} catch (Exception e) {
|
||||
// don't stop the edit if there's an exception
|
||||
log.error("Exception while retracting inferences: " + e.getMessage());
|
||||
|
@ -1191,6 +1213,103 @@ public class SimpleReasoner extends StatementListener {
|
|||
return (getSimpleReasonerFromServletContext(ctx) == null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void notifyEvent(Model model, Object event) {
|
||||
|
||||
if (event instanceof BulkUpdateEvent) {
|
||||
if (((BulkUpdateEvent) event).getBegin()) {
|
||||
|
||||
log.info("received BulkUpdateEvent(true)");
|
||||
|
||||
if (batchMode1 || batchMode2) {
|
||||
log.error("received a BulkUpdateEvent while already processing one; this event will be ignored and ABox reasoning may not be performed properly");
|
||||
return;
|
||||
} else {
|
||||
batchMode1 = true;
|
||||
batchMode2 = false;
|
||||
aBoxDeltaModeler1.getRetractions().removeAll();
|
||||
}
|
||||
} else {
|
||||
log.info("received BulkUpdateEvent(false)");
|
||||
new Thread(new DeltaComputer()).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DeltaComputer extends Thread {
|
||||
public DeltaComputer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Model retractions = aBoxDeltaModeler1.getRetractions();
|
||||
boolean finished = (retractions.size() == 0);
|
||||
String qualifier = "(1)";
|
||||
|
||||
while (!finished) {
|
||||
retractions.enterCriticalSection(Lock.READ);
|
||||
|
||||
try {
|
||||
log.info("started computing inferences for batch " + qualifier + " update");
|
||||
StmtIterator iter = retractions.listStatements();
|
||||
|
||||
int num = 0;
|
||||
while (iter.hasNext()) {
|
||||
Statement stmt = iter.next();
|
||||
|
||||
try {
|
||||
removedStatement(stmt);
|
||||
} catch (Exception e) {
|
||||
log.error("exception while computing inferences for batch " + qualifier + " update: " + e.getMessage());
|
||||
}
|
||||
|
||||
num++;
|
||||
if ((num % 6000) == 0) {
|
||||
log.info("still computing inferences for batch " + qualifier + " update...");
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
retractions.removeAll();
|
||||
retractions.leaveCriticalSection();
|
||||
log.info("finished computing inferences for batch " + qualifier + " update");
|
||||
}
|
||||
|
||||
|
||||
if (batchMode1 && (aBoxDeltaModeler2.getRetractions().size() > 0)) {
|
||||
retractions = aBoxDeltaModeler2.getRetractions();
|
||||
batchMode2 = true;
|
||||
batchMode1 = false;
|
||||
qualifier = "(2)";
|
||||
log.info("switching from batch mode 1 to batch mode 2");
|
||||
} else if (batchMode2 && (aBoxDeltaModeler1.getRetractions().size() > 0)) {
|
||||
retractions = aBoxDeltaModeler1.getRetractions();
|
||||
batchMode1 = true;
|
||||
batchMode2 = false;
|
||||
qualifier = "(1)";
|
||||
log.info("switching from batch mode 2 to batch mode 1");
|
||||
} else {
|
||||
finished = true;
|
||||
log.info("finished processing retractions in batch mode");
|
||||
}
|
||||
}
|
||||
|
||||
if (aBoxDeltaModeler1.getRetractions().size() > 0) {
|
||||
log.warn("Unexpected condition: the aBoxDeltaModeler1 retractions model was not empty at the end of the DeltaComputer.run method");
|
||||
aBoxDeltaModeler1.getRetractions().removeAll();
|
||||
}
|
||||
|
||||
if (aBoxDeltaModeler2.getRetractions().size() > 0) {
|
||||
log.warn("Unexpected condition: the aBoxDeltaModeler2 retractions model was not empty at the end of the DeltaComputer.run method");
|
||||
aBoxDeltaModeler2.getRetractions().removeAll();
|
||||
}
|
||||
|
||||
batchMode1 = false;
|
||||
batchMode2 = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String stmtString(Statement statement) {
|
||||
return " [subject = " + statement.getSubject().getURI() +
|
||||
"] [property = " + statement.getPredicate().getURI() +
|
||||
|
|
Loading…
Add table
Reference in a new issue