From f398183c94a670b14f7656fc14979274d8240d9e Mon Sep 17 00:00:00 2001 From: ryounes Date: Mon, 21 Mar 2011 22:24:33 +0000 Subject: [PATCH] NIHVIVO-2186 Modify custom list view queries to filter out statements with no linked individual when user is not editing the page. Involves pruning the grouped property list of properties and groups which are thereby empty. --- .../CollatedObjectPropertyTemplateModel.java | 5 +++ .../individual/GroupedPropertyList.java | 44 +++++++++++++++++-- .../ObjectPropertyTemplateModel.java | 28 ++++++------ .../PropertyGroupTemplateModel.java | 4 ++ ...UncollatedObjectPropertyTemplateModel.java | 5 +++ webapp/web/config/listViewConfig-default.xml | 8 ++-- 6 files changed, 73 insertions(+), 21 deletions(-) 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 65816cfcc..9add632c4 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 @@ -82,6 +82,11 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM } } + @Override + protected boolean isEmpty() { + return subclasses.isEmpty(); + } + protected ConfigError checkQuery(String queryString) { if (StringUtils.isBlank(queryString)) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index 3351c2e03..bee727cd6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; @@ -100,9 +101,40 @@ public class GroupedPropertyList extends BaseTemplateModel { for (PropertyGroup propertyGroup: propertyGroupList) { groups.add(new PropertyGroupTemplateModel(vreq, propertyGroup, subject, policyHelper, populatedDataPropertyList, populatedObjectPropertyList)); - } + } + + if (!editing) { + pruneEmptyProperties(); + } } + + // It's possible that a collated object property retrieved in the call to getPopulatedObjectPropertyList() + // is now empty of statements, because if not editing, some statements without a linked individual + // are not retrieved by the query. (See elements in queries.) + // Remove these properties, and also remove any groups with no remaining properties. + private void pruneEmptyProperties() { + Iterator iGroups = groups.iterator(); + while (iGroups.hasNext()) { + PropertyGroupTemplateModel pgtm = iGroups.next(); + Iterator iProperties = pgtm.getProperties().iterator(); + while (iProperties.hasNext()) { + PropertyTemplateModel property = iProperties.next(); + if (property instanceof ObjectPropertyTemplateModel) { + // It's not necessary to do comparable pruning of the subclass list + // of a CollatedObjectPropertyTemplateModel, because the collated subclass + // list is compiled on the basis of existing statements. There will not + // be any empty subclasses. + if ( ( (ObjectPropertyTemplateModel) property).isEmpty() ) { + iProperties.remove(); + } + } + } + if (pgtm.isEmpty()) { + iGroups.remove(); + } + } + } @SuppressWarnings("unchecked") protected void sort(List propertyList) { @@ -417,14 +449,18 @@ public class GroupedPropertyList extends BaseTemplateModel { } public PropertyTemplateModel getPropertyAndRemoveFromList(String propertyUri) { - + for (PropertyGroupTemplateModel pgtm : groups) { List properties = pgtm.getProperties(); for (PropertyTemplateModel ptm : properties) { if (propertyUri.equals(ptm.getUri())) { - // Remove the property from the group + // Remove the property from the group. + // NB Works with a for-each loop instead of an iterator, since + // iteration doesn't continue after the remove. properties.remove(ptm); - // If this is the only property in the group, remove the group as well + // If this is the only property in the group, remove the group as well. + // NB Works with a for-each loop instead of an iterator, since + // iteration doesn't continue after the remove. if (properties.size() == 0) { groups.remove(pgtm); } 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 29a7365fa..844eafcd3 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 @@ -118,6 +118,8 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel } } + protected abstract boolean isEmpty(); + @Override protected int getPropertyDisplayTier(Property p) { // For some reason ObjectProperty.getDomainDisplayTier() returns a String @@ -324,8 +326,8 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel private static final String NODE_NAME_QUERY_SELECT = "query-select"; private static final String NODE_NAME_TEMPLATE = "template"; private static final String NODE_NAME_POSTPROCESSOR = "postprocessor"; - private static final String NODE_NAME_COLLATION_FRAGMENT = "collation-fragment"; - private static final String NODE_NAME_LINKED_INDIVIDUAL_OPTIONAL = "linked-individual-optional"; + private static final String NODE_NAME_COLLATED = "collated"; + private static final String NODE_NAME_LINKED_INDIVIDUAL_REQUIRED = "linked-individual-required"; /* NB The default post-processor is not the same as the post-processor for the default view. The latter * actually defines its own post-processor, whereas the default post-processor is used for custom views @@ -463,27 +465,27 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel Node selectQueryNode = doc.getElementsByTagName(NODE_NAME_QUERY_SELECT).item(0); String value = null; if (selectQueryNode != null) { - boolean removeCollationFragments = ObjectPropertyTemplateModel.this instanceof UncollatedObjectPropertyTemplateModel; - /* If editing the page (policyHelper != null), show statements with missing linked individual; otherwise, hide these + boolean collated = ObjectPropertyTemplateModel.this instanceof CollatedObjectPropertyTemplateModel; + /* If not editing the page (policyHelper == null), hide statements with missing linked individual; otherwise, show these * statements. We might want to refine this based on whether the user can edit the statement in question, but that - * would require a completely different approach: including the statement in the query results, and then during the - * postprocessing phase, checking the editing policy, and removing the statement if it's not editable. We would not + * would require a completely different approach: include the statement in the query results, and then during the + * postprocessing phase, check the editing policy, and remove the statement if it's not editable. We would not * preprocess the query, as here. */ - boolean linkedIndividualOptional = policyHelper != null; + boolean linkedIndividualRequired = policyHelper == null; NodeList children = selectQueryNode.getChildNodes(); int childCount = children.getLength(); value = ""; for (int i = 0; i < childCount; i++) { Node node = children.item(i); - if (node.getNodeName().equals(NODE_NAME_COLLATION_FRAGMENT)) { - if (!removeCollationFragments) { + if (node.getNodeName().equals(NODE_NAME_COLLATED)) { + if (collated) { value += node.getChildNodes().item(0).getNodeValue(); - } - } else if (node.getNodeName().equals(NODE_NAME_LINKED_INDIVIDUAL_OPTIONAL)) { - if (linkedIndividualOptional) { + } // else ignore this node + } else if (node.getNodeName().equals(NODE_NAME_LINKED_INDIVIDUAL_REQUIRED)) { + if (linkedIndividualRequired) { value += node.getChildNodes().item(0).getNodeValue(); - } + } // else ignore this node } else { value += node.getNodeValue(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java index 1b5be6252..546922516 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java @@ -40,6 +40,10 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel { } } } + + protected boolean isEmpty() { + return properties.isEmpty(); + } protected void remove(PropertyTemplateModel ptm) { properties.remove(ptm); 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 4e72ca0a6..2966a8049 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 @@ -55,6 +55,11 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat } } + @Override + protected boolean isEmpty() { + return statements.isEmpty(); + } + /* Access methods for templates */ public List getStatements() { diff --git a/webapp/web/config/listViewConfig-default.xml b/webapp/web/config/listViewConfig-default.xml index a44605743..57e809402 100644 --- a/webapp/web/config/listViewConfig-default.xml +++ b/webapp/web/config/listViewConfig-default.xml @@ -11,15 +11,15 @@ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#> - SELECT ?subclass + SELECT ?subclass ?object ?name ?moniker WHERE { ?subject ?property ?object - OPTIONAL { ?object a ?subclass } + OPTIONAL { ?object a ?subclass } FILTER ( afn:namespace(?subclass) != "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#" ) - + OPTIONAL { ?object rdfs:label ?name } OPTIONAL { ?object vitro:moniker ?moniker } - } ORDER BY ?subclass ?name ?object + } ORDER BY ?subclass ?name ?object