VIVO-778 Connect the plumbing properly.
Make TBoxReasonerModule a module on the Application. Make the reasoner status available through the module. Initialize it in startup_listeners.txt Create a concrete class for PelletTBoxReasonerModule, and configure it in applicationSetup.n3 Get rid of PelletReasonerSetup. Make it so the ExecutorService in BasicTBoxReasonerDriver uses a VitroBackgroundThread.,
This commit is contained in:
parent
3d65a708b7
commit
fb97bae6af
21 changed files with 565 additions and 326 deletions
|
@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerModule;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
|
||||
|
@ -41,6 +42,7 @@ public class ApplicationImpl implements Application {
|
|||
private FileStorage fileStorage;
|
||||
private ContentTripleSource contentTripleSource;
|
||||
private ConfigurationTripleSource configurationTripleSource;
|
||||
private TBoxReasonerModule tboxReasonerModule;
|
||||
|
||||
public void setServletContext(ServletContext ctx) {
|
||||
this.ctx = ctx;
|
||||
|
@ -140,6 +142,22 @@ public class ApplicationImpl implements Application {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TBoxReasonerModule getTBoxReasonerModule() {
|
||||
return tboxReasonerModule;
|
||||
}
|
||||
|
||||
@Property(uri = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#hasTBoxReasonerModule")
|
||||
public void setTBoxReasonerModule(TBoxReasonerModule module) {
|
||||
if (tboxReasonerModule == null) {
|
||||
tboxReasonerModule = module;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Configuration includes multiple intances of TBoxReasonerModule: "
|
||||
+ tboxReasonerModule + ", and " + module);
|
||||
}
|
||||
}
|
||||
|
||||
@Validation
|
||||
public void validate() throws Exception {
|
||||
if (searchEngine == null) {
|
||||
|
@ -162,6 +180,10 @@ public class ApplicationImpl implements Application {
|
|||
throw new IllegalStateException(
|
||||
"Configuration did not include a ConfigurationTripleSource.");
|
||||
}
|
||||
if (tboxReasonerModule == null) {
|
||||
throw new IllegalStateException(
|
||||
"Configuration did not include a TBoxReasonerModule.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -244,4 +266,30 @@ public class ApplicationImpl implements Application {
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Setup the reasoners.
|
||||
//
|
||||
// This must happen after the FileGraphSetup.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static class ReasonersSetup implements ServletContextListener {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
Application app = ApplicationUtils.instance();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
ComponentStartupStatus css = new ComponentStartupStatusImpl(this,
|
||||
ss);
|
||||
|
||||
TBoxReasonerModule tboxReasoner = app.getTBoxReasonerModule();
|
||||
tboxReasoner.startup(app, css);
|
||||
ss.info(this, "Started the TBoxReasonerModule: " + tboxReasoner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
Application app = ApplicationUtils.instance();
|
||||
app.getTBoxReasonerModule().shutdown(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vedit.beans.Option;
|
||||
import edu.cornell.mannlib.vedit.util.FormUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
|
||||
|
@ -24,10 +25,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMa
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.search.controller.IndexController;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver.Status;
|
||||
|
||||
public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
||||
|
||||
|
@ -160,24 +160,21 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
|||
|
||||
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.EDIT_ONTOLOGY.ACTION)) {
|
||||
|
||||
String pelletError = null;
|
||||
String pelletExplanation = null;
|
||||
Object tbrObj = getServletContext().getAttribute("tboxReasoner");
|
||||
if ( tbrObj instanceof TBoxReasonerDriver) {
|
||||
Status status = ((TBoxReasonerDriver) tbrObj).getStatus();
|
||||
if (!status.isConsistent()) {
|
||||
pelletError = "INCONSISTENT ONTOLOGY: reasoning halted.";
|
||||
pelletExplanation = status.getExplanation();
|
||||
} else if ( status.isInErrorState() ) {
|
||||
pelletError = "An error occurred during reasoning. Reasoning has been halted. See error log for details.";
|
||||
}
|
||||
String error = null;
|
||||
String explanation = null;
|
||||
TBoxReasonerStatus status = ApplicationUtils.instance().getTBoxReasonerModule().getStatus();
|
||||
if (!status.isConsistent()) {
|
||||
error = "INCONSISTENT ONTOLOGY: reasoning halted.";
|
||||
explanation = status.getExplanation();
|
||||
} else if ( status.isInErrorState() ) {
|
||||
error = "An error occurred during reasoning. Reasoning has been halted. See error log for details.";
|
||||
}
|
||||
|
||||
if (pelletError != null) {
|
||||
if (error != null) {
|
||||
Map<String, String> pellet = new HashMap<String, String>();
|
||||
pellet.put("error", pelletError);
|
||||
if (pelletExplanation != null) {
|
||||
pellet.put("explanation", pelletExplanation);
|
||||
pellet.put("error", error);
|
||||
if (explanation != null) {
|
||||
pellet.put("explanation", explanation);
|
||||
}
|
||||
map.put("pellet", pellet);
|
||||
}
|
||||
|
|
|
@ -44,11 +44,12 @@ import com.hp.hpl.jena.vocabulary.RDF;
|
|||
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||
|
||||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerModule;
|
||||
|
||||
public class JenaAdminActions extends BaseEditController {
|
||||
|
||||
|
@ -191,9 +192,8 @@ public class JenaAdminActions extends BaseEditController {
|
|||
}
|
||||
|
||||
private void printRestrictions() {
|
||||
TBoxReasoner reasoner = (TBoxReasoner) getServletContext().getAttribute("tboxReasonerWrapper");
|
||||
TBoxReasonerModule reasoner = ApplicationUtils.instance().getTBoxReasonerModule();
|
||||
for (Restriction rest : reasoner.listRestrictions() ) {
|
||||
//System.out.println();
|
||||
if (rest.isAllValuesFromRestriction()) {
|
||||
log.trace("All values from: ");
|
||||
AllValuesFromRestriction avfr = rest.asAllValuesFromRestriction();
|
||||
|
|
|
@ -41,6 +41,7 @@ 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.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
||||
|
@ -51,8 +52,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver;
|
||||
|
||||
public class DataPropertyDaoJena extends PropertyDaoJena implements
|
||||
DataPropertyDao {
|
||||
|
@ -357,10 +358,8 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
|
|||
}
|
||||
|
||||
protected boolean reasoningAvailable() {
|
||||
TBoxReasonerDriver pl = getWebappDaoFactory().getTBoxReasonerDriver();
|
||||
return !(
|
||||
( pl == null || !pl.getStatus().isConsistent() || pl.getStatus().isInErrorState() )
|
||||
);
|
||||
TBoxReasonerStatus status = ApplicationUtils.instance().getTBoxReasonerModule().getStatus();
|
||||
return status.isConsistent() && !status.isInErrorState();
|
||||
}
|
||||
|
||||
private String getRequiredDatatypeURI(Individual individual, DataProperty dataprop, List<String> vclassURIs) {
|
||||
|
|
|
@ -50,7 +50,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig;
|
|||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.URIUtils;
|
||||
|
||||
public class WebappDaoFactoryJena implements WebappDaoFactory {
|
||||
|
@ -70,8 +69,6 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
|||
|
||||
protected WebappDaoFactoryConfig config;
|
||||
|
||||
protected TBoxReasonerDriver tbrd;
|
||||
|
||||
protected String userURI;
|
||||
|
||||
private Map<String,String> properties = new HashMap<String,String>();
|
||||
|
@ -238,18 +235,6 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
|||
return config.getNonUserNamespaces();
|
||||
}
|
||||
|
||||
/**
|
||||
* This enables the WebappDaoFactory to check the status of a reasoner.
|
||||
* This will likely be refactored in future releases.
|
||||
*/
|
||||
public void setTBoxReasonerDriver(TBoxReasonerDriver tbrd) {
|
||||
this.tbrd = tbrd;
|
||||
}
|
||||
|
||||
public TBoxReasonerDriver getTBoxReasonerDriver() {
|
||||
return this.tbrd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCommentsForResource(String resourceURI) {
|
||||
List<String> commentList = new LinkedList<String>();
|
||||
|
|
|
@ -8,12 +8,12 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerStatus;
|
||||
|
||||
public class IndividualsViaVClassOptions implements FieldOptions {
|
||||
|
||||
|
@ -101,20 +101,13 @@ public class IndividualsViaVClassOptions implements FieldOptions {
|
|||
return individualMap;
|
||||
}
|
||||
|
||||
protected boolean isReasoningAvailable( WebappDaoFactory wDaoFact){
|
||||
boolean inferenceAvailable = false;
|
||||
if (wDaoFact instanceof WebappDaoFactoryJena) {
|
||||
TBoxReasonerDriver pl = ((WebappDaoFactoryJena) wDaoFact).getTBoxReasonerDriver();
|
||||
if (pl != null && pl.getStatus().isConsistent() && !pl.getStatus().isInErrorState()
|
||||
&& !pl.isReasoning()) {
|
||||
inferenceAvailable = true;
|
||||
}
|
||||
}
|
||||
return inferenceAvailable;
|
||||
protected boolean isReasoningAvailable(){
|
||||
TBoxReasonerStatus status = ApplicationUtils.instance().getTBoxReasonerModule().getStatus();
|
||||
return status.isConsistent() && !status.isInErrorState();
|
||||
}
|
||||
|
||||
protected Map<String, Individual> addWhenMissingInference( String classUri , WebappDaoFactory wDaoFact ){
|
||||
boolean inferenceAvailable = isReasoningAvailable(wDaoFact);
|
||||
boolean inferenceAvailable = isReasoningAvailable();
|
||||
Map<String,Individual> individualMap = new HashMap<String,Individual>();
|
||||
if ( !inferenceAvailable ) {
|
||||
for (String subclassURI : wDaoFact.getVClassDao().getAllSubClassURIs(classUri)) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import edu.cornell.mannlib.vitro.webapp.application.VitroHomeDirectory;
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerModule;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
|
||||
|
||||
|
@ -29,6 +30,8 @@ public interface Application {
|
|||
|
||||
ConfigurationTripleSource getConfigurationTripleSource();
|
||||
|
||||
TBoxReasonerModule getTBoxReasonerModule();
|
||||
|
||||
void shutdown();
|
||||
|
||||
public interface Component {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.hp.hpl.jena.ontology.Restriction;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
|
||||
/**
|
||||
* A wrapper around the TBox reasoner
|
||||
*/
|
||||
public interface TBoxReasonerModule extends Application.Module {
|
||||
/**
|
||||
* What is the TBox reasoner doing now?
|
||||
*/
|
||||
TBoxReasonerStatus getStatus();
|
||||
|
||||
/**
|
||||
* What restrictions are currently in the reasoner's internal model?
|
||||
*/
|
||||
List<Restriction> listRestrictions();
|
||||
|
||||
/**
|
||||
* Wait until the TBox reasoner becomes quiet.
|
||||
*/
|
||||
void waitForTBoxReasoning();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner;
|
||||
|
||||
/**
|
||||
* What is the current state of the TBox reasoner?
|
||||
*/
|
||||
public interface TBoxReasonerStatus {
|
||||
/**
|
||||
* Is reasoning in progress based on changes to the TBox?
|
||||
*/
|
||||
boolean isReasoning();
|
||||
|
||||
/**
|
||||
* Is the TBox free of inconsistency?
|
||||
*/
|
||||
boolean isConsistent();
|
||||
|
||||
/**
|
||||
* Did the reasoner fail in its most recent attempt?
|
||||
*/
|
||||
boolean isInErrorState();
|
||||
|
||||
/**
|
||||
* A description of the error state, or an empty string (never null).
|
||||
*/
|
||||
String getExplanation();
|
||||
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.BasicTBoxReasonerDriver;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerConfiguration;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.pellet.PelletTBoxReasoner;
|
||||
|
||||
/**
|
||||
* Start the Pellet reasoner on the TBox.
|
||||
*/
|
||||
public class PelletReasonerSetup implements ServletContextListener {
|
||||
private static final Log log = LogFactory.getLog(PelletReasonerSetup.class);
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
ContextModelAccess contextModels = ModelAccess.on(ctx);
|
||||
OntModel tboxAssertionsModel = contextModels
|
||||
.getOntModel(TBOX_ASSERTIONS);
|
||||
Model tboxInferencesModel = contextModels
|
||||
.getOntModel(TBOX_INFERENCES).getBaseModel();
|
||||
OntModel tboxUnionModel = contextModels.getOntModel(TBOX_UNION);
|
||||
WebappDaoFactory wadf = contextModels.getWebappDaoFactory();
|
||||
|
||||
TBoxReasoner reasoner = new PelletTBoxReasoner(
|
||||
ReasonerConfiguration.DEFAULT);
|
||||
TBoxReasonerDriver driver = new BasicTBoxReasonerDriver(
|
||||
tboxAssertionsModel, tboxInferencesModel, tboxUnionModel,
|
||||
reasoner, ReasonerConfiguration.DEFAULT);
|
||||
|
||||
sce.getServletContext().setAttribute("tboxReasoner", driver);
|
||||
sce.getServletContext().setAttribute("tboxReasonerWrapper", reasoner);
|
||||
|
||||
if (wadf instanceof WebappDaoFactoryJena) {
|
||||
((WebappDaoFactoryJena) wadf).setTBoxReasonerDriver(driver);
|
||||
}
|
||||
|
||||
ss.info(this, "Pellet reasoner connected for the TBox");
|
||||
|
||||
waitForTBoxReasoning(sce);
|
||||
}
|
||||
|
||||
public static void waitForTBoxReasoning(ServletContextEvent sce) {
|
||||
TBoxReasonerDriver driver = (TBoxReasonerDriver) sce.getServletContext().getAttribute("tboxReasoner");
|
||||
if (driver == null) {
|
||||
return;
|
||||
}
|
||||
int sleeps = 0;
|
||||
// sleep at least once to make sure the TBox reasoning gets started
|
||||
while ((0 == sleeps)
|
||||
|| ((sleeps < 1000) && driver.isReasoning())) {
|
||||
if (((sleeps - 1) % 10) == 0) { // print message at 10 second
|
||||
// intervals
|
||||
log.info("Waiting for initial TBox reasoning to complete");
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// This should never happen.
|
||||
e.printStackTrace();
|
||||
}
|
||||
sleeps++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
// Nothing to tear down
|
||||
}
|
||||
|
||||
}
|
|
@ -89,7 +89,11 @@ public class UpdateKnowledgeBase implements ServletContextListener {
|
|||
putReportingPathsIntoSettings(ctx, settings);
|
||||
putNonReportingPathsIntoSettings(ctx, settings);
|
||||
|
||||
PelletReasonerSetup.waitForTBoxReasoning(sce);
|
||||
try {
|
||||
ApplicationUtils.instance().getTBoxReasonerModule().waitForTBoxReasoning();
|
||||
} catch (Exception e) {
|
||||
// Should mean that the reasoner is not even started yet.
|
||||
}
|
||||
|
||||
WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory();
|
||||
settings.setDefaultNamespace(wadf.getDefaultNamespace());
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.tboxreasoner;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
|
||||
/**
|
||||
* The basic implementation of the TBoxReasonerDriver.
|
||||
*/
|
||||
public class BasicTBoxReasonerDriver implements TBoxReasonerDriver {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(BasicTBoxReasonerDriver.class);
|
||||
|
||||
private final LockableOntModel lockableAssertionsModel;
|
||||
private final LockableModel lockableInferencesModel;
|
||||
private final LockableOntModel lockableFullModel;
|
||||
|
||||
private final ReasonerConfiguration reasonerConfiguration;
|
||||
|
||||
private final ConfiguredReasonerListener listener;
|
||||
|
||||
private final Set<TBoxChanges> pendingChangeSets;
|
||||
|
||||
private final ExecutorService executorService;
|
||||
|
||||
private final TBoxReasoner reasoner;
|
||||
|
||||
private TBoxReasonerDriver.Status status;
|
||||
|
||||
public BasicTBoxReasonerDriver(OntModel assertionsModel,
|
||||
Model inferencesModel, OntModel fullModel, TBoxReasoner reasoner,
|
||||
ReasonerConfiguration reasonerConfiguration) {
|
||||
this.lockableAssertionsModel = new LockableOntModel(assertionsModel);
|
||||
this.lockableInferencesModel = new LockableModel(inferencesModel);
|
||||
this.lockableFullModel = new LockableOntModel(fullModel);
|
||||
this.reasoner = reasoner;
|
||||
this.reasonerConfiguration = reasonerConfiguration;
|
||||
|
||||
this.listener = new ConfiguredReasonerListener(reasonerConfiguration,
|
||||
this);
|
||||
|
||||
this.pendingChangeSets = Collections.synchronizedSet(new HashSet<TBoxChanges>());
|
||||
|
||||
this.executorService = Executors.newFixedThreadPool(1);
|
||||
|
||||
assertionsModel.getBaseModel().register(listener);
|
||||
fullModel.getBaseModel().register(listener);
|
||||
|
||||
doInitialReasoning();
|
||||
}
|
||||
|
||||
private void doInitialReasoning() {
|
||||
try (LockedOntModel assertionsModel = lockableAssertionsModel.read()) {
|
||||
for (ReasonerStatementPattern pat : reasonerConfiguration
|
||||
.getInferenceDrivingPatternAllowSet()) {
|
||||
listener.addedStatements(assertionsModel.listStatements(
|
||||
(Resource) null, pat.getPredicate(), (RDFNode) null));
|
||||
}
|
||||
}
|
||||
listener.notifyEvent(null, new EditEvent(null, false));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReasoning() {
|
||||
return !pendingChangeSets.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runSynchronizer(TBoxChanges changeSet) {
|
||||
if (!changeSet.isEmpty()) {
|
||||
executorService.execute(new ReasoningTask(changeSet));
|
||||
}
|
||||
}
|
||||
|
||||
private class ReasoningTask implements Runnable {
|
||||
private final TBoxChanges changes;
|
||||
private List<ReasonerStatementPattern> patternList;
|
||||
|
||||
public ReasoningTask(TBoxChanges changes) {
|
||||
this.changes = changes;
|
||||
pendingChangeSets.add(changes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
reasoner.updateReasonerModel(changes);
|
||||
status = reasoner.performReasoning();
|
||||
|
||||
buildPatternList();
|
||||
updateInferencesModel();
|
||||
} finally {
|
||||
pendingChangeSets.remove(changes);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildPatternList() {
|
||||
PatternListBuilder patternListBuilder = new PatternListBuilder(
|
||||
reasonerConfiguration, reasoner, changes);
|
||||
this.patternList = patternListBuilder.build();
|
||||
}
|
||||
|
||||
private void updateInferencesModel() {
|
||||
InferenceModelUpdater inferenceModelUpdater = new InferenceModelUpdater(
|
||||
reasoner, lockableInferencesModel, lockableFullModel, listener);
|
||||
inferenceModelUpdater.update(patternList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -67,7 +67,7 @@ public class InferenceModelUpdater {
|
|||
addNewInferences(filteredReasonerModel);
|
||||
removeOldInferences(filterInferencesModel(patternList),
|
||||
filteredReasonerModel);
|
||||
log.warn("Added: " + addCount + ", Retracted: " + retractCount);
|
||||
log.debug("Added: " + addCount + ", Retracted: " + retractCount);
|
||||
}
|
||||
|
||||
private void addNewInferences(List<Statement> filteredReasonerModel) {
|
||||
|
@ -96,7 +96,7 @@ public class InferenceModelUpdater {
|
|||
filtered.add(pattern.matchStatementsFromModel(inferencesModel));
|
||||
}
|
||||
}
|
||||
log.warn("Filtered inferences model: " + filtered.size());
|
||||
log.debug("Filtered inferences model: " + filtered.size());
|
||||
return filtered;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ import com.hp.hpl.jena.ontology.ObjectProperty;
|
|||
import com.hp.hpl.jena.ontology.Restriction;
|
||||
import com.hp.hpl.jena.rdf.model.Statement;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver.Status;
|
||||
|
||||
/**
|
||||
* The functionality of a TBox reasoner.
|
||||
*
|
||||
|
@ -53,5 +51,37 @@ public interface TBoxReasoner {
|
|||
* updating and reasoning.
|
||||
*/
|
||||
List<Statement> filterResults(List<ReasonerStatementPattern> patternList);
|
||||
|
||||
public static class Status {
|
||||
public static final Status SUCCESS = new Status(true, false, "");
|
||||
public static final Status ERROR = new Status(true, true, "");
|
||||
|
||||
public static final Status inconsistent(String explanation) {
|
||||
return new Status(false, false, explanation);
|
||||
}
|
||||
|
||||
private final boolean consistent;
|
||||
private final boolean inErrorState;
|
||||
private final String explanation;
|
||||
|
||||
private Status(boolean consistent, boolean inErrorState,
|
||||
String explanation) {
|
||||
this.consistent = consistent;
|
||||
this.inErrorState = inErrorState;
|
||||
this.explanation = explanation;
|
||||
}
|
||||
|
||||
public boolean isConsistent() {
|
||||
return consistent;
|
||||
}
|
||||
|
||||
public boolean isInErrorState() {
|
||||
return inErrorState;
|
||||
}
|
||||
|
||||
public String getExplanation() {
|
||||
return explanation;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.tboxreasoner;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerStatus;
|
||||
|
||||
|
||||
/**
|
||||
* What calls can the ConfiguredReasonerListener make to drive the TBox
|
||||
|
@ -11,40 +13,5 @@ public interface TBoxReasonerDriver {
|
|||
|
||||
void runSynchronizer(TBoxChanges changeSet);
|
||||
|
||||
boolean isReasoning();
|
||||
|
||||
Status getStatus();
|
||||
|
||||
public static class Status {
|
||||
public static final Status SUCCESS = new Status(true, false, "");
|
||||
public static final Status ERROR = new Status(true, true, "");
|
||||
|
||||
public static final Status inconsistent(String explanation) {
|
||||
return new Status(false, false, explanation);
|
||||
}
|
||||
|
||||
private final boolean consistent;
|
||||
private final boolean inErrorState;
|
||||
private final String explanation;
|
||||
|
||||
private Status(boolean consistent, boolean inErrorState,
|
||||
String explanation) {
|
||||
this.consistent = consistent;
|
||||
this.inErrorState = inErrorState;
|
||||
this.explanation = explanation;
|
||||
}
|
||||
|
||||
public boolean isConsistent() {
|
||||
return consistent;
|
||||
}
|
||||
|
||||
public boolean isInErrorState() {
|
||||
return inErrorState;
|
||||
}
|
||||
|
||||
public String getExplanation() {
|
||||
return explanation;
|
||||
}
|
||||
|
||||
}
|
||||
TBoxReasonerStatus getStatus();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread.WorkLevel.IDLE;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread.WorkLevel.WORKING;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ConfiguredReasonerListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.InferenceModelUpdater;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.PatternListBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerConfiguration;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerStatementPattern;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxChanges;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
||||
|
||||
/**
|
||||
* The basic implementation of the TBoxReasonerDriver. It gets help from a
|
||||
* listener, an executor, and a reasoner.
|
||||
*
|
||||
* Create a listener that listens for changes to the TBox, but filters them
|
||||
* according to a ReasonerConfiguration object. The listener accumulates the
|
||||
* changes it likes, until it detects an ending EditEvent. Then it passes the
|
||||
* change set back to the driver.
|
||||
*
|
||||
* Each time a change set is received, a task is created and given to the
|
||||
* executor to run. The executor is single-threaded, so the change sets are
|
||||
* processed in sequence.
|
||||
*
|
||||
* Processing involves the following steps:
|
||||
*
|
||||
* 1. Telling the reasoner about the changes, so it can update its own internal
|
||||
* ontology model.
|
||||
*
|
||||
* 2. Telling the reasoner to re-inference its model. A status is returned.
|
||||
*
|
||||
* 3. Asking the reasoner for the inferences from its model. As with the initial
|
||||
* changes, these inferences are filtered according to the
|
||||
* ReasonerConfiguration.
|
||||
*
|
||||
* 4. Synchronizing the applications TBox inferences model with the inferences
|
||||
* obtained from the reasoner.
|
||||
*
|
||||
* ----------------------
|
||||
*
|
||||
* Possible optimization: if change sets come in quickly enough that the third
|
||||
* set is received while the first is still being processed, it would be
|
||||
* reasonable to merge the second and third sets into one.
|
||||
*/
|
||||
public class BasicTBoxReasonerDriver implements TBoxReasonerDriver {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(BasicTBoxReasonerDriver.class);
|
||||
|
||||
private final LockableOntModel lockableAssertionsModel;
|
||||
private final LockableModel lockableInferencesModel;
|
||||
private final LockableOntModel lockableFullModel;
|
||||
|
||||
private final ReasonerConfiguration reasonerConfiguration;
|
||||
|
||||
private final ConfiguredReasonerListener listener;
|
||||
|
||||
private final Set<TBoxChanges> pendingChangeSets;
|
||||
|
||||
private final ExecutorService executorService;
|
||||
|
||||
private final TBoxReasoner reasoner;
|
||||
|
||||
private TBoxReasoner.Status innerStatus;
|
||||
|
||||
public BasicTBoxReasonerDriver(OntModel assertionsModel,
|
||||
Model inferencesModel, OntModel fullModel, TBoxReasoner reasoner,
|
||||
ReasonerConfiguration reasonerConfiguration) {
|
||||
this.lockableAssertionsModel = new LockableOntModel(assertionsModel);
|
||||
this.lockableInferencesModel = new LockableModel(inferencesModel);
|
||||
this.lockableFullModel = new LockableOntModel(fullModel);
|
||||
this.reasoner = reasoner;
|
||||
this.reasonerConfiguration = reasonerConfiguration;
|
||||
|
||||
this.listener = new ConfiguredReasonerListener(reasonerConfiguration,
|
||||
this);
|
||||
|
||||
this.pendingChangeSets = Collections
|
||||
.synchronizedSet(new HashSet<TBoxChanges>());
|
||||
|
||||
this.executorService = Executors.newFixedThreadPool(1,
|
||||
new VitroBackgroundThread.Factory("TBoxReasoner"));
|
||||
|
||||
assertionsModel.getBaseModel().register(listener);
|
||||
fullModel.getBaseModel().register(listener);
|
||||
|
||||
doInitialReasoning();
|
||||
}
|
||||
|
||||
private void doInitialReasoning() {
|
||||
try (LockedOntModel assertionsModel = lockableAssertionsModel.read()) {
|
||||
for (ReasonerStatementPattern pat : reasonerConfiguration
|
||||
.getInferenceDrivingPatternAllowSet()) {
|
||||
listener.addedStatements(assertionsModel.listStatements(
|
||||
(Resource) null, pat.getPredicate(), (RDFNode) null));
|
||||
}
|
||||
}
|
||||
listener.notifyEvent(null, new EditEvent(null, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TBoxReasonerStatus getStatus() {
|
||||
return new FullStatus(innerStatus, !pendingChangeSets.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runSynchronizer(TBoxChanges changeSet) {
|
||||
if (!changeSet.isEmpty()) {
|
||||
executorService.execute(new ReasoningTask(changeSet));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down the thread that runs the reasoning tasks. Don't wait longer
|
||||
* than 1 minute.
|
||||
*/
|
||||
public void shutdown() {
|
||||
executorService.shutdown();
|
||||
int waited = 0;
|
||||
while (waited < 60 && !executorService.isTerminated()) {
|
||||
try {
|
||||
log.info("Waiting for TBox reasoner to terminate.");
|
||||
executorService.awaitTermination(5, TimeUnit.SECONDS);
|
||||
waited += 5;
|
||||
} catch (InterruptedException e) {
|
||||
// Should never happen.
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!executorService.isTerminated()) {
|
||||
log.warn("Forcing TBox reasoner to terminate.");
|
||||
executorService.shutdownNow();
|
||||
}
|
||||
if (!executorService.isTerminated()) {
|
||||
log.error("TBox reasoner did not terminate.");
|
||||
}
|
||||
}
|
||||
|
||||
private class ReasoningTask implements Runnable {
|
||||
private final TBoxChanges changes;
|
||||
private List<ReasonerStatementPattern> patternList;
|
||||
|
||||
public ReasoningTask(TBoxChanges changes) {
|
||||
this.changes = changes;
|
||||
pendingChangeSets.add(changes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setWorking();
|
||||
|
||||
reasoner.updateReasonerModel(changes);
|
||||
innerStatus = reasoner.performReasoning();
|
||||
|
||||
buildPatternList();
|
||||
updateInferencesModel();
|
||||
|
||||
setIdle();
|
||||
} finally {
|
||||
pendingChangeSets.remove(changes);
|
||||
}
|
||||
}
|
||||
|
||||
private void setWorking() {
|
||||
Thread current = Thread.currentThread();
|
||||
if (current instanceof VitroBackgroundThread) {
|
||||
((VitroBackgroundThread) current).setWorkLevel(WORKING);
|
||||
}
|
||||
}
|
||||
|
||||
private void setIdle() {
|
||||
Thread current = Thread.currentThread();
|
||||
if (current instanceof VitroBackgroundThread) {
|
||||
((VitroBackgroundThread) current).setWorkLevel(IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildPatternList() {
|
||||
PatternListBuilder patternListBuilder = new PatternListBuilder(
|
||||
reasonerConfiguration, reasoner, changes);
|
||||
this.patternList = patternListBuilder.build();
|
||||
}
|
||||
|
||||
private void updateInferencesModel() {
|
||||
InferenceModelUpdater inferenceModelUpdater = new InferenceModelUpdater(
|
||||
reasoner, lockableInferencesModel, lockableFullModel,
|
||||
listener);
|
||||
inferenceModelUpdater.update(patternList);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FullStatus implements TBoxReasonerStatus {
|
||||
private final TBoxReasoner.Status reasonerStatus;
|
||||
private final boolean reasoning;
|
||||
|
||||
public FullStatus(Status reasonerStatus, boolean reasoning) {
|
||||
this.reasonerStatus = reasonerStatus;
|
||||
this.reasoning = reasoning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReasoning() {
|
||||
return reasoning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConsistent() {
|
||||
return reasonerStatus.isConsistent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInErrorState() {
|
||||
return reasonerStatus.isInErrorState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExplanation() {
|
||||
String explanation = reasonerStatus.getExplanation();
|
||||
return explanation == null ? "" : explanation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,6 @@ import com.hp.hpl.jena.vocabulary.RDFS;
|
|||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerConfiguration;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerStatementPattern;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxChanges;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasonerDriver.Status;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.TBoxReasoner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.pellet;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_ASSERTIONS;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_INFERENCES;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.TBOX_UNION;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.Restriction;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerModule;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.ReasonerConfiguration;
|
||||
import edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.BasicTBoxReasonerDriver;
|
||||
|
||||
/**
|
||||
* Configure a Pellet reasoner on the TBox.
|
||||
*/
|
||||
public class PelletTBoxReasonerModule implements TBoxReasonerModule {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(PelletTBoxReasonerModule.class);
|
||||
|
||||
private PelletTBoxReasoner reasoner;
|
||||
private BasicTBoxReasonerDriver driver;
|
||||
|
||||
@Override
|
||||
public void startup(Application application, ComponentStartupStatus ss) {
|
||||
ServletContext ctx = application.getServletContext();
|
||||
|
||||
ContextModelAccess contextModels = ModelAccess.on(ctx);
|
||||
OntModel tboxAssertionsModel = contextModels
|
||||
.getOntModel(TBOX_ASSERTIONS);
|
||||
Model tboxInferencesModel = contextModels.getOntModel(TBOX_INFERENCES)
|
||||
.getBaseModel();
|
||||
OntModel tboxUnionModel = contextModels.getOntModel(TBOX_UNION);
|
||||
|
||||
reasoner = new PelletTBoxReasoner(ReasonerConfiguration.DEFAULT);
|
||||
driver = new BasicTBoxReasonerDriver(tboxAssertionsModel,
|
||||
tboxInferencesModel, tboxUnionModel, reasoner,
|
||||
ReasonerConfiguration.DEFAULT);
|
||||
|
||||
ss.info("Pellet reasoner connected for the TBox");
|
||||
|
||||
waitForTBoxReasoning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TBoxReasonerStatus getStatus() {
|
||||
if (driver == null) {
|
||||
throw new IllegalStateException(
|
||||
"PelletTBoxReasonerModule has not been started.");
|
||||
}
|
||||
return driver.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Restriction> listRestrictions() {
|
||||
if (reasoner == null) {
|
||||
throw new IllegalStateException(
|
||||
"PelletTBoxReasonerModule has not been started.");
|
||||
}
|
||||
return reasoner.listRestrictions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(Application application) {
|
||||
driver.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForTBoxReasoning() {
|
||||
int sleeps = 0;
|
||||
// sleep at least once to make sure the TBox reasoning gets started
|
||||
while ((0 == sleeps)
|
||||
|| ((sleeps < 1000) && getStatus().isReasoning())) {
|
||||
if (((sleeps - 1) % 10) == 0) { // print message at 10 second
|
||||
// intervals
|
||||
log.info("Waiting for initial TBox reasoning to complete");
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// This should never happen.
|
||||
e.printStackTrace();
|
||||
}
|
||||
sleeps++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,8 @@ import java.util.Collections;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -106,4 +108,25 @@ public class VitroBackgroundThread extends Thread {
|
|||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory class, for use in Executors, that creates threads with
|
||||
* successive names.
|
||||
*/
|
||||
public static class Factory implements ThreadFactory{
|
||||
private final String threadName;
|
||||
private final AtomicInteger index;
|
||||
|
||||
public Factory(String threadName) {
|
||||
this.threadName = threadName;
|
||||
this.index = new AtomicInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
return new VitroBackgroundThread(r, threadName + "_" + index.getAndIncrement());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerModule;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
|
||||
|
||||
|
@ -101,4 +102,11 @@ public class ApplicationStub implements Application {
|
|||
"ApplicationStub.getConfigurationTripleSource() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TBoxReasonerModule getTBoxReasonerModule() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("ApplicationStub.getTBoxReasonerModule() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.RemoveObsoletePermissions
|
|||
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.PelletListenerSetup
|
||||
edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$ReasonersSetup
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup
|
||||
|
||||
#edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
|
||||
|
|
Loading…
Add table
Reference in a new issue