VIVO-502 fix bugs in editable property merge

This commit is contained in:
brianjlowe 2013-11-07 11:29:36 -05:00
parent 5b6e86ab01
commit 690072d00d
3 changed files with 118 additions and 45 deletions

View file

@ -1014,14 +1014,14 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (uri.equals(propRegister.getURI())) { if (uri.equals(propRegister.getURI())) {
property = propRegister.clone(); property = propRegister.clone();
} else { } else {
property = getObjectPropertyByURI(uri); ObjectProperty newProperty = getObjectPropertyByURI(uri);
if (property != null) { if (newProperty != null) {
propRegister = property; propRegister = newProperty;
// add canonical instance of the property first in the list // add canonical instance of the property first in the list
// before the range-changed versions // before the range-changed versions
properties.add(property); properties.add(newProperty);
// isolate the canonical prop from what's about to happen next // isolate the canonical prop from what's about to happen next
property = property.clone(); property = newProperty.clone();
} }
} }
if (property != null) { if (property != null) {

View file

@ -595,19 +595,34 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
private void updatePropertyRangeMap(Map<String, Resource[]> map, private void updatePropertyRangeMap(Map<String, Resource[]> map,
String propURI, String propURI,
Resource[] ranges) { Resource[] ranges,
boolean replaceIfMoreSpecific) {
Resource[] existingRanges = map.get(propURI); Resource[] existingRanges = map.get(propURI);
if (existingRanges == null) { if (existingRanges == null) {
map.put(propURI, ranges); map.put(propURI, ranges);
} else if (existingRanges[0] == null && existingRanges[1] != null) { } else if (existingRanges[0] == null && existingRanges[1] != null) {
existingRanges[0] = ranges[0]; existingRanges[0] = ranges[0];
map.put(propURI, existingRanges); map.put(propURI, existingRanges);
} else if (existingRanges[0] != null && existingRanges[1] == null) { } else if (existingRanges[0] != null) {
existingRanges[1] = ranges[1]; if (existingRanges[1] == null) {
existingRanges[1] = ranges[1];
}
if (moreSpecificThan(ranges[0], existingRanges[0])) {
existingRanges[0] = ranges[0];
}
map.put(propURI, existingRanges); map.put(propURI, existingRanges);
} }
} }
private boolean moreSpecificThan(Resource r1, Resource r2) {
if(r1.getURI() == null) {
return false;
} else if (r2.getURI() == null) {
return true;
}
return getWebappDaoFactory().getVClassDao().isSubClassOf(r1.getURI(), r2.getURI());
}
private List<OntClass> listSuperClasses(OntClass ontClass) { private List<OntClass> listSuperClasses(OntClass ontClass) {
return relatedClasses(ontClass, RDFS.subClassOf); return relatedClasses(ontClass, RDFS.subClassOf);
} }
@ -711,10 +726,11 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
Resource[] ranges = new Resource[2]; Resource[] ranges = new Resource[2];
if (rest.isAllValuesFromRestriction()) { if (rest.isAllValuesFromRestriction()) {
ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom(); ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges, true);
} else if (rest.isSomeValuesFromRestriction()) { } else if (rest.isSomeValuesFromRestriction()) {
ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom(); ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom();
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges, false);
} }
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges);
} }
} }
@ -736,7 +752,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
Resource[] ranges = new Resource[2]; Resource[] ranges = new Resource[2];
ranges[0] = rangeRes; ranges[0] = rangeRes;
updatePropertyRangeMap( updatePropertyRangeMap(
applicableProperties, prop.getURI(), ranges); applicableProperties, prop.getURI(), ranges, false);
} }
} }
@ -831,9 +847,9 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
String domainURIStr = (domainRes != null && !domainRes.isAnon()) ? String domainURIStr = (domainRes != null && !domainRes.isAnon()) ?
domainURIStr = domainRes.getURI() domainURIStr = domainRes.getURI()
: null; : null;
if (rangeRes == null) { // if (rangeRes == null) {
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above // pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
} else { if(rangeRes != null) {
String rangeClassURI; String rangeClassURI;
if (rangeRes.isAnon()) { if (rangeRes.isAnon()) {
rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId() rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId()

View file

@ -105,7 +105,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
// unpopulated, so the properties are displayed to allow statements to be added to these properties. // unpopulated, so the properties are displayed to allow statements to be added to these properties.
// RY In future, we should limit this to properties that the user has permission to add properties to. // RY In future, we should limit this to properties that the user has permission to add properties to.
if (editing) { if (editing) {
mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList); propertyList = mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList);
} }
// Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones // Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones
@ -122,9 +122,11 @@ public class GroupedPropertyList extends BaseTemplateModel {
mergeAllPossibleDataProperties(propertyList); mergeAllPossibleDataProperties(propertyList);
} }
if (editing) { // Not currently necessary since the language-specific version is now added
propertyList = correctLanguageForProperties(propertyList); // during the merge
} // if (editing) {
// propertyList = correctLanguageForProperties(propertyList);
// }
sort(propertyList); sort(propertyList);
@ -253,7 +255,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
} }
} }
private void mergeAllPossibleObjectProperties( private List<Property> mergeAllPossibleObjectProperties(
List<ObjectProperty> populatedObjectPropertyList, List<ObjectProperty> populatedObjectPropertyList,
List<Property> propertyList) { List<Property> propertyList) {
@ -271,10 +273,27 @@ public class GroupedPropertyList extends BaseTemplateModel {
if (allPropInstColl != null) { if (allPropInstColl != null) {
for (PropertyInstance pi : allPropInstColl) { for (PropertyInstance pi : allPropInstColl) {
if (pi != null) { if (pi != null) {
if (!alreadyOnObjectPropertyList( // use the language-aware wdf because redundancy check
populatedObjectPropertyList, pi)) { // for display will depend on public label match
addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getDomainClassURI(), pi.getRangeClassURI(), ObjectProperty piOp = wdf.getObjectPropertyDao().getObjectPropertyByURIs(
propertyList); pi.getPropertyURI(), pi.getDomainClassURI(), pi.getRangeClassURI());
if (piOp == null) {
continue;
}
boolean addToList = true;
int opIndex = 0;
for(ObjectProperty op : populatedObjectPropertyList) {
if(redundant(op, piOp)) {
addToList = false;
if (moreRestrictiveRange(piOp, op, wadf)) {
propertyList = replaceOpWithPiOpInList(piOp, op, opIndex, propertyList);
}
break;
}
opIndex++;
}
if(addToList) {
propertyList.add(piOp);
} }
} else { } else {
log.error("a property instance in the Collection created by PropertyInstanceDao.getAllPossiblePropInstForIndividual() is unexpectedly null"); log.error("a property instance in the Collection created by PropertyInstanceDao.getAllPossiblePropInstForIndividual() is unexpectedly null");
@ -292,35 +311,73 @@ public class GroupedPropertyList extends BaseTemplateModel {
addObjectPropertyToPropertyList(propertyUri, null, null, propertyList); addObjectPropertyToPropertyList(propertyUri, null, null, propertyList);
} }
} }
return propertyList;
} }
private boolean alreadyOnObjectPropertyList(List<ObjectProperty> opList, private boolean moreRestrictiveRange(ObjectProperty piOp, ObjectProperty op,
PropertyInstance pi) { WebappDaoFactory wadf) {
if (pi.getPropertyURI() == null) { if(piOp.getRangeVClassURI() == null) {
return false;
} else if (op.getRangeVClassURI() == null) {
return (piOp.getRangeVClassURI() != null);
} else {
return (wadf.getVClassDao().isSubClassOf(
piOp.getRangeVClassURI(), op.getRangeVClassURI()));
}
}
private List<Property> replaceOpWithPiOpInList(ObjectProperty piOp,
ObjectProperty op, int opIndex, List<Property> propertyList) {
List<Property> returnList = new ArrayList<Property>();
int index = 0;
for(Property p : propertyList) {
if(index == opIndex /* p.equals(op) */) {
returnList.add(piOp);
} else {
returnList.add(p);
}
index++;
}
return returnList;
}
private boolean redundant(ObjectProperty op, ObjectProperty op2) {
if (op2.getURI() == null) {
return false; return false;
} }
for (ObjectProperty op : opList) { boolean uriMatches = (op.getURI() != null
boolean uriMatches = (op.getURI() != null && op.getURI().equals(op2.getURI()));
&& op.getURI().equals(pi.getPropertyURI())); boolean domainMatches = false;
boolean domainMatches = false; boolean rangeMatches = false;
boolean rangeMatches = false; boolean labelMatches = false;
if(op.getDomainVClassURI() == null) { if(op.getDomainPublic() == null) {
if(pi.getDomainClassURI() == null) { if(op2.getDomainPublic() == null) {
domainMatches = true; labelMatches = true;
} }
} else if (op.getDomainVClassURI().equals(pi.getDomainClassURI())) { } else if (op.getDomainPublic().equals(op2.getDomainPublic())) {
labelMatches = true;
}
if(uriMatches && labelMatches) {
return true;
}
if(op.getDomainVClassURI() == null) {
if(op2.getDomainVClassURI() == null) {
domainMatches = true; domainMatches = true;
} }
if(op.getRangeVClassURI() == null) { } else if (op.getDomainVClassURI().equals(op2.getDomainVClassURI())) {
if (pi.getDomainClassURI() == null) { domainMatches = true;
rangeMatches = true; }
} if(op.getRangeVClassURI() == null) {
} else if (op.getRangeVClassURI().equals(pi.getRangeClassURI())) { if (op2.getRangeVClassURI() == null) {
rangeMatches = true; rangeMatches = true;
} }
if (uriMatches && domainMatches && rangeMatches) { } else if (op.getRangeVClassURI().equals(op2.getRangeVClassURI())) {
return true; rangeMatches = true;
} }
if (uriMatches && domainMatches && rangeMatches) {
return true;
} }
return false; return false;
} }