This commit is contained in:
sjm222 2010-12-27 00:48:09 +00:00
parent 5e3f106f72
commit 85db1c3ba0
5 changed files with 231 additions and 63 deletions

View file

@ -39,9 +39,7 @@ public class ABoxUpdater {
private OntModel newTBoxAnnotationsModel;
private OntologyChangeLogger logger;
private OntologyChangeRecord record;
private OntClass OWL_THING = (ModelFactory
.createOntologyModel(OntModelSpec.OWL_MEM))
.createClass(OWL.Thing.getURI());
private OntClass OWL_THING = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createClass(OWL.Thing.getURI());
/**
*
@ -311,7 +309,7 @@ public class ABoxUpdater {
namedClassList.add(ontClass);
}
}
OntClass parent = (namedClassList.isEmpty())
OntClass parent = (!namedClassList.isEmpty())
? namedClassList.get(0)
: OWL_THING;
@ -323,10 +321,9 @@ public class ABoxUpdater {
}
//log summary of changes
//logger.log("Class " + deletedClass.getURI() + " has been deleted. Any references to it in the knowledge base will be changed to " +
// replacementClass.getURI());
logger.log("Class " + deletedClass.getURI() + " has been deleted. Any references to it in the knowledge base will be changed to " + replacementClass.getURI());
AtomicOntologyChange chg = new AtomicOntologyChange(deletedClass.getURI(), replacementClass.getURI(), AtomicChangeType.RENAME);
AtomicOntologyChange chg = new AtomicOntologyChange(deletedClass.getURI(), replacementClass.getURI(), AtomicChangeType.RENAME, change.getNotes());
renameClass(chg);
}
@ -349,18 +346,59 @@ public class ABoxUpdater {
}
private void addProperty(AtomicOntologyChange propObj) throws IOException{
OntProperty tempProperty = newTboxModel.getOntProperty
(propObj.getDestinationURI());
if (tempProperty == null) {
logger.logError("Unable to find property " +
propObj.getDestinationURI() +
" in newTBoxModel");
OntProperty addedProperty = newTboxModel.getOntProperty (propObj.getDestinationURI());
if (addedProperty == null) {
logger.logError("Unable to find property " + propObj.getDestinationURI() + " in new TBox");
return;
}
OntProperty superProperty = tempProperty.getSuperProperty();
// if the newly added property has an inverse in the new TBox, then for all existing
// ABox statements involving that inverse (if the inverse is new also there won't be
// any) add the corresponding statement with the new property.
//
// Shouldn't a reasoner be doing this?
OntProperty inverseOfAddedProperty = addedProperty.getInverseOf();
if (inverseOfAddedProperty != null) {
Model additions = ModelFactory.createDefaultModel();
aboxModel.enterCriticalSection(Lock.WRITE);
try {
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
additions.add(newStmt);
}
aboxModel.add(additions);
record.recordAdditions(additions);
if (additions.size() > 0) {
logger.log(additions.size() + " statement" +
((additions.size() > 1) ? "s" : "") +
" with predicate " + addedProperty.getURI() + " " +
((additions.size() > 1) ? "were" : "was")
+ " added (as an inverse to existing " + inverseOfAddedProperty.getURI() +
" assertions");
}
} finally {
aboxModel.leaveCriticalSection();
}
}
/* OntProperty superProperty = addedProperty.getSuperProperty();
if (superProperty == null) {
return;
}
int count = aboxModel.listStatements(
(Resource) null, superProperty, (RDFNode) null).toSet().size();
if (count > 0) {
@ -369,7 +407,7 @@ public class ABoxUpdater {
"a new subproperty " + propObj.getDestinationURI() +
" in the new ontology version. ");
logger.log("Please review uses of this property to see if " + propObj.getDestinationURI() + " is a more appropriate choice.");
}
}*/
}
private void deleteProperty(AtomicOntologyChange propObj) throws IOException{
@ -413,7 +451,7 @@ public class ABoxUpdater {
propObj.getSourceURI() + " " + (plural ? "were" : "was") + " removed. ");
}
} else {
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME);
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes());
renameProperty(chg);
}
@ -435,8 +473,7 @@ public class ABoxUpdater {
}
Model renamePropAddModel = ModelFactory.createDefaultModel();
Model renamePropRetractModel =
ModelFactory.createDefaultModel();
Model renamePropRetractModel = ModelFactory.createDefaultModel();
aboxModel.enterCriticalSection(Lock.WRITE);
try {

View file

@ -13,6 +13,7 @@ public class AtomicOntologyChange {
private String sourceURI;
private String destinationURI;
private AtomicChangeType atomicChangeType;
private String notes;
public AtomicOntologyChange() {
@ -20,11 +21,13 @@ public class AtomicOntologyChange {
public AtomicOntologyChange(String sourceURI,
String destinationURI,
AtomicChangeType atomicChangeType) {
AtomicChangeType atomicChangeType,
String notes) {
this.sourceURI = sourceURI;
this.destinationURI = destinationURI;
this.atomicChangeType = atomicChangeType;
this.notes = notes;
}
@ -63,9 +66,17 @@ public class AtomicOntologyChange {
public void setAtomicChangeType(AtomicChangeType atomicChangeType) {
this.atomicChangeType = atomicChangeType;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public enum AtomicChangeType {
ADD, DELETE, RENAME
}
}

View file

@ -2,9 +2,26 @@
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 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.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;
/**
@ -17,7 +34,19 @@ public class DateTimeMigration {
private OntModel aboxModel;
private OntologyChangeLogger logger;
private OntologyChangeRecord 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 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 dateTimePrecisionProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createObjectProperty(dateTimePrecisionURI);
/**
* Constructor
*
@ -40,24 +69,110 @@ public class DateTimeMigration {
* and property definitions in the transition from version 1.1 to 1.2.
*
*/
public void updateABox() {
public void updateABox() throws IOException {
// note: not handling timezones - they are not expected to be in the 1.1.1 data
DateFormat yearFormat = new SimpleDateFormat("yyyy");
DateFormat yearMonthFormat = new SimpleDateFormat("yyyy-mm");
DateFormat yearMonthDayFormat = new SimpleDateFormat("yyyy-mm-dd");
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());
} catch (ParseException pe) {
logger.log("Parse Exception for year literal: " + stmt.getObject().asLiteral().getLexicalForm() + ". skipping statement.");
}
newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) );
} else if (ymPrecisionURI.equals(precision)) {
try {
date = yearMonthFormat.parse(stmt.getObject().asLiteral().getLexicalForm());
} catch (ParseException pe) {
logger.log("Parse Exception for year literal: " + stmt.getObject().asLiteral().getLexicalForm() + ". skipping statement.");
}
newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) );
} else if (ymdPrecisionURI.equals(precision)) {
try {
date = yearMonthDayFormat.parse(stmt.getObject().asLiteral().getLexicalForm());
} catch (ParseException pe) {
logger.log("Parse Exception for year literal: " + stmt.getObject().asLiteral().getLexicalForm() + ". skipping statement.");
}
newStmt = ResourceFactory.createStatement(stmt.getSubject(), stmt.getPredicate(), getDateTimeLiteral(date) );
} else if (ymdtPrecisionURI.equals(precision)) {
logger.log("WARNING: unhandled precision found for individual " + stmt.getSubject().getURI() + ": " + precision );
} else {
logger.log("WARNING: unrecognized precision found for individual " + stmt.getSubject().getURI() + ": " + precision );
}
if (newStmt != null ) {
additions.add(newStmt);
retractions.add(stmt);
}
}
aboxModel.remove(retractions);
record.recordRetractions(retractions);
aboxModel.add(additions);
record.recordAdditions(additions);
} finally {
aboxModel.leaveCriticalSection();
}
}
public String getPrecision(Statement stmt) {
String precision = null;
aboxModel.enterCriticalSection(Lock.WRITE);
try {
Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
aboxModel.remove(retractions);
record.recordRetractions(retractions);
aboxModel.add(additions);
record.recordAdditions(additions);
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) {
// Note this loses time zone info, don't know how get parser to extract that
//Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") );
Calendar cal = Calendar.getInstance();
cal.setTime(date);
XSDDateTime dt = new XSDDateTime(cal);
return ResourceFactory.createTypedLiteral(dt);
}
}

