diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseObjectPropertyDataPostProcessor.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseObjectPropertyDataPostProcessor.java index a9e6c2ae7..3ef869c00 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseObjectPropertyDataPostProcessor.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseObjectPropertyDataPostProcessor.java @@ -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 foundObjects = new ArrayList(); - for (Map map : data) { + log.debug("Processing property: " + objectPropertyTemplateModel.getUri()); + Iterator> dataIterator = data.iterator(); + while (dataIterator.hasNext()) { + Map 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); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java index 88635337d..7da7f8c7b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java @@ -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> 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> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString()); + List> statementData = + opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString()); + + /* Apply postprocessing */ + postprocess(statementData, wdf); - Map> unsortedSubclasses = hasDefaultListView() ? - collateDefaultListView(subjectUri, propertyUri, statementData, vreq) : - collateCustomListView(subjectUri, propertyUri, statementData, vreq); + /* Collate the data */ + Map> unsortedSubclasses = + collate(subjectUri, propertyUri, statementData, vreq); /* Sort by subclass name */ Comparator comparer = new Comparator() { @@ -67,10 +58,10 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM subclasses.putAll(unsortedSubclasses); } - private Map> collateCustomListView(String subjectUri, + private Map> collate(String subjectUri, String propertyUri, List> statementData, VitroRequest vreq) { - Map> unsortedSubclasses = + Map> subclassMap = new HashMap>(); String currentSubclassUri = null; List currentList = null; @@ -80,19 +71,11 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM currentSubclassUri = subclassUri; currentList = new ArrayList(); String subclassName = getSubclassName(subclassUri, vreq); - unsortedSubclasses.put(subclassName, currentList); + subclassMap.put(subclassName, currentList); } currentList.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map)); } - return unsortedSubclasses; - } - - private Map> collateDefaultListView(String subjectUri, - String propertyUri, List> statementData, VitroRequest vreq) { - - Map> unsortedSubclasses = - new HashMap>(); - 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 getDirectVClasses(String key, List> data) { - return null; - } + @Override + protected String getDefaultConfigFileName() { + return DEFAULT_CONFIG_FILE; + } + /* Access methods for templates */ public Map> getSubclasses() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index a90d9e264..39dcc0d39 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -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); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java index 70df1490f..22e1ff685 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java @@ -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 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> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString()); + + /* Apply postprocessing */ postprocess(statementData, wdf); + + /* Put into data structure to send to template */ statements = new ArrayList(statementData.size()); for (Map map : statementData) { statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map)); } } + @Override + protected String getDefaultConfigFileName() { + return DEFAULT_CONFIG_FILE; + } + /* Access methods for templates */ public List getStatements() { diff --git a/webapp/web/config/listViewConfig-default-collated.xml b/webapp/web/config/listViewConfig-default-collated.xml new file mode 100644 index 000000000..fb3c446d2 --- /dev/null +++ b/webapp/web/config/listViewConfig-default-collated.xml @@ -0,0 +1,43 @@ + + + + + + + + PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + + SELECT ?subclass ?object ?name ?moniker { + GRAPH ?g1 { ?subject ?property ?object } + OPTIONAL { GRAPH ?g2 { ?object rdfs:label ?name } } + OPTIONAL { GRAPH ?g3 { ?object vitro:moniker ?moniker } } + OPTIONAL { GRAPH ?g4 { ?object a ?subclass } + FILTER (?g4 != <http://vitro.mannlib.cornell.edu/default/inferred-tbox> && + ?g4 != <http://vitro.mannlib.cornell.edu/default/vitro-kb-inf> ) + } + } + + + edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DefaultListViewDataPostProcessor + + + diff --git a/webapp/web/config/listViewConfig-default.xml b/webapp/web/config/listViewConfig-default-uncollated.xml similarity index 95% rename from webapp/web/config/listViewConfig-default.xml rename to webapp/web/config/listViewConfig-default-uncollated.xml index bd3b30c25..c04fbd9c3 100644 --- a/webapp/web/config/listViewConfig-default.xml +++ b/webapp/web/config/listViewConfig-default-uncollated.xml @@ -1,7 +1,9 @@ -