NIHVIVO-215

This commit is contained in:
sjm222 2010-03-26 19:26:16 +00:00
parent ae7b5b9835
commit 174ca4dbcb
2 changed files with 170 additions and 48 deletions

View file

@ -10,14 +10,12 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.AllValuesFromRestriction;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntResource;
@ -575,26 +573,12 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
ontModel.enterCriticalSection(Lock.WRITE);
try {
com.hp.hpl.jena.ontology.DatatypeProperty jDataprop = ontModel.getDatatypeProperty(dtp.getURI());
if (dtp.getPublicName() == null || dtp.getPublicName().length() == 0) {
jDataprop.removeAll(RDFS.label);
} else {
jDataprop.setLabel(dtp.getPublicName(), (String) getDefaultLanguage());
}
Resource domainRes = null;
if ( (dtp.getDomainClassURI() != null) && (dtp.getDomainClassURI().length()>0) ) {
domainRes = ontModel.getResource(dtp.getDomainClassURI());
}
jDataprop.removeAll(RDFS.domain);
if (domainRes != null) {
jDataprop.setDomain(domainRes);
}
if (dtp.getRangeDatatypeURI() != null && !dtp.getRangeDatatypeURI().equals("")) {
Resource rangeResource = ontModel.getResource(dtp.getRangeDatatypeURI());
if (rangeResource != null)
jDataprop.setRange(rangeResource);
} else {
jDataprop.removeAll(RDFS.range);
}
updateRDFSLabel(jDataprop, dtp.getPublicName());
updatePropertyResourceURIValue(jDataprop, RDFS.domain,dtp.getDomainClassURI(),ontModel);
updatePropertyResourceURIValue(jDataprop, RDFS.range,dtp.getRangeDatatypeURI(),ontModel);
if (dtp.getFunctional()) {
if (!ontModel.contains(jDataprop,RDF.type,OWL.FunctionalProperty)) {
ontModel.add(jDataprop,RDF.type,OWL.FunctionalProperty);
@ -604,37 +588,25 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
ontModel.remove(jDataprop,RDF.type,OWL.FunctionalProperty);
}
}
updatePropertyStringValue(jDataprop, EXAMPLE, dtp.getExample(), ontModel);
updatePropertyStringValue(jDataprop, DESCRIPTION_ANNOT, dtp.getDescription(), ontModel);
updatePropertyStringValue(jDataprop, PUBLIC_DESCRIPTION_ANNOT, dtp.getPublicDescription(), ontModel);
updatePropertyNonNegativeIntValue(jDataprop, DISPLAY_RANK_ANNOT, dtp.getDisplayTier(), ontModel);
updatePropertyNonNegativeIntValue(jDataprop, DISPLAY_LIMIT, dtp.getDisplayLimit(), ontModel);
//updatePropertyStringValue(jDataprop, HIDDEN_ANNOT, dtp.getHidden(), ontModel);
jDataprop.removeAll(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
if (HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT != null && dtp.getHiddenFromDisplayBelowRoleLevel() != null) { // only need to add if present
jDataprop.addProperty(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(dtp.getHiddenFromDisplayBelowRoleLevel().getURI()));
}
jDataprop.removeAll(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
if (PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT != null && dtp.getProhibitedFromUpdateBelowRoleLevel() != null) { // only need to add if present
jDataprop.addProperty(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(dtp.getProhibitedFromUpdateBelowRoleLevel().getURI()));
}
/*
updatePropertyBooleanValue(jDataprop, PROPERTY_SELFEDITPROHIBITEDANNOT, dtp.isSelfEditProhibited(), ontModel, JenaBaseDao.KEEP_ONLY_IF_TRUE);
updatePropertyBooleanValue(jDataprop, PROPERTY_CURATOREDITPROHIBITEDANNOT, dtp.isCuratorEditProhibited(), ontModel, JenaBaseDao.KEEP_ONLY_IF_TRUE);
*/
try {
jDataprop.removeAll(PROPERTY_INPROPERTYGROUPANNOT);
if (dtp.getGroupURI() != null && dtp.getGroupURI().length()>0) {
String badURIErrorStr = checkURI(dtp.getGroupURI());
if (badURIErrorStr == null) {
jDataprop.addProperty(PROPERTY_INPROPERTYGROUPANNOT, ontModel.getResource(dtp.getGroupURI()));
} else {
log.error(badURIErrorStr);
}
}
} catch (Exception e) {
log.error("error linking data property "+dtp.getURI()+" to property group");
}
if (dtp.getHiddenFromDisplayBelowRoleLevel() != null) {
updatePropertyResourceURIValue(jDataprop,HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT,dtp.getHiddenFromDisplayBelowRoleLevel().getURI(),ontModel);
}
if (dtp.getProhibitedFromUpdateBelowRoleLevel() != null) {
updatePropertyResourceURIValue(jDataprop,PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT,dtp.getProhibitedFromUpdateBelowRoleLevel().getURI(),ontModel);
}
if (dtp.getGroupURI() != null) {
updatePropertyResourceURIValue(jDataprop,PROPERTY_INPROPERTYGROUPANNOT,dtp.getGroupURI(),ontModel);
}
updatePropertyStringValue(jDataprop,PROPERTY_CUSTOMENTRYFORMANNOT,dtp.getCustomEntryForm(),ontModel);
} finally {
ontModel.leaveCriticalSection();

View file

@ -0,0 +1,150 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.dao.jena;
import org.junit.Assert;
import org.junit.Test;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
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.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
/**
*
*
*/
public class DataPropertyDaoJenaTest {
@Test
// Test that the DataPropertyDaoJena::updateDataProperty method will only update the jena model for
// those properties in DataProperty that have a different value from what is already in the
// jena model for that property.
//
// Specifically, updateDataProperty method should not remove a statement from the model and
// then add the same statement back in. The reason for this is that in vitro the "immutable" properties
// are stored in a sub-model and the user-editable properties are stored in a super-model and
// all updates are performed against the super-model, so removing and then re-adding
// the same statement may result in a change of state (if the statement was in the sub-model
// it will migrate to the super-model) because of the way jena handles additions and
// deletions with respect to super and sub models. This migration of statements may cause
// undesirable behavior in the vitro application.
public void minimalUpdates(){
// 1. create two models and attach one as a sub-model of the other
// 2. populate the sub-model with one statement for each of the 13 properties represented in DataProperty
// 3. save the state of both the sub-model and the super-model
// 4. populate a DataProperty object with the data in the (combined) model and call the updateDataProperty
// (having made no changes to the DataProperty object)
// 5. verify that both the sub-model and the super-model are unchanged
String propertyURI = "http://vivoweb.org/ontology/core#addressCity";
OntModel superModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); // this simulates the user-editable ontology in vivo
OntModel subModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); // this simulates the core ontology in vivo
superModel.addSubModel(subModel);
String rdfsLabel = "this is the rdfs label";
String lang = "en-US";
// populate sub-model
DatatypeProperty property1 = subModel.createDatatypeProperty(propertyURI);
property1.setLabel(rdfsLabel,lang);
property1.setPropertyValue(RDFS.domain, subModel.createResource("http://thisIsTheDomainClassURI"));
property1.setPropertyValue(RDFS.range, subModel.createResource("http://thisIsTheRangeClassURI"));
property1.addProperty(RDF.type, OWL.FunctionalProperty);
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.EXAMPLE_ANNOT), subModel.createTypedLiteral("this is the example"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.DESCRIPTION_ANNOT), subModel.createTypedLiteral("this is the description"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PUBLIC_DESCRIPTION_ANNOT), subModel.createTypedLiteral("this is the public description"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.DISPLAY_RANK_ANNOT), subModel.createTypedLiteral(21));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.DISPLAY_LIMIT), subModel.createTypedLiteral(5));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT), subModel.createResource("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT), subModel.createResource("http://thisIsTheInPropertyGroupURI"));
property1.setPropertyValue(subModel.createProperty(VitroVocabulary.PROPERTY_CUSTOMENTRYFORMANNOT), subModel.createResource("http://thisIsTheCustomFormEntryURI"));
// Save copies of sub-model and super-model
// uncommment the next two lines to debug failures
//System.out.println("**Before updating data property:");
//printModels(superModel, subModel);
superModel.removeSubModel(subModel);
OntModel origSubModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
origSubModel.add(subModel);
OntModel origSuperModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
origSuperModel.add(superModel);
superModel.addSubModel(subModel);
// Populate the DataProperty with the data in the sub-model and then update the combined model
// (from the unchanged object).
WebappDaoFactoryJena wdfj = new WebappDaoFactoryJena(superModel);
DataPropertyDaoJena dpdj = (DataPropertyDaoJena) wdfj.getDataPropertyDao();
DataProperty dataProperty = dpdj.getDataPropertyByURI(propertyURI); // the DataProperty will be populated
// with the information already in
// the jena model.
Assert.assertEquals(dataProperty.getPublicName(), property1.getLabel(lang));
dpdj.updateDataProperty(dataProperty); // we haven't changed any values here, so
// the models should be unchanged.
// Verify that the sub-model and super-model are both unchanged
// uncommment the next two lines to debug failures
//System.out.println("\n**After updating data property:");
//printModels(superModel,subModel);
superModel.removeSubModel(subModel);
//modtime affects the diff but we don't care about that difference
wipeOutModTime(origSubModel);
wipeOutModTime(origSuperModel);
wipeOutModTime(subModel);
wipeOutModTime(superModel);
Assert.assertTrue(subModel.isIsomorphicWith(origSubModel));
Assert.assertTrue(superModel.isIsomorphicWith(origSuperModel));
}
void printModels(OntModel superModel, OntModel subModel) {
// Detach the submodel for printing to get an accurate
// account of what is in each.
superModel.removeSubModel(subModel);
System.out.println("\nThe sub-model has " + subModel.size() + " statements:");
System.out.println("---------------------------------------------------");
subModel.writeAll(System.out,"N3",null);
System.out.println("\nThe super-model has " + superModel.size() + " statements:");
System.out.println("---------------------------------------------------");
superModel.write(System.out,"N3",null);
superModel.addSubModel(subModel);
}
void wipeOutModTime(Model model){
model.removeAll(null, model.createProperty(VitroVocabulary.MODTIME), null);
}
}