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:
parent
a829de7923
commit
8e97ff3678
1 changed files with 299 additions and 263 deletions
|
@ -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() {
|
||||
|
|
Loading…
Add table
Reference in a new issue