View file

@ -2,18 +2,17 @@
package edu.cornell.mannlib.vitro.webapp.ontology.update;
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange;
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.skife.csv.CSVReader;
import org.skife.csv.SimpleReader;
import java.io.FileInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.StringTokenizer;
import java.util.ArrayList;
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
/**
* Performs parsing on Prompt output and provides change object list.
@ -61,12 +60,19 @@ public class OntologyChangeParser {
} else {
changeObj = new AtomicOntologyChange();
if (cols[0] != null && cols[0].length() > 0) {
changeObj.setSourceURI(cols[0]);
}
if (cols[1] != null && cols[1].length() > 0) {
changeObj.setDestinationURI(cols[1]);
}
if (cols[4] != null && cols[4].length() > 0) {
changeObj.setNotes(cols[4]);
}
if ("Yes".equals(cols[2])) {
changeObj.setAtomicChangeType(AtomicChangeType.RENAME);
} else if ("Delete".equals(cols[3])) {
@ -77,6 +83,8 @@ public class OntologyChangeParser {
logger.logError("Invalid rename or change type data: '" +
cols[2] + " " + cols[3] + "'");
}
changeObjects.add(changeObj);
}

View file

@ -65,7 +65,6 @@ public class OntologyUpdater {
if (!logger.errorsWritten()) {
// add assertions to the knowledge base showing that the
// update was successful, so we don't need to run it again.
// TODO improve error handling in future version.
assertSuccess();
}
@ -80,19 +79,19 @@ public class OntologyUpdater {
private void performUpdate() throws IOException {
DateTimeMigration dtMigration = new DateTimeMigration(settings.getOntModelSelector().getABoxModel(), logger, record);
dtMigration.updateABox();
performSparqlConstructAdditions(settings.getSparqlConstructAdditionsDir(), settings.getOntModelSelector().getABoxModel());
performSparqlConstructRetractions(settings.getSparqlConstructDeletionsDir(), settings.getOntModelSelector().getABoxModel());
DateTimeMigration dtMigration = new DateTimeMigration(settings.getOntModelSelector().getABoxModel(), logger, record);
dtMigration.updateABox();
List<AtomicOntologyChange> rawChanges = getAtomicOntologyChanges();
AtomicOntologyChangeLists changes = new AtomicOntologyChangeLists(rawChanges,
settings.getNewTBoxModel(),
settings.getOldTBoxModel());
//process the TBox before the ABox
updateTBoxAnnotations();
//TODO: uncomment updateTBoxAnnotations();
updateABox(changes);
@ -226,8 +225,7 @@ public class OntologyUpdater {
private List<AtomicOntologyChange> getAtomicOntologyChanges()
throws IOException {
return (new OntologyChangeParser(logger))
.parseFile(settings.getDiffFile());
return (new OntologyChangeParser(logger)).parseFile(settings.getDiffFile());
}
@ -339,18 +337,19 @@ public class OntologyUpdater {
if (changeObj.getSourceURI() != null){
if (oldTboxModel.getOntProperty(changeObj.getSourceURI()) != null){
atomicPropertyChanges.add(changeObj);
}
else if (oldTboxModel.getOntClass(changeObj.getSourceURI()) != null) {
atomicClassChanges.add(changeObj);
}
else{
logger.logError("Source URI is neither a Property" +
" nor a Class. " + "Change Object skipped for sourceURI: " + changeObj.getSourceURI());
atomicPropertyChanges.add(changeObj);
} else if (oldTboxModel.getOntClass(changeObj.getSourceURI()) != null) {
atomicClassChanges.add(changeObj);
} else if ("Prop".equals(changeObj.getNotes())) {
atomicPropertyChanges.add(changeObj);
} else if ("Class".equals(changeObj.getNotes())) {
atomicClassChanges.add(changeObj);
} else{
logger.log("WARNING: Source URI is neither a Property" +
" nor a Class. " + "Change Object skipped for sourceURI: " + changeObj.getSourceURI());
}
}
else if(changeObj.getDestinationURI() != null){
} else if(changeObj.getDestinationURI() != null){
if (newTboxModel.getOntProperty(changeObj.getDestinationURI()) != null) {
atomicPropertyChanges.add(changeObj);
@ -358,16 +357,14 @@ public class OntologyUpdater {
getDestinationURI()) != null) {
atomicClassChanges.add(changeObj);
} else{
logger.logError("Destination URI is neither a Property" +
logger.log("WARNING: Destination URI is neither a Property" +
" nor a Class. " + "Change Object skipped for destinationURI: " + changeObj.getDestinationURI());
}
}
else{
logger.logError("Source and Destination URI can't be null. "
+ "Change Object skipped" );
} else{
logger.log("WARNING: Source and Destination URI can't be null. " + "Change Object skipped" );
}
}
//logger.log("Property and Class change Object lists separated");
//logger.log("Property and Class change Object lists have been created");
}
public List<AtomicOntologyChange> getAtomicClassChanges() {