VIVO-957 updating so most specific types are retrieved for the object uri instead of any string comparison or subclass comparison through the dao
This commit is contained in:
parent
9f9cea06e3
commit
ed9b82258d
1 changed files with 51 additions and 65 deletions
|
@ -12,6 +12,8 @@ import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -22,6 +24,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
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.dao.WebappDaoFactory;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
|
||||||
|
|
||||||
public class CollatedObjectPropertyTemplateModel extends
|
public class CollatedObjectPropertyTemplateModel extends
|
||||||
|
@ -135,6 +139,9 @@ public class CollatedObjectPropertyTemplateModel extends
|
||||||
// others will be removed
|
// 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>();
|
||||||
|
//Useful to keep track of objects where statement data may not match the most specific type
|
||||||
|
//returne for some reason, in which case useful to keep track
|
||||||
|
Set<String> filteredObjects = 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);
|
||||||
|
@ -142,18 +149,29 @@ public class CollatedObjectPropertyTemplateModel extends
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
processedObjects.add(objectUri);
|
processedObjects.add(objectUri);
|
||||||
List<Map<String, String>> dataForThisObject = new ArrayList<Map<String, String>>();
|
//Get most specific type for this particular
|
||||||
|
List<String> mostSpecificTypes = this.getSortedMostSpecificType(objectUri);
|
||||||
|
//If more than one most specific type, will compare against both of them
|
||||||
|
//and if the first one matches, the object will be placed under that
|
||||||
|
//otherwise subclass will be checked against the other
|
||||||
for (Map<String, String> innerMap : statementData) {
|
for (Map<String, String> innerMap : statementData) {
|
||||||
|
//Check both the object uri and that the subclass returned matches
|
||||||
|
//the most specific type
|
||||||
if (innerMap.get(objectVariableName) == objectUri) {
|
if (innerMap.get(objectVariableName) == objectUri) {
|
||||||
dataForThisObject.add(innerMap);
|
//At this point, the statement data will already have the most specific type
|
||||||
|
//represented
|
||||||
|
String subclass = innerMap.get(SUBCLASS_VARIABLE_NAME);
|
||||||
|
if(mostSpecificTypes.contains(subclass)) {
|
||||||
|
filteredList.add(innerMap);
|
||||||
|
filteredObjects.add(objectUri);
|
||||||
|
} else {
|
||||||
|
if(log.isDebugEnabled()) {
|
||||||
|
log.debug("Iterating through statement data, Subclass does not match most specific type for Object URI - " + objectUri + " - subclass:" + subclass + " - most specific types=" + mostSpecificTypes.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
statementData.retainAll(filteredList);
|
statementData.retainAll(filteredList);
|
||||||
|
@ -161,67 +179,35 @@ public class CollatedObjectPropertyTemplateModel extends
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Data after subclass filtering");
|
log.debug("Data after subclass filtering");
|
||||||
logData(statementData);
|
logData(statementData);
|
||||||
|
//check and see if filteredObjects and processedObjects not the same size
|
||||||
|
if(filteredObjects.size() < processedObjects.size()) {
|
||||||
|
log.debug("Certain objects not included in statements displayed for collated subclasses");
|
||||||
|
processedObjects.removeAll(filteredObjects);
|
||||||
|
log.debug("These object uris not represented" + processedObjects.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DataComparatorBySubclass implements
|
//Get the most specific type
|
||||||
Comparator<Map<String, String>> {
|
//An alternative would be to ensure that the default form, or any form that utilizes collation
|
||||||
|
//will return most specific type within the listview select/construct queries so the resulting
|
||||||
@Override
|
//statement data has that value
|
||||||
public int compare(Map<String, String> map1, Map<String, String> map2) {
|
List<String> getMostSpecificTypesForObject(String objectURI) {
|
||||||
|
WebappDaoFactory wadf = ModelAccess.on(vreq).getWebappDaoFactory();
|
||||||
String subclass1 = map1.get(SUBCLASS_VARIABLE_NAME);
|
return wadf.getIndividualDao().getIndividualByURI(objectURI).getMostSpecificTypeURIs();
|
||||||
String subclass2 = map2.get(SUBCLASS_VARIABLE_NAME);
|
|
||||||
|
|
||||||
if (subclass1 == null) {
|
|
||||||
if (subclass2 == null) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return 1; // nulls rank highest
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subclass2 == null) {
|
|
||||||
return -1; // nulls rank highest
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, " | ");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This will return a single most specific type for an object
|
||||||
|
//If there are multiple most specific types, the list will be sorted alphabetically and
|
||||||
|
//the first one will be returned
|
||||||
|
List<String> getSortedMostSpecificType(String objectURI) {
|
||||||
|
List<String> mostSpecificTypeURIs = this.getMostSpecificTypesForObject(objectURI);
|
||||||
|
Collections.sort(mostSpecificTypeURIs);
|
||||||
|
return mostSpecificTypeURIs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Collate the statements by subclass.
|
// Collate the statements by subclass.
|
||||||
private List<SubclassTemplateModel> collate(String subjectUri,
|
private List<SubclassTemplateModel> collate(String subjectUri,
|
||||||
ObjectProperty property, List<Map<String, String>> statementData,
|
ObjectProperty property, List<Map<String, String>> statementData,
|
||||||
|
|
Loading…
Add table
Reference in a new issue