From ea5094d0ef245e525244bc947b152a0d86804609 Mon Sep 17 00:00:00 2001 From: stellamit Date: Thu, 7 Jul 2011 21:31:28 +0000 Subject: [PATCH] NIHVIVO-2837 - compute mostSpecificType annotations on the upgrade to 1.3 --- .../vitro/webapp/reasoner/SimpleReasoner.java | 93 +++++++++++++++++-- .../webapp/servlet/setup/FileGraphSetup.java | 13 ++- .../servlet/setup/SimpleReasonerSetup.java | 25 ++++- .../servlet/setup/UpdateKnowledgeBase.java | 2 +- 4 files changed, 115 insertions(+), 18 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index fa453b6d2..b292703c0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -71,14 +71,7 @@ public class SimpleReasoner extends StatementListener { this.inferenceModel = inferenceModel; this.inferenceRebuildModel = inferenceRebuildModel; this.scratchpadModel = scratchpadModel; - - inferenceRebuildModel.enterCriticalSection(Lock.WRITE); - try { - inferenceRebuildModel.removeAll(); - } finally { - inferenceRebuildModel.leaveCriticalSection(); - } - + aboxModel.register(this); } @@ -334,7 +327,8 @@ public class SimpleReasoner extends StatementListener { } } } else { - log.warn("Didn't find target class (the object of the added rdf:type statement) in the TBox: " + ((Resource)stmt.getObject()).getURI()); + if ( !(stmt.getObject().asResource().getNameSpace()).equals(OWL.NS)) + log.warn("Didn't find target class (the object of the added rdf:type statement) in the TBox"); } } else { log.warn("The object of this rdf:type assertion has a null URI: " + stmtString(stmt)); @@ -785,7 +779,10 @@ public class SimpleReasoner extends StatementListener { } if (ontClass == null) { - log.warn("(setMostSpecificType) Didn't find target class (the object of the added rdf:type statement) in the TBox: " + (stmt.getObject().asResource()).getURI()); + if ( !(stmt.getObject().asResource().getNameSpace()).equals(OWL.NS)) { + log.warn("(setMostSpecificType) Didn't find target class (the object of the added rdf:type statement) in the TBox: " + + (stmt.getObject().asResource()).getURI() + "\nstatement is: " + stmtString(stmt)); + } continue; } @@ -1060,7 +1057,83 @@ public class SimpleReasoner extends StatementListener { log.info("ABox inference model updated"); } + + /* + * Special for version 1.3 + */ + public synchronized void recomputeMostSpecificType() { + + // recompute the inferences + inferenceRebuildModel.enterCriticalSection(Lock.WRITE); + aboxModel.enterCriticalSection(Lock.WRITE); + tboxModel.enterCriticalSection(Lock.READ); + + try { + inferenceRebuildModel.removeAll(); + StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, (RDFNode) null); + + log.info("Computing mostSpecificType annotations"); + while (iter.hasNext()) { + Statement stmt = iter.next(); + setMostSpecificTypes(stmt.getSubject(), inferenceRebuildModel); + } + } catch (Exception e) { + log.error("Exception while recomputing ABox inference model", e); + inferenceRebuildModel.removeAll(); // don't do this in the finally, it's needed in the case + // where there isn't an exception + return; + } finally { + aboxModel.leaveCriticalSection(); + tboxModel.leaveCriticalSection(); + inferenceRebuildModel.leaveCriticalSection(); + } + + + // reflect the recomputed inferences into the application inference + // model. + inferenceRebuildModel.enterCriticalSection(Lock.WRITE); + scratchpadModel.enterCriticalSection(Lock.WRITE); + log.info("Updating ABox inference model"); + + try { + // Add everything from the recomputed inference model that is not already + // in the current inference model to the current inference model. + inferenceModel.enterCriticalSection(Lock.READ); + + try { + scratchpadModel.removeAll(); + StmtIterator iter = inferenceRebuildModel.listStatements(); + while (iter.hasNext()) { + Statement stmt = iter.next(); + if (!inferenceModel.contains(stmt)) { + scratchpadModel.add(stmt); + } + } + } catch (Exception e) { + log.error("Exception while reconciling the current and recomputed ABox inference models", e); + } finally { + inferenceModel.leaveCriticalSection(); + } + + inferenceModel.enterCriticalSection(Lock.WRITE); + try { + inferenceModel.add(scratchpadModel); + } catch (Exception e){ + log.error("Exception while reconciling the current and recomputed ABox inference models", e); + } finally { + inferenceModel.leaveCriticalSection(); + } + } finally { + inferenceRebuildModel.removeAll(); + scratchpadModel.removeAll(); + inferenceRebuildModel.leaveCriticalSection(); + scratchpadModel.leaveCriticalSection(); + } + + log.info("ABox inference model updated"); + } + public static SimpleReasoner getSimpleReasonerFromServletContext(ServletContext ctx) { Object simpleReasoner = ctx.getAttribute("simpleReasoner"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index 595b30920..b77aa010a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -84,11 +84,14 @@ public class FileGraphSetup implements ServletContextListener { t.printStackTrace(); } - if ( (aboxChanged || tboxChanged) && !isUpdateRequired(sce.getServletContext()) ) { - log.info("a full recompute of the Abox will be performed because" + - " the filegraph abox(s) and/or tbox(s) have changed or are being read for the first time." ); - SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext()); - } + if (isUpdateRequired(sce.getServletContext())) { + log.info("mostSpecificType will be computed because a knowledge base migration was performed." ); + SimpleReasonerSetup.setMSTComputeRequired(sce.getServletContext()); + } else if (aboxChanged || tboxChanged) { + log.info("a full recompute of the Abox will be performed because" + + " the filegraph abox(s) and/or tbox(s) have changed or are being read for the first time." ); + SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext()); + } } /* diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index afc4d2e65..e5b29c07d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -98,8 +98,7 @@ public class SimpleReasonerSetup implements ServletContextListener { // the simple reasoner will register itself as a listener to the ABox assertions SimpleReasoner simpleReasoner = new SimpleReasoner(unionOms.getTBoxModel(), assertionsOms.getABoxModel(), inferencesOms.getABoxModel(), rebuildModel, scratchModel); - if (isRecomputeRequired(sce.getServletContext())) { - + if (isRecomputeRequired(sce.getServletContext())) { log.info("ABox inference recompute required"); int sleeps = 0; @@ -112,7 +111,19 @@ public class SimpleReasonerSetup implements ServletContextListener { } simpleReasoner.recompute(); + } else if ( isMSTComputeRequired(sce.getServletContext()) ) { + log.info("most specific type computation required"); + int sleeps = 0; + while (sleeps < 1000 && pelletListener.isReasoning()) { + if ((sleeps % 30) == 0) { + log.info("Waiting for initial TBox reasoning to complete"); + } + Thread.sleep(100); + sleeps++; + } + + simpleReasoner.recomputeMostSpecificType(); } assertionsOms.getTBoxModel().register(new SimpleReasonerTBoxListener(simpleReasoner)); @@ -142,4 +153,14 @@ public class SimpleReasonerSetup implements ServletContextListener { return (ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR) != null); } + private static final String MSTCOMPUTE_REQUIRED_ATTR = + SimpleReasonerSetup.class.getName() + ".MSTComputeRequired"; + + public static void setMSTComputeRequired(ServletContext ctx) { + ctx.setAttribute(MSTCOMPUTE_REQUIRED_ATTR, true); + } + + private static boolean isMSTComputeRequired(ServletContext ctx) { + return (ctx.getAttribute(MSTCOMPUTE_REQUIRED_ATTR) != null); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index dd5b5727a..2e1fe2638 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -112,7 +112,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { try { if (ontologyUpdater.updateRequired()) { - ctx.setAttribute(IndexConstants.INDEX_REBUILD_REQUESTED_AT_STARTUP, Boolean.TRUE); + //ctx.setAttribute(IndexConstants.INDEX_REBUILD_REQUESTED_AT_STARTUP, Boolean.TRUE); ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE); //doMiscAppMetadataReplacements(ctx.getRealPath(MISC_REPLACEMENTS_FILE), oms); reloadDisplayModel(ctx);