NIHVIVO-1510 Temporarily display collated properties as uncollated, until collated view is implemented.

This commit is contained in:
rjy7 2010-12-13 20:03:06 +00:00
parent efc48a3054
commit 91f96a2304
8 changed files with 95 additions and 42 deletions

View file

@ -89,4 +89,12 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec
return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, query); return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, query);
} }
// @Override
// // RY What about filtering?
// public Map<String, List<Map<String, Object>>> getCollatedObjectPropertyStatementsForIndividual(
// String subjectUri, String propertyUri, String query) {
// return innerObjectPropertyStatementDao.getCollatedObjectPropertyStatementsForIndividual(subjectUri, propertyUri, query);
// }
} }

View file

@ -2,37 +2,54 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.ArrayList; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel { public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
private static final Log log = LogFactory.getLog(CollatedObjectPropertyTemplateModel.class); private static final Log log = LogFactory.getLog(CollatedObjectPropertyTemplateModel.class);
private List<SubclassList> subclassList; private Map<String, List<ObjectPropertyStatementTemplateModel>> collatedStatements;
//private List<SubclassList> subclassList;
CollatedObjectPropertyTemplateModel(ObjectProperty property, Individual subject, WebappDaoFactory wdf) { CollatedObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) {
super(property, subject, wdf); super(op, subject, wdf);
subclassList = new ArrayList<SubclassList>(); ObjectPropertyStatementDao opDao = wdf.getObjectPropertyStatementDao();
String subjectUri = subject.getURI();
String propertyUri = op.getURI();
List<Map<String, Object>> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
collatedStatements = new HashMap<String, List<ObjectPropertyStatementTemplateModel>>(statementData.size());
// for (Map<String, Object> map : statementData) {
// statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map, wdf));
// }
if (statementData.size() > 0) {
String collationTarget = getCollationTarget();
List<VClass> vclasses = getDirectVClasses(collationTarget, statementData);
}
} }
public List<SubclassList> getSubclassList() { private List<VClass> getDirectVClasses(String key, List<Map<String, Object>> data) {
return subclassList; return null;
} }
// public List<SubclassList> getStatements() {
// return subclassList;
// }
/* Access methods for templates */ /* Access methods for templates */
public Map<String, List<ObjectPropertyStatementTemplateModel>> getCollatedStatements() {
return collatedStatements;
}
@Override @Override
public boolean isCollatedBySubclass() { public boolean isCollatedBySubclass() {
return true; return true;

View file

@ -27,7 +27,7 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
this.propertyUri = propertyUri; this.propertyUri = propertyUri;
this.wdf = wdf; this.wdf = wdf;
this.data = new HashMap<String, Object>(data.size()); this.data = new HashMap<String, Object>(data.size());
// See comments above StatementIndividual class definition on why we don't just set this.data = data. // See comments above the StatementObject class definition on why we don't just set this.data = data.
for (String key : data.keySet()) { for (String key : data.keySet()) {
Object value = data.get(key); Object value = data.get(key);
if (value instanceof Individual) { if (value instanceof Individual) {
@ -40,9 +40,11 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
} }
/* This is a hopefully temporary solution to account for the fact that in the default /* This is a hopefully temporary solution to account for the fact that in the default
* object property list view we are displaying the object's name and moniker. These * object property list view we display the object's name and moniker, and these
* cannot be derived from a simple sparql query. The name is either the label, localName, or id, * cannot be derived from a simple sparql query.
* because context nodes do not have labels. But in general we do not want to display context nodes *
* The name is either the label, localName, or id, because context nodes do not have labels
* (and blank nodes do not have local names?). But in general we do not want to display context nodes
* in the property list view; we are only displaying them temporarily until custom list views * in the property list view; we are only displaying them temporarily until custom list views
* are implemented. In general any object that we want to display in a custom view should have a label, * are implemented. In general any object that we want to display in a custom view should have a label,
* and we can get that directly from the sparql query. Note that we can get the localName using an ARQ * and we can get that directly from the sparql query. Note that we can get the localName using an ARQ
@ -50,16 +52,28 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
* SELECT ?object (afn:localname(?object) AS ?localName) ... * SELECT ?object (afn:localname(?object) AS ?localName) ...
* but it is harder (or impossible) to do what the individual.getName() function does in a SPARQL query. * but it is harder (or impossible) to do what the individual.getName() function does in a SPARQL query.
* *
* In the case of moniker, the Individual.getMoniker() * In the case of moniker, the Individual.getMoniker() returns the VClass if moniker is null.
* returns the VClass if moniker is null. But moniker is a vitro namespace property which will be * But moniker is a vitro namespace property which will be eliminated in a future version,
* eliminated in a future version, and the get-vclass-if-no-moniker logic should be moved into the * and the get-vclass-if-no-moniker logic should be moved into the display modules where it belongs.
* display modules where it belongs. In general any information that we would want to display in the custom * In general any information that we would want to display in the custom list view should be obtained
* list view should be obtained directly in the sparql query. * directly in the sparql query, and that should be generally true for custom queries and views.
*
* We could instead make these methods of the outer class that take a uri parameter, but then the template
* semantics is less intuitive: we would have ${statement.moniker(object)} rather than
* ${statement.object.name}, but the moniker is not a property of the statement.
* *
* We don't want to put an Individual into the template model, because the beans wrapper used in IndividualController * We don't want to put an Individual into the template model, because the beans wrapper used in IndividualController
* has exposure level EXPOSE_SAFE, due to the need to call methods with parameters rather than simple parameterless * has exposure level EXPOSE_SAFE, due to the need to call methods with parameters rather than simple parameterless
* getters. We don't want to expose the Individual's setters to the template, so we wrap it in an individual that * getters. We don't want to expose the Individual's setters to the template, so we wrap it in an individual that
* only has getters. * only has getters.
*
* RY *** Consider doing this only for the default query. The custom query can just store the data values as strings
* (uri, label, etc.). There should be no issues with label and moniker in a custom query (but is that true, or do
* some custom queries display the moniker?), and to handle url we can create a directive <@profileUrl individual=object />
* where object is the object uri. This will get the WebappDaoFactory from the request and call
* UrlBuilder.getIndividualProfileUrl(String individualUri, WebappDaoFactory wdf). Equivalently, have a method of this
* object getProfileUrl(String uri), so in the template we call ${statement.profileUrl(object)} (but still the semantics
* is a bit weird, since the profile url doesn't belong to the statement).
*/ */
public class StatementObject { public class StatementObject {
@ -69,6 +83,8 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
this.individual = individual; this.individual = individual;
} }
/* Access methods for templates */
public String getName() { public String getName() {
return individual.getName(); return individual.getName();
} }
@ -89,13 +105,6 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
return data.get(key); return data.get(key);
} }
// public IndividualTemplateModel getIndividual(String key) {
// IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
// Individual individual = iDao.getIndividualByURI(data.get(key));
// return new IndividualTemplateModel(individual, vreq);
// }
public String getEditLink() { public String getEditLink() {
return null; return null;
} }

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
@ -16,6 +17,7 @@ import org.w3c.dom.NodeList;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel { public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel {
@ -35,10 +37,16 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
protected String getQueryString() { protected String getQueryString() {
return config.queryString; return config.queryString;
} }
protected String getCollationTarget() {
return config.collationTarget;
}
protected static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) { protected static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) {
return op.getCollateBySubclass() ? new CollatedObjectPropertyTemplateModel(op, subject, wdf) // Temporarily comment out, since collation not working. Display as uncollated for now.
: new UncollatedObjectPropertyTemplateModel(op, subject, wdf); // return op.getCollateBySubclass() ? new CollatedObjectPropertyTemplateModel(op, subject, wdf)
// : new UncollatedObjectPropertyTemplateModel(op, subject, wdf);
return new UncollatedObjectPropertyTemplateModel(op, subject, wdf);
} }
private class PropertyListConfig { private class PropertyListConfig {
@ -47,9 +55,11 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
private static final String CONFIG_FILE_PATH = "/views/"; private static final String CONFIG_FILE_PATH = "/views/";
private static final String NODE_NAME_QUERY = "query"; private static final String NODE_NAME_QUERY = "query";
private static final String NODE_NAME_TEMPLATE = "template"; private static final String NODE_NAME_TEMPLATE = "template";
private static final String NODE_NAME_COLLATION_TARGET = "collation-target";
private String queryString; private String queryString;
private String templateName; private String templateName;
private String collationTarget;
PropertyListConfig(ObjectProperty op) { PropertyListConfig(ObjectProperty op) {
String filename = DEFAULT_CONFIG_FILE;; String filename = DEFAULT_CONFIG_FILE;;
@ -60,19 +70,20 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
String configFilename = getConfigFilename(filename); String configFilename = getConfigFilename(filename);
try { try {
File config = new File(configFilename); File config = new File(configFilename);
if (configFilename != DEFAULT_CONFIG_FILE && ! config.exists()) { if (configFilename != DEFAULT_CONFIG_FILE && ! config.exists()) {
log.warn("Can't find config file " + configFilename + " for object property " + op.getURI() + "\n" + log.warn("Can't find config file " + configFilename + " for object property " + op.getURI() + "\n" +
". Using default config file instead."); ". Using default config file instead.");
configFilename = getConfigFilename(DEFAULT_CONFIG_FILE); configFilename = getConfigFilename(DEFAULT_CONFIG_FILE);
// Should we test for the existence of the default, and throw an error if it doesn't exist? // Should we test for the existence of the default, and throw an error if it doesn't exist?
} }
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder(); DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(configFilename); Document doc = db.parse(configFilename);
queryString = getConfigValue(doc, NODE_NAME_QUERY); queryString = getConfigValue(doc, NODE_NAME_QUERY);
templateName = getConfigValue(doc, NODE_NAME_TEMPLATE); templateName = getConfigValue(doc, NODE_NAME_TEMPLATE);
collationTarget = getConfigValue(doc, NODE_NAME_COLLATION_TARGET);
} catch (Exception e) { } catch (Exception e) {
log.error("Error processing config file " + configFilename + " for object property " + op.getURI(), e); log.error("Error processing config file " + configFilename + " for object property " + op.getURI(), e);
// What should we do here? // What should we do here?

View file

@ -12,6 +12,8 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
/** List of object property statements for an individual, where the objects belong to a single subclass **/ /** List of object property statements for an individual, where the objects belong to a single subclass **/
// RY ** This can probably be eliminated. It can be a map of subclass name to statements.
public class SubclassList extends BaseTemplateModel { public class SubclassList extends BaseTemplateModel {
private static final Log log = LogFactory.getLog(SubclassList.class); private static final Log log = LogFactory.getLog(SubclassList.class);

View file

@ -2,6 +2,10 @@
<#-- Template for property listing on individual profile page --> <#-- Template for property listing on individual profile page -->
<#-- RY Just a temporary fix to prevent classgroup heading from being pushed to the right edge of the page.
Feel free to redo/remove. -->
<div style="clear: both;" />
<#list propertyGroups as group> <#list propertyGroups as group>
<#-- Get the group name --> <#-- Get the group name -->
@ -40,10 +44,10 @@
</#list> </#list>
<#else> <#-- object property --> <#else> <#-- object property -->
<#if ! property.collatedBySubclass> <#if property.collatedBySubclass>
<#include "${property.template}">
<#else>
<#include "objectPropertyList-collated.ftl"> <#include "objectPropertyList-collated.ftl">
<#else>
<#include "${property.template}">
</#if> </#if>
</#if> </#if>
</div> <!-- end property --> </div> <!-- end property -->

View file

@ -135,4 +135,4 @@ ${headScripts.add("/js/jquery_plugins/getUrlParam.js",
"http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D", "http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D",
"/js/toggle.js")} "/js/toggle.js")}
${scripts.add("/js/imageUpload/imageUploadUtils.js")} ${scripts.add("/js/imageUpload/imageUploadUtils.js")}

View file

@ -7,5 +7,7 @@
} }
</query> </query>
<collation-target>object</collation-target>
<template>objectPropertyList-default.ftl</template> <template>objectPropertyList-default.ftl</template>
</view-config> </view-config>