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