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())) {
property = propRegister.clone();
} else {
property = getObjectPropertyByURI(uri);
if (property != null) {
propRegister = property;
ObjectProperty newProperty = getObjectPropertyByURI(uri);
if (newProperty != null) {
propRegister = newProperty;
// add canonical instance of the property first in the list
// before the range-changed versions
properties.add(property);
properties.add(newProperty);
// isolate the canonical prop from what's about to happen next
property = property.clone();
property = newProperty.clone();
}
}
if (property != null) {

View file

@ -595,19 +595,34 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
private void updatePropertyRangeMap(Map<String, Resource[]> map,
String propURI,
Resource[] ranges) {
Resource[] ranges,
boolean replaceIfMoreSpecific) {
Resource[] existingRanges = map.get(propURI);
if (existingRanges == null) {
map.put(propURI, ranges);
} else if (existingRanges[0] == null && existingRanges[1] != null) {
existingRanges[0] = ranges[0];
map.put(propURI, existingRanges);
} else if (existingRanges[0] != null && existingRanges[1] == null) {
existingRanges[1] = ranges[1];
} else if (existingRanges[0] != null) {
if (existingRanges[1] == null) {
existingRanges[1] = ranges[1];
}
if (moreSpecificThan(ranges[0], existingRanges[0])) {
existingRanges[0] = ranges[0];
}
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) {
return relatedClasses(ontClass, RDFS.subClassOf);
}
@ -711,10 +726,11 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
Resource[] ranges = new Resource[2];
if (rest.isAllValuesFromRestriction()) {
ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges, true);
} else if (rest.isSomeValuesFromRestriction()) {
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];
ranges[0] = rangeRes;
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()) ?
domainURIStr = domainRes.getURI()
: null;
if (rangeRes == null) {
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
} else {
// if (rangeRes == null) {
// pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
if(rangeRes != null) {
String rangeClassURI;
if (rangeRes.isAnon()) {
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.
// RY In future, we should limit this to properties that the user has permission to add properties to.
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
@ -122,9 +122,11 @@ public class GroupedPropertyList extends BaseTemplateModel {
mergeAllPossibleDataProperties(propertyList);
}
if (editing) {
propertyList = correctLanguageForProperties(propertyList);
}
// Not currently necessary since the language-specific version is now added
// during the merge
// if (editing) {
// propertyList = correctLanguageForProperties(propertyList);
// }
sort(propertyList);
@ -253,7 +255,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
}
private void mergeAllPossibleObjectProperties(
private List<Property> mergeAllPossibleObjectProperties(
List<ObjectProperty> populatedObjectPropertyList,
List<Property> propertyList) {
@ -271,10 +273,27 @@ public class GroupedPropertyList extends BaseTemplateModel {
if (allPropInstColl != null) {
for (PropertyInstance pi : allPropInstColl) {
if (pi != null) {
if (!alreadyOnObjectPropertyList(
populatedObjectPropertyList, pi)) {
addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getDomainClassURI(), pi.getRangeClassURI(),
propertyList);
// use the language-aware wdf because redundancy check
// for display will depend on public label match
ObjectProperty piOp = wdf.getObjectPropertyDao().getObjectPropertyByURIs(
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 {
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);
}
}
return propertyList;
}
private boolean alreadyOnObjectPropertyList(List<ObjectProperty> opList,
PropertyInstance pi) {
if (pi.getPropertyURI() == null) {
private boolean moreRestrictiveRange(ObjectProperty piOp, ObjectProperty op,
WebappDaoFactory wadf) {
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;
}
for (ObjectProperty op : opList) {
boolean uriMatches = (op.getURI() != null
&& op.getURI().equals(pi.getPropertyURI()));
boolean domainMatches = false;
boolean rangeMatches = false;
if(op.getDomainVClassURI() == null) {
if(pi.getDomainClassURI() == null) {
domainMatches = true;
}
} else if (op.getDomainVClassURI().equals(pi.getDomainClassURI())) {
boolean uriMatches = (op.getURI() != null
&& op.getURI().equals(op2.getURI()));
boolean domainMatches = false;
boolean rangeMatches = false;
boolean labelMatches = false;
if(op.getDomainPublic() == null) {
if(op2.getDomainPublic() == null) {
labelMatches = true;
}
} else if (op.getDomainPublic().equals(op2.getDomainPublic())) {
labelMatches = true;
}
if(uriMatches && labelMatches) {
return true;
}
if(op.getDomainVClassURI() == null) {
if(op2.getDomainVClassURI() == null) {
domainMatches = true;
}
if(op.getRangeVClassURI() == null) {
if (pi.getDomainClassURI() == null) {
rangeMatches = true;
}
} else if (op.getRangeVClassURI().equals(pi.getRangeClassURI())) {
} else if (op.getDomainVClassURI().equals(op2.getDomainVClassURI())) {
domainMatches = true;
}
if(op.getRangeVClassURI() == null) {
if (op2.getRangeVClassURI() == null) {
rangeMatches = true;
}
if (uriMatches && domainMatches && rangeMatches) {
return true;
}
} else if (op.getRangeVClassURI().equals(op2.getRangeVClassURI())) {
rangeMatches = true;
}
if (uriMatches && domainMatches && rangeMatches) {
return true;
}
return false;
}