VIVO-957 error, updating subclass sorting method for object, using superclasses of classes instead of just comparing whether classes are subclasses of each other

This commit is contained in:
hudajkhan 2015-02-03 15:25:18 -05:00
parent a829de7923
commit 8e97ff3678

View file

@ -24,18 +24,22 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel { public class CollatedObjectPropertyTemplateModel extends
ObjectPropertyTemplateModel {
private static final Log log = LogFactory.getLog(CollatedObjectPropertyTemplateModel.class); private static final Log log = LogFactory
.getLog(CollatedObjectPropertyTemplateModel.class);
private static final String SUBCLASS_VARIABLE_NAME = "subclass"; private static final String SUBCLASS_VARIABLE_NAME = "subclass";
private static final Pattern SELECT_SUBCLASS_PATTERN = private static final Pattern SELECT_SUBCLASS_PATTERN =
// SELECT ?subclass // SELECT ?subclass
Pattern.compile("SELECT[^{]*\\?" + SUBCLASS_VARIABLE_NAME + "\\b", Pattern.CASE_INSENSITIVE); Pattern.compile("SELECT[^{]*\\?" + SUBCLASS_VARIABLE_NAME + "\\b",
Pattern.CASE_INSENSITIVE);
// ORDER BY ?subclass // ORDER BY ?subclass
// ORDER BY DESC(?subclass) // ORDER BY DESC(?subclass)
private static final Pattern ORDER_BY_SUBCLASS_PATTERN = private static final Pattern ORDER_BY_SUBCLASS_PATTERN = Pattern.compile(
Pattern.compile("ORDER\\s+BY\\s+(DESC\\s*\\(\\s*)?\\?" + SUBCLASS_VARIABLE_NAME, Pattern.CASE_INSENSITIVE); "ORDER\\s+BY\\s+(DESC\\s*\\(\\s*)?\\?" + SUBCLASS_VARIABLE_NAME,
Pattern.CASE_INSENSITIVE);
private final List<SubclassTemplateModel> subclasses; private final List<SubclassTemplateModel> subclasses;
private final VClassDao vclassDao; private final VClassDao vclassDao;
@ -50,7 +54,8 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
vclassDao = vreq.getWebappDaoFactory().getVClassDao(); vclassDao = vreq.getWebappDaoFactory().getVClassDao();
if (populatedObjectPropertyList.contains(op)) { if (populatedObjectPropertyList.contains(op)) {
log.debug("Getting data for populated object property " + op.getURI()); log.debug("Getting data for populated object property "
+ op.getURI());
/* Get the data */ /* Get the data */
List<Map<String, String>> statementData = getStatementData(); List<Map<String, String>> statementData = getStatementData();
@ -58,11 +63,13 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
/* Apply post-processing */ /* Apply post-processing */
postprocess(statementData); postprocess(statementData);
/* Collate the data */ /* Collate the data */log.debug("Collate:collating subclasses for "
+ subjectUri + " - predicate= " + op.getURI());
subclasses = collate(subjectUri, op, statementData, editing); subclasses = collate(subjectUri, op, statementData, editing);
for (SubclassTemplateModel subclass : subclasses) { for (SubclassTemplateModel subclass : subclasses) {
List<ObjectPropertyStatementTemplateModel> list = subclass.getStatements(); List<ObjectPropertyStatementTemplateModel> list = subclass
.getStatements();
postprocessStatementList(list); postprocessStatementList(list);
} }
@ -87,12 +94,12 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
Matcher m; Matcher m;
m = SELECT_SUBCLASS_PATTERN.matcher(queryString); m = SELECT_SUBCLASS_PATTERN.matcher(queryString);
if ( ! m.find() ) { if (!m.find()) {
return ConfigError.NO_SUBCLASS_SELECT; return ConfigError.NO_SUBCLASS_SELECT;
} }
m = ORDER_BY_SUBCLASS_PATTERN.matcher(queryString); m = ORDER_BY_SUBCLASS_PATTERN.matcher(queryString);
if ( ! m.find() ) { if (!m.find()) {
return ConfigError.NO_SUBCLASS_ORDER_BY; return ConfigError.NO_SUBCLASS_ORDER_BY;
} }
@ -106,14 +113,16 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
} }
/* /*
* The query returns subclasses of a specific superclass that the object belongs to; for example, * The query returns subclasses of a specific superclass that the object
* in the case of authorInAuthorship, subclasses of core:InformationResource. Here we remove all but * belongs to; for example, in the case of authorInAuthorship, subclasses of
* the most specific subclass for the object. * core:InformationResource. Here we remove all but the most specific
* subclass for the object.
*/ */
private void filterSubclasses(List<Map<String, String>> statementData) { private void filterSubclasses(List<Map<String, String>> statementData) {
String objectVariableName = getObjectKey(); String objectVariableName = getObjectKey();
if (objectVariableName == null) { if (objectVariableName == null) {
log.error("Cannot remove duplicate statements for property " + getUri() + " because no object found to dedupe."); log.error("Cannot remove duplicate statements for property "
+ getUri() + " because no object found to dedupe.");
return; return;
} }
@ -122,10 +131,12 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
logData(statementData); logData(statementData);
} }
// Compile a list of the statements with most specific subclasses; others will be removed // Compile a list of the statements with most specific subclasses;
// others will be removed
List<Map<String, String>> filteredList = new ArrayList<Map<String, String>>(); List<Map<String, String>> filteredList = new ArrayList<Map<String, String>>();
Set<String> processedObjects = new HashSet<String>(); Set<String> processedObjects = new HashSet<String>();
for (Map<String, String> outerMap : statementData) { for (Map<String, String> outerMap : statementData) {
String objectUri = outerMap.get(objectVariableName); String objectUri = outerMap.get(objectVariableName);
if (processedObjects.contains(objectUri)) { if (processedObjects.contains(objectUri)) {
continue; continue;
@ -133,12 +144,15 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
processedObjects.add(objectUri); processedObjects.add(objectUri);
List<Map<String, String>> dataForThisObject = new ArrayList<Map<String, String>>(); List<Map<String, String>> dataForThisObject = new ArrayList<Map<String, String>>();
for (Map<String, String> innerMap : statementData) { for (Map<String, String> innerMap : statementData) {
if ( innerMap.get(objectVariableName) == objectUri ) { if (innerMap.get(objectVariableName) == objectUri) {
dataForThisObject.add(innerMap); dataForThisObject.add(innerMap);
} }
} }
// Sort the data for this object from most to least specific subclass, with nulls at end // Sort the data for this object from most to least specific
// subclass, with nulls at end
Collections.sort(dataForThisObject, new DataComparatorBySubclass()); Collections.sort(dataForThisObject, new DataComparatorBySubclass());
filteredList.add(dataForThisObject.get(0)); filteredList.add(dataForThisObject.get(0));
} }
@ -150,7 +164,8 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
} }
} }
private class DataComparatorBySubclass implements Comparator<Map<String, String>> { private class DataComparatorBySubclass implements
Comparator<Map<String, String>> {
@Override @Override
public int compare(Map<String, String> map1, Map<String, String> map2) { public int compare(Map<String, String> map1, Map<String, String> map2) {
@ -170,27 +185,47 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
return -1; // nulls rank highest return -1; // nulls rank highest
} }
if (subclass1.equals(subclass2)) { // if subclasses are equal, return 0
if (subclass1.equals(subclass2))
return 0; return 0;
String subclass1Superclasses = this
.getSuperclassesAsString(subclass1);
String subclass2Superclasses = this
.getSuperclassesAsString(subclass2);
int s1SuperclassesLength = subclass1Superclasses.length();
int s2SuperclassesLength = subclass2Superclasses.length();
if (s1SuperclassesLength == s2SuperclassesLength) {
// If the length is the same, then compare the strings
// alphabetically
return subclass1Superclasses.compareTo(subclass2Superclasses);
} else {
// if the length is different, the longer string is the more
// specific type
return (s1SuperclassesLength > s2SuperclassesLength ? -1 : 1);
}
} }
List<String> superclasses = vclassDao.getAllSuperClassURIs(subclass1); // Given a particular class URI, generate a string representing the
if (superclasses.contains(subclass2)) { // superclasses and types of the class
return -1; // The types are first sorted alphabetically and then concatenated to
} // form the string representation
private String getSuperclassesAsString(String classURI) {
List<String> superclasses = vclassDao
.getAllSuperClassURIs(classURI);
if (superclasses == null || superclasses.size() == 0)
return "";
Collections.sort(superclasses);
return StringUtils.join(superclasses, " | ");
superclasses = vclassDao.getAllSuperClassURIs(subclass2);
if (superclasses.contains(subclass1)) {
return 1;
}
return 0;
} }
} }
// Collate the statements by subclass. // Collate the statements by subclass.
private List<SubclassTemplateModel> collate(String subjectUri, ObjectProperty property, private List<SubclassTemplateModel> collate(String subjectUri,
List<Map<String, String>> statementData, boolean editing) { ObjectProperty property, List<Map<String, String>> statementData,
boolean editing) {
String objectKey = getObjectKey(); String objectKey = getObjectKey();
@ -206,8 +241,8 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
for (SubclassTemplateModel subclass : subclasses) { for (SubclassTemplateModel subclass : subclasses) {
VClass subclassVClass = subclass.getVClass(); VClass subclassVClass = subclass.getVClass();
if ( ( vclass == null && subclassVClass == null ) || if ((vclass == null && subclassVClass == null)
( vclass != null && vclass.equals(subclassVClass) ) ) { || (vclass != null && vclass.equals(subclassVClass))) {
listForThisSubclass = subclass.getStatements(); listForThisSubclass = subclass.getStatements();
break; break;
} }
@ -215,77 +250,78 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
if (listForThisSubclass == null) { if (listForThisSubclass == null) {
listForThisSubclass = new ArrayList<ObjectPropertyStatementTemplateModel>(); listForThisSubclass = new ArrayList<ObjectPropertyStatementTemplateModel>();
subclasses.add(new SubclassTemplateModel(vclass, listForThisSubclass)); subclasses.add(new SubclassTemplateModel(vclass,
listForThisSubclass));
} }
listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri, listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(
property, objectKey, map, getTemplateName(), vreq)); subjectUri, property, objectKey, map, getTemplateName(),
vreq));
} }
return subclasses; return subclasses;
} }
// class SubclassComparatorByDisplayRank implements Comparator<String> { // class SubclassComparatorByDisplayRank implements Comparator<String> {
// //
// private List<VClass> vclasses; // private List<VClass> vclasses;
// //
// SubclassComparatorByDisplayRank(List<VClass> vclasses) { // SubclassComparatorByDisplayRank(List<VClass> vclasses) {
// this.vclasses = vclasses; // this.vclasses = vclasses;
// } // }
// //
// @Override // @Override
// public int compare(String nameLeft, String nameRight) { // public int compare(String nameLeft, String nameRight) {
// //
// if (StringUtils.isBlank(uriLeft)) { // if (StringUtils.isBlank(uriLeft)) {
// return StringUtils.isBlank(uriRight) ? 0 : 1; // return StringUtils.isBlank(uriRight) ? 0 : 1;
// } // }
// //
// VClass vclassLeft = vclassDao.getVClassByURI(uriLeft); // VClass vclassLeft = vclassDao.getVClassByURI(uriLeft);
// VClass vclassRight = vclassDao.getVClassByURI(uriRight); // VClass vclassRight = vclassDao.getVClassByURI(uriRight);
// //
// if (vclassLeft == null) { // if (vclassLeft == null) {
// return vclassRight == null ? 0 : 1; // return vclassRight == null ? 0 : 1;
// } // }
// //
// int rankLeft = vclassLeft.getDisplayRank(); // int rankLeft = vclassLeft.getDisplayRank();
// int rankRight = vclassRight.getDisplayRank(); // int rankRight = vclassRight.getDisplayRank();
// //
// int intCompare = 0; // int intCompare = 0;
// //
// // Values < 1 are undefined and go at end, not beginning // // Values < 1 are undefined and go at end, not beginning
// if (rankLeft < 1) { // if (rankLeft < 1) {
// intCompare = rankRight < 1 ? 0 : 1; // intCompare = rankRight < 1 ? 0 : 1;
// } else if (rankRight < 1) { // } else if (rankRight < 1) {
// intCompare = -1; // intCompare = -1;
// } else { // } else {
// intCompare = ((Integer)rankLeft).compareTo(rankRight); // intCompare = ((Integer)rankLeft).compareTo(rankRight);
// } // }
// //
// if (intCompare != 0) { // if (intCompare != 0) {
// return intCompare; // return intCompare;
// } // }
// //
// // If display ranks are equal, sort by name // // If display ranks are equal, sort by name
// if (nameLeft == null) { // if (nameLeft == null) {
// return nameRight == null ? 0 : 1; // return nameRight == null ? 0 : 1;
// } // }
// if (nameRight == null) { // if (nameRight == null) {
// return -1; // return -1;
// } // }
// return nameLeft.compareToIgnoreCase(nameRight); // return nameLeft.compareToIgnoreCase(nameRight);
// //
// } // }
// } // }
// private String getSubclassName(String subclassUri) {
// if (subclassUri.isEmpty()) {
// return "";
// }
// VClass vclass = vclassDao.getVClassByURI(subclassUri);
// return vclass != null ? vclass.getName() : "";
// }
// private String getSubclassName(String subclassUri) {
// if (subclassUri.isEmpty()) {
// return "";
// }
// VClass vclass = vclassDao.getVClassByURI(subclassUri);
// return vclass != null ? vclass.getName() : "";
// }
/* Template properties */ /* Template properties */