diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/DateTimeMigration.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/DateTimeMigration.java deleted file mode 100644 index 0ce3ca4b8..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/DateTimeMigration.java +++ /dev/null @@ -1,282 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.ontology.update; - -import java.io.IOException; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; -import com.hp.hpl.jena.datatypes.xsd.XSDDateTime; -import com.hp.hpl.jena.ontology.DatatypeProperty; -import com.hp.hpl.jena.ontology.ObjectProperty; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.shared.Lock; - -/** -* Performs knowledge base updates to the abox to align with the new -* 1.2 Date/Time representation. -* -*/ -public class DateTimeMigration { - - private OntModel aboxModel; - private ChangeLogger logger; - private ChangeRecord record; - - private static final String dateTimeURI = "http://vivoweb.org/ontology/core#dateTime"; - private static final String dateTimePrecisionURI = "http://vivoweb.org/ontology/core#dateTimePrecision"; - private static final String hasTimeIntervalURI = "http://vivoweb.org/ontology/core#hasTimeInterval"; - private static final String dateTimeIntervalURI = "http://vivoweb.org/ontology/core#dateTimeInterval"; - private static final String startURI = "http://vivoweb.org/ontology/core#start"; - private static final String endURI = "http://vivoweb.org/ontology/core#end"; - - private static final String yPrecisionURI = "http://vivoweb.org/ontology/core#yearPrecision"; - private static final String ymPrecisionURI = "http://vivoweb.org/ontology/core#yearMonthPrecision"; - private static final String ymdPrecisionURI = "http://vivoweb.org/ontology/core#yearMonthDayPrecision"; - private static final String ymdtPrecisionURI = "http://vivoweb.org/ontology/core#yearMonthDayTimePrecision"; - - private DatatypeProperty dateTimeProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createDatatypeProperty(dateTimeURI); - private ObjectProperty hasTimeIntervalProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createObjectProperty(hasTimeIntervalURI); - private ObjectProperty dateTimeIntervalProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createObjectProperty(dateTimeIntervalURI); - private ObjectProperty dateTimePrecisionProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createObjectProperty(dateTimePrecisionURI); - private ObjectProperty startProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createObjectProperty(startURI); - private ObjectProperty endProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createObjectProperty(endURI); - - /** - * Constructor - * - * @param aboxModel - the knowledge base to be updated - * @param logger - for writing to the change log - * and the error log. - * @param record - for writing to the additions model - * and the retractions model. - */ - public DateTimeMigration(OntModel aboxModel,ChangeLogger logger, ChangeRecord record) { - - this.aboxModel = aboxModel; - this.logger = logger; - this.record = record; - } - - /** - * - * Update the abox to align with changes in the Date/Time class - * and property definitions in the transition from version 1.1 to 1.2. - * - */ - public void updateABox() throws IOException { - - updateAcademicIntervals(); - updateLiterals(); - } - - /** - * - * - */ - public void updateAcademicIntervals() throws IOException { - - aboxModel.enterCriticalSection(Lock.WRITE); - - try { - Model additions = ModelFactory.createDefaultModel(); - Model retractions = ModelFactory.createDefaultModel(); - - StmtIterator iter = aboxModel.listStatements((Resource) null, hasTimeIntervalProp, (RDFNode) null); - - int datelessCount = 0; - while (iter.hasNext()) { - - Statement stmt1 = iter.next(); - - if (!stmt1.getObject().isResource()) { - logger.log("WARN: the object of this statement is expected to be a resource: " + ABoxUpdater.stmtString(stmt1)); - continue; - } - - Statement stmt2 = aboxModel.getProperty(stmt1.getObject().asResource(), dateTimeIntervalProp); - - if (stmt2 == null) { - datelessCount++; - additions.add(stmt1.getSubject(), dateTimeIntervalProp, stmt1.getObject()); - //additions.add(stmt1.getObject().asResource(), dateTimeIntervalForProp, stmt1.getSubject()); - continue; - } - - if (!stmt2.getObject().isResource()) { - logger.log("WARN: the object of this statement is expected to be a resource: " + ABoxUpdater.stmtString(stmt2)); - continue; - } - - retractions.add(stmt2); - //retractions.add(stmt2.getObject().asResource(), dateTimeIntervalForProp, stmt2.getSubject()); - additions.add(stmt1.getSubject(), dateTimeIntervalProp, stmt1.getObject()); - //additions.add(stmt1.getObject().asResource(), dateTimeIntervalForProp, stmt1.getSubject()); - - StmtIterator iter2 = aboxModel.listStatements(stmt2.getObject().asResource(), (Property) null, (RDFNode) null); - - while (iter2.hasNext()) { - Statement stmt3 = iter2.next(); - retractions.add(stmt3); - - if ( (stmt3.getPredicate().equals(startProp)) || (stmt3.getPredicate().equals(endProp)) ) { - additions.add(stmt1.getObject().asResource(), stmt3.getPredicate(), stmt3.getObject()); - } - } - } - - aboxModel.remove(retractions); - record.recordRetractions(retractions); - aboxModel.add(additions); - record.recordAdditions(additions); - - if (datelessCount > 0) { - logger.log("INFO: Found " + datelessCount + " Academic Term and/or Year individual" + ((datelessCount > 1) ? "s" : "") + - " that " + ((datelessCount > 1) ? "don't have " : "doesn't have ") + "an associated date." + - " Such an individual will be displayed as an incomplete Date/Time" + - " interval on any Course page that refers to it."); - } - - if (additions.size() > 0) { - long count = additions.size() / 2; - logger.log("Updated " + count + " Academic interval" + ((count > 1) ? "s" : "") + " to the new date/time format"); - } - } finally { - aboxModel.leaveCriticalSection(); - } - } - - /** - * - * - */ - public void updateLiterals() throws IOException { - - DateFormat yearFormat = new SimpleDateFormat("yyyy"); - DateFormat yearMonthFormat = new SimpleDateFormat("yyyy-MM"); - DateFormat yearMonthDayFormat = new SimpleDateFormat("yyyy-MM-dd"); - DateFormat yearMonthDayFormat2 = new SimpleDateFormat("dd-MMM-yy"); - - aboxModel.enterCriticalSection(Lock.WRITE); - - try { - Model additions = ModelFactory.createDefaultModel(); - Model retractions = ModelFactory.createDefaultModel(); - - StmtIterator iter = aboxModel.listStatements((Resource) null, dateTimeProp, (RDFNode) null); - - while (iter.hasNext()) { - Statement newStmt = null; - Date date = null; - Statement stmt = iter.next(); - String precision = getPrecision(stmt); - - if (precision == null) { - logger.log("WARNING: no precision found for individual " + stmt.getSubject().getURI() ); - } else if (yPrecisionURI.equals(precision)) { - try { - date = yearFormat.parse(stmt.getObject().asLiteral().getLexicalForm()); - newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) ); - } catch (ParseException pe) { - logger.log("Parse Exception for year literal: " + stmt.getObject().asLiteral().getLexicalForm() + - ". The following statement has been removed from the knowledge base " + ABoxUpdater.stmtString(stmt)); - } - } else if (ymPrecisionURI.equals(precision)) { - try { - date = yearMonthFormat.parse(stmt.getObject().asLiteral().getLexicalForm()); - newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) ); - } catch (ParseException pe) { - logger.log("Parse Exception for yearMonth literal: " + stmt.getObject().asLiteral().getLexicalForm() + - ". The following statement has been removed from the knowledge base " + ABoxUpdater.stmtString(stmt)); - } - } else if (ymdPrecisionURI.equals(precision)) { - try { - date = yearMonthDayFormat.parse(stmt.getObject().asLiteral().getLexicalForm()); - newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) ); - } catch (ParseException pe) { - try { - date = yearMonthDayFormat2.parse(stmt.getObject().asLiteral().getLexicalForm()); - newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) ); - } catch (ParseException pe2) { - logger.log("Parse Exception for yearMonthDay literal: " + stmt.getObject().asLiteral().getLexicalForm() + - ". The following statement has been removed from the knowledge base " + ABoxUpdater.stmtString(stmt)); - } - } - } else if (ymdtPrecisionURI.equals(precision)) { - logger.log("WARNING: unhandled precision found for individual " + stmt.getSubject().getURI() + ": " + precision + - ". The following statement has been removed from the knowledge base " + ABoxUpdater.stmtString(stmt)); - } else { - logger.log("WARNING: unrecognized precision found for individual " + stmt.getSubject().getURI() + ": " + precision + - ". The following statement has been removed from the knowledge base " + ABoxUpdater.stmtString(stmt)); - } - - retractions.add(stmt); - - if (newStmt != null ) { - additions.add(newStmt); - } - } - - aboxModel.remove(retractions); - record.recordRetractions(retractions); - aboxModel.add(additions); - record.recordAdditions(additions); - - if (additions.size() > 0) { - logger.log("Updated " + additions.size() + " date/time literal" + - ((additions.size() > 1) ? "s" : "") + " to the xsd:dateTime representation"); - } - } finally { - aboxModel.leaveCriticalSection(); - } - } - - public String getPrecision(Statement stmt) { - - String precision = null; - - aboxModel.enterCriticalSection(Lock.WRITE); - - try { - StmtIterator iter = aboxModel.listStatements(stmt.getSubject(), dateTimePrecisionProp, (RDFNode) null); - - while (iter.hasNext()) { - Statement statement = iter.next(); - precision = ((Resource)statement.getObject()).getURI(); - } - - return precision; - - } finally { - aboxModel.leaveCriticalSection(); - } - } - - public static Literal getDateTimeLiteral(Date date) { - - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - cal.setTime(date); - cal.set(Calendar.HOUR, 0); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND,0); - XSDDateTime dt = new XSDDateTime(cal); - String dateString = dt.toString().substring(0, dt.toString().length()-1); - return ResourceFactory.createTypedLiteral(dateString, XSDDatatype.XSDdateTime); - } -} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 3ffe69854..5c481263a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -93,9 +93,6 @@ public class KnowledgeBaseUpdater { performSparqlConstructAdditions(settings.getSparqlConstructAdditionsDir(), settings.getOntModelSelector().getABoxModel()); performSparqlConstructRetractions(settings.getSparqlConstructDeletionsDir(), settings.getOntModelSelector().getABoxModel()); - DateTimeMigration dtMigration = new DateTimeMigration(settings.getOntModelSelector().getABoxModel(), logger, record); - dtMigration.updateABox(); - List rawChanges = getAtomicOntologyChanges(); AtomicOntologyChangeLists changes = new AtomicOntologyChangeLists(rawChanges,settings.getNewTBoxModel(),settings.getOldTBoxModel()); 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 2b526424a..0092d5c9b 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 @@ -47,9 +47,10 @@ public class FileGraphSetup implements ServletContextListener { boolean aboxChanged = false; // indicates whether any ABox file graph model has changed boolean tboxChanged = false; // indicates whether any TBox file graph model has changed + OntModelSelectorImpl baseOms = null; try { - OntModelSelectorImpl baseOms = (OntModelSelectorImpl) sce.getServletContext().getAttribute("baseOntModelSelector"); + baseOms = (OntModelSelectorImpl) sce.getServletContext().getAttribute("baseOntModelSelector"); Store kbStore = (Store) sce.getServletContext().getAttribute("kbStore"); // ABox files @@ -81,8 +82,16 @@ public class FileGraphSetup implements ServletContextListener { t.printStackTrace(); } - if (aboxChanged | tboxChanged) { - SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext()); + if (aboxChanged || tboxChanged) { + + if ( !JenaDataSourceSetup.updateRequired(sce.getServletContext(), baseOms.getTBoxModel())) { + 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()); + } else { + log.info("A knowledgebase update is required. A full recompute of the Abox will not be" + + " performed; instead inferences will be updated incrementally as the knowledge base is updated."); + } } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java index a0ff897a6..3f8101a0f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java @@ -95,7 +95,7 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java private void setUpJenaDataSource(ServletContext ctx) throws SQLException { - /* commenting out during development of 1.3 - this will be redone. + /* if ( updateRequired(ctx, memModel)) { log.error(getMigrationErrString()); System.out.println(getMigrationErrString()); @@ -104,7 +104,7 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java AbortStartup.abortStartup(ctx); throw new MigrationRequiredError(getMigrationErrString()); } - */ + */ OntModelSelectorImpl baseOms = new OntModelSelectorImpl(); OntModelSelectorImpl inferenceOms = new OntModelSelectorImpl(); @@ -611,32 +611,37 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java * Executes a SPARQL ASK query to determine whether the knowledge base * needs to be updated to conform to a new ontology version */ - public boolean updateRequired(ServletContext ctx, OntModel m) throws IOException { + public static boolean updateRequired(ServletContext ctx, OntModel m) { boolean required = false; - String sparqlQueryStr = KnowledgeBaseUpdater.loadSparqlQuery(UpdateKnowledgeBase.getAskQueryPath(ctx)); - if (sparqlQueryStr == null) { - return required; - } - - Query query = QueryFactory.create(sparqlQueryStr); - QueryExecution isUpdated = QueryExecutionFactory.create(query, m); - - // if the ASK query DOES have a solution (i.e. the assertions exist - // showing that the update has already been performed), then the update - // is NOT required. - - if (isUpdated.execAsk()) { - required = false; - } else { - required = true; - String sparqlQueryStr2 = KnowledgeBaseUpdater.loadSparqlQuery(UpdateKnowledgeBase.getAskEmptyQueryPath(ctx)); - if (sparqlQueryStr2 != null) { - Query query2 = QueryFactory.create(sparqlQueryStr2); - QueryExecution isNotEmpty = QueryExecutionFactory.create(query2, m); - required = isNotEmpty.execAsk(); - } + try { + String sparqlQueryStr = KnowledgeBaseUpdater.loadSparqlQuery(UpdateKnowledgeBase.getAskQueryPath(ctx)); + if (sparqlQueryStr == null) { + return required; + } + + Query query = QueryFactory.create(sparqlQueryStr); + QueryExecution isUpdated = QueryExecutionFactory.create(query, m); + + // if the ASK query DOES have a solution (i.e. the assertions exist + // showing that the update has already been performed), then the update + // is NOT required. + + if (isUpdated.execAsk()) { + required = false; + } else { + required = true; + String sparqlQueryStr2 = KnowledgeBaseUpdater.loadSparqlQuery(UpdateKnowledgeBase.getAskEmptyQueryPath(ctx)); + if (sparqlQueryStr2 != null) { + Query query2 = QueryFactory.create(sparqlQueryStr2); + QueryExecution isNotEmpty = QueryExecutionFactory.create(query2, m); + required = isNotEmpty.execAsk(); + } + } + } catch (IOException e) { + log.error("error while trying to determine if a knowledgbase update is required", e); + return false; } return required; 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 ef0d78210..5bf22b38b 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 @@ -61,9 +61,9 @@ public class UpdateKnowledgeBase implements ServletContextListener { private static final String SPARQL_CONSTRUCT_DELETIONS_DIR = DATA_DIR + "sparqlConstructs/deletions/"; private static final String MISC_REPLACEMENTS_FILE = DATA_DIR + "miscReplacements.rdf"; private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; - private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/submodels/"; + private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/filegraph/tbox/"; private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/"; - private static final String NEW_TBOX_ANNOTATIONS_DIR = "/WEB-INF/ontologies/user"; + private static final String NEW_TBOX_ANNOTATIONS_DIR = "/WEB-INF/ontologies/user/tbox/"; public void contextInitialized(ServletContextEvent sce) { @@ -122,7 +122,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { reloadDisplayModel(ctx); } } catch (Throwable t){ - log.warn("Unable to perform miscellaneous application metadata replacements", t); + log.warn("warning", t); } ontologyUpdater.update(); @@ -236,7 +236,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { } } catch (FileNotFoundException fnfe) { log.error(rdfFiles[i].getName() + " not found. Unable to load" + - " RDF from this location."); + " RDF from this location: " + directoryPath); } } return om;