NIHVIVO-1510 Collation of properties using default list view. NIHVIVO-1569 Fixed a bug in BaseObjectPropertyDataPostProcessor.removeDuplicates()

This commit is contained in:
rjy7 2011-01-05 19:48:50 +00:00
parent 587e83f6b1
commit 25a818efa9
6 changed files with 90 additions and 70 deletions

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@ -58,11 +59,14 @@ public abstract class BaseObjectPropertyDataPostProcessor implements
return;
}
List<String> foundObjects = new ArrayList<String>();
for (Map<String, String> map : data) {
log.debug("Processing property: " + objectPropertyTemplateModel.getUri());
Iterator<Map<String, String>> dataIterator = data.iterator();
while (dataIterator.hasNext()) {
Map<String, String> map = dataIterator.next();
String objectValue = map.get(objectVariableName);
// We arbitrarily remove all but the first. Not sure what selection criteria could be brought to bear on this.
if (foundObjects.contains(objectValue)) {
data.remove(map);
dataIterator.remove();
} else {
foundObjects.add(objectValue);
}

View file

@ -26,36 +26,27 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
private static final Log log = LogFactory.getLog(CollatedObjectPropertyTemplateModel.class);
private static final String DEFAULT_CONFIG_FILE = "listViewConfig-default-collated.xml";
private SortedMap<String, List<ObjectPropertyStatementTemplateModel>> subclasses;
CollatedObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq) throws Exception {
super(op, subject, vreq);
// RY Temporarily throw an error because collation hasn't been implemented yet.
// boolean error = true;
// if (error) {
// throw new Exception("Collated object property not implemented yet");
// }
/* Change the approach to collation:
* Custom views can get the subclasses in the query. Must use a term ?subclass - throw error if not.
* Default view: we may be able to figure out the class to get subclasses of by inspecting the property.
* If not, use getDirectClasses etc of the object term.
* We need a subclassed and nonsubclassed default query for the default view: collated-query and uncollated-query.
* We can also use these for custom views. Throw error if property is collated but there's no subclass term
* in the query. (The reverse is okay - uncollated property with a subclass term in the query.
*/
/* Get the data */
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
ObjectPropertyStatementDao opDao = wdf.getObjectPropertyStatementDao();
String subjectUri = subject.getURI();
String propertyUri = op.getURI();
List<Map<String, String>> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
List<Map<String, String>> statementData =
opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
/* Apply postprocessing */
postprocess(statementData, wdf);
Map<String, List<ObjectPropertyStatementTemplateModel>> unsortedSubclasses = hasDefaultListView() ?
collateDefaultListView(subjectUri, propertyUri, statementData, vreq) :
collateCustomListView(subjectUri, propertyUri, statementData, vreq);
/* Collate the data */
Map<String, List<ObjectPropertyStatementTemplateModel>> unsortedSubclasses =
collate(subjectUri, propertyUri, statementData, vreq);
/* Sort by subclass name */
Comparator<String> comparer = new Comparator<String>() {
@ -67,10 +58,10 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
subclasses.putAll(unsortedSubclasses);
}
private Map<String, List<ObjectPropertyStatementTemplateModel>> collateCustomListView(String subjectUri,
private Map<String, List<ObjectPropertyStatementTemplateModel>> collate(String subjectUri,
String propertyUri, List<Map<String, String>> statementData, VitroRequest vreq) {
Map<String, List<ObjectPropertyStatementTemplateModel>> unsortedSubclasses =
Map<String, List<ObjectPropertyStatementTemplateModel>> subclassMap =
new HashMap<String, List<ObjectPropertyStatementTemplateModel>>();
String currentSubclassUri = null;
List<ObjectPropertyStatementTemplateModel> currentList = null;
@ -80,19 +71,11 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
currentSubclassUri = subclassUri;
currentList = new ArrayList<ObjectPropertyStatementTemplateModel>();
String subclassName = getSubclassName(subclassUri, vreq);
unsortedSubclasses.put(subclassName, currentList);
subclassMap.put(subclassName, currentList);
}
currentList.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map));
}
return unsortedSubclasses;
}
private Map<String, List<ObjectPropertyStatementTemplateModel>> collateDefaultListView(String subjectUri,
String propertyUri, List<Map<String, String>> statementData, VitroRequest vreq) {
Map<String, List<ObjectPropertyStatementTemplateModel>> unsortedSubclasses =
new HashMap<String, List<ObjectPropertyStatementTemplateModel>>();
return unsortedSubclasses;
return subclassMap;
}
private String getSubclassName(String subclassUri, VitroRequest vreq) {
@ -100,30 +83,12 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
VClass vclass = vclassDao.getVClassByURI(subclassUri);
return vclass.getName();
}
private String getCollationTargetError() {
String errorMessage = null;
String collationTarget = getCollationTarget();
// Make sure the collation target is not null or empty.
if (collationTarget == null || collationTarget.trim().isEmpty()) {
errorMessage = "No collation target specified.";
} else {
// Make sure the collation target is one of the select terms in the query.
String queryString = getQueryString();
String selectClause = queryString.substring(0, queryString.indexOf("{"));
Pattern collationTargetPattern = Pattern.compile("\\b\\\\?" + collationTarget + "\\b");
Matcher matcher = collationTargetPattern.matcher(selectClause);
if (! matcher.find()) {
errorMessage = "Invalid collation target.";
}
}
return errorMessage;
}
private List<VClass> getDirectVClasses(String key, List<Map<String, Object>> data) {
return null;
}
@Override
protected String getDefaultConfigFileName() {
return DEFAULT_CONFIG_FILE;
}
/* Access methods for templates */
public Map<String, List<ObjectPropertyStatementTemplateModel>> getSubclasses() {

View file

@ -55,11 +55,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
protected String getQueryString() {
return config.queryString;
}
protected String getCollationTarget() {
return config.collationTarget;
}
protected boolean hasDefaultListView() {
return config.isDefaultConfig;
}
@ -95,19 +91,18 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
}
}
protected abstract String getDefaultConfigFileName();
private class PropertyListConfig {
private static final String DEFAULT_CONFIG_FILE = "listViewConfig-default.xml";
private static final String CONFIG_FILE_PATH = "/config/";
private static final String NODE_NAME_QUERY = "query";
private static final String NODE_NAME_TEMPLATE = "template";
private static final String NODE_NAME_COLLATION_TARGET = "collation-target";
private static final String NODE_NAME_POSTPROCESSOR = "postprocessor";
private boolean isDefaultConfig;
private String queryString;
private String templateName;
private String collationTarget;
private String postprocessor;
PropertyListConfig(ObjectProperty op, VitroRequest vreq) throws Exception {
@ -117,7 +112,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
ObjectPropertyDao opDao = wdf.getObjectPropertyDao();
String configFileName = opDao.getCustomListConfigFileName(op);
if (configFileName == null) { // no custom config; use default config
configFileName = DEFAULT_CONFIG_FILE;
configFileName = getDefaultConfigFileName();
}
log.debug("Using list view config file " + configFileName + " for object property " + op.getURI());
@ -127,7 +122,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
if ( ! isDefaultConfig(configFileName) && ! config.exists() ) {
log.warn("Can't find config file " + configFilePath + " for object property " + op.getURI() + "\n" +
". Using default config file instead.");
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE);
configFilePath = getConfigFilePath(getDefaultConfigFileName());
// Should we test for the existence of the default, and throw an error if it doesn't exist?
}
setValuesFromConfigFile(configFilePath);
@ -143,7 +138,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
log.warn("Invalid list view config for object property " + op.getURI() +
" in " + configFilePath + ":\n" +
invalidConfigMessage + " Using default config instead.");
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE);
configFilePath = getConfigFilePath(getDefaultConfigFileName());
setValuesFromConfigFile(configFilePath);
}
}
@ -152,7 +147,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
}
private boolean isDefaultConfig(String configFileName) {
return configFileName.equals(DEFAULT_CONFIG_FILE);
return configFileName.equals(getDefaultConfigFileName());
}
private String checkForInvalidConfig(VitroRequest vreq) {
@ -189,7 +184,6 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
templateName = getConfigValue(doc, NODE_NAME_TEMPLATE);
// Optional values
collationTarget = getConfigValue(doc, NODE_NAME_COLLATION_TARGET);
postprocessor = getConfigValue(doc, NODE_NAME_POSTPROCESSOR);
} catch (Exception e) {
log.error("Error processing config file " + configFilePath, e);

View file

@ -18,23 +18,35 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
private static final Log log = LogFactory.getLog(UncollatedObjectPropertyTemplateModel.class);
private static final String DEFAULT_CONFIG_FILE = "listViewConfig-default-uncollated.xml";
private List<ObjectPropertyStatementTemplateModel> statements;
UncollatedObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq) {
super(op, subject, vreq);
/* Get the data */
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
ObjectPropertyStatementDao opDao = wdf.getObjectPropertyStatementDao();
String subjectUri = subject.getURI();
String propertyUri = op.getURI();
List<Map<String, String>> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
/* Apply postprocessing */
postprocess(statementData, wdf);
/* Put into data structure to send to template */
statements = new ArrayList<ObjectPropertyStatementTemplateModel>(statementData.size());
for (Map<String, String> map : statementData) {
statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map));
}
}
@Override
protected String getDefaultConfigFileName() {
return DEFAULT_CONFIG_FILE;
}
/* Access methods for templates */
public List<ObjectPropertyStatementTemplateModel> getStatements() {