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.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 Pattern SELECT_SUBCLASS_PATTERN =
// 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 DESC(?subclass)
private static final Pattern ORDER_BY_SUBCLASS_PATTERN =
Pattern.compile("ORDER\\s+BY\\s+(DESC\\s*\\(\\s*)?\\?" + SUBCLASS_VARIABLE_NAME, Pattern.CASE_INSENSITIVE);
private static final Pattern ORDER_BY_SUBCLASS_PATTERN = Pattern.compile(
"ORDER\\s+BY\\s+(DESC\\s*\\(\\s*)?\\?" + SUBCLASS_VARIABLE_NAME,
Pattern.CASE_INSENSITIVE);
private final List<SubclassTemplateModel> subclasses;
private final VClassDao vclassDao;
@ -50,7 +54,8 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
vclassDao = vreq.getWebappDaoFactory().getVClassDao();
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 */
List<Map<String, String>> statementData = getStatementData();
@ -58,11 +63,13 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
/* Apply post-processing */
postprocess(statementData);
/* Collate the data */
/* Collate the data */log.debug("Collate:collating subclasses for "
+ subjectUri + " - predicate= " + op.getURI());
subclasses = collate(subjectUri, op, statementData, editing);
for (SubclassTemplateModel subclass : subclasses) {
List<ObjectPropertyStatementTemplateModel> list = subclass.getStatements();
List<ObjectPropertyStatementTemplateModel> list = subclass
.getStatements();
postprocessStatementList(list);
}
@ -106,14 +113,16 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
}
/*
* The query returns subclasses of a specific superclass that the object belongs to; for example,
* in the case of authorInAuthorship, subclasses of core:InformationResource. Here we remove all but
* the most specific subclass for the object.
* The query returns subclasses of a specific superclass that the object
* belongs to; for example, in the case of authorInAuthorship, subclasses of
* core:InformationResource. Here we remove all but the most specific
* subclass for the object.
*/
private void filterSubclasses(List<Map<String, String>> statementData) {
String objectVariableName = getObjectKey();
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;
}
@ -122,10 +131,12 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
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>>();
Set<String> processedObjects = new HashSet<String>();
for (Map<String, String> outerMap : statementData) {
String objectUri = outerMap.get(objectVariableName);
if (processedObjects.contains(objectUri)) {
continue;
@ -137,8 +148,11 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
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());
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
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
}
if (subclass1.equals(subclass2)) {
// if subclasses are equal, return 0
if (subclass1.equals(subclass2))
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);
if (superclasses.contains(subclass2)) {
return -1;
}
// Given a particular class URI, generate a string representing the
// superclasses and types of the class
// 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.
private List<SubclassTemplateModel> collate(String subjectUri, ObjectProperty property,
List<Map<String, String>> statementData, boolean editing) {
private List<SubclassTemplateModel> collate(String subjectUri,
ObjectProperty property, List<Map<String, String>> statementData,
boolean editing) {
String objectKey = getObjectKey();
@ -206,8 +241,8 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
for (SubclassTemplateModel subclass : subclasses) {
VClass subclassVClass = subclass.getVClass();
if ( ( vclass == null && subclassVClass == null ) ||
( vclass != null && vclass.equals(subclassVClass) ) ) {
if ((vclass == null && subclassVClass == null)
|| (vclass != null && vclass.equals(subclassVClass))) {
listForThisSubclass = subclass.getStatements();
break;
}
@ -215,11 +250,13 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
if (listForThisSubclass == null) {
listForThisSubclass = new ArrayList<ObjectPropertyStatementTemplateModel>();
subclasses.add(new SubclassTemplateModel(vclass, listForThisSubclass));
subclasses.add(new SubclassTemplateModel(vclass,
listForThisSubclass));
}
listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri,
property, objectKey, map, getTemplateName(), vreq));
listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(
subjectUri, property, objectKey, map, getTemplateName(),
vreq));
}
@ -286,7 +323,6 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
// return vclass != null ? vclass.getName() : "";
// }
/* Template properties */
public List<SubclassTemplateModel> getSubclasses() {