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);
}
// @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;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
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;
public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
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) {
super(property, subject, wdf);
subclassList = new ArrayList<SubclassList>();
CollatedObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) {
super(op, subject, wdf);
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() {
return subclassList;
private List<VClass> getDirectVClasses(String key, List<Map<String, Object>> data) {
return null;
}
// public List<SubclassList> getStatements() {
// return subclassList;
// }
/* Access methods for templates */
public Map<String, List<ObjectPropertyStatementTemplateModel>> getCollatedStatements() {
return collatedStatements;
}
@Override
public boolean isCollatedBySubclass() {
return true;

View file

@ -27,7 +27,7 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
this.propertyUri = propertyUri;
this.wdf = wdf;
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()) {
Object value = data.get(key);
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
* object property list view we are displaying the object's name and moniker. These
* cannot be derived from a simple sparql query. The name is either the label, localName, or id,
* because context nodes do not have labels. But in general we do not want to display context nodes
* 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, 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
* 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
@ -50,16 +52,28 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
* 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.
*
* In the case of moniker, the Individual.getMoniker()
* returns the VClass if moniker is null. But moniker is a vitro namespace property which will be
* eliminated in a future version, and the get-vclass-if-no-moniker logic should be moved into the
* display modules where it belongs. In general any information that we would want to display in the custom
* list view should be obtained directly in the sparql query.
* In the case of moniker, the Individual.getMoniker() returns the VClass if moniker is null.
* But moniker is a vitro namespace property which will be eliminated in a future version,
* and the get-vclass-if-no-moniker logic should be moved into the display modules where it belongs.
* In general any information that we would want to display in the custom list view should be obtained
* 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
* 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
* 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 {
@ -69,6 +83,8 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
this.individual = individual;
}
/* Access methods for templates */
public String getName() {
return individual.getName();
}
@ -89,13 +105,6 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
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() {
return null;
}

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.io.File;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
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.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel {
@ -35,10 +37,16 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
protected String getQueryString() {
return config.queryString;
}
protected String getCollationTarget() {
return config.collationTarget;
}
protected static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) {
return op.getCollateBySubclass() ? new CollatedObjectPropertyTemplateModel(op, subject, wdf)
: new UncollatedObjectPropertyTemplateModel(op, subject, wdf);
// Temporarily comment out, since collation not working. Display as uncollated for now.
// return op.getCollateBySubclass() ? new CollatedObjectPropertyTemplateModel(op, subject, wdf)
// : new UncollatedObjectPropertyTemplateModel(op, subject, wdf);
return new UncollatedObjectPropertyTemplateModel(op, subject, wdf);
}
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 NODE_NAME_QUERY = "query";
private static final String NODE_NAME_TEMPLATE = "template";
private static final String NODE_NAME_COLLATION_TARGET = "collation-target";
private String queryString;
private String templateName;
private String collationTarget;
PropertyListConfig(ObjectProperty op) {
String filename = DEFAULT_CONFIG_FILE;;
@ -60,19 +70,20 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
String configFilename = getConfigFilename(filename);
try {
File config = new File(configFilename);
if (configFilename != DEFAULT_CONFIG_FILE && ! config.exists()) {
log.warn("Can't find config file " + configFilename + " for object property " + op.getURI() + "\n" +
". Using default config file instead.");
configFilename = getConfigFilename(DEFAULT_CONFIG_FILE);
// Should we test for the existence of the default, and throw an error if it doesn't exist?
}
File config = new File(configFilename);
if (configFilename != DEFAULT_CONFIG_FILE && ! config.exists()) {
log.warn("Can't find config file " + configFilename + " for object property " + op.getURI() + "\n" +
". Using default config file instead.");
configFilename = getConfigFilename(DEFAULT_CONFIG_FILE);
// 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();
Document doc = db.parse(configFilename);
queryString = getConfigValue(doc, NODE_NAME_QUERY);
templateName = getConfigValue(doc, NODE_NAME_TEMPLATE);
collationTarget = getConfigValue(doc, NODE_NAME_COLLATION_TARGET);
} catch (Exception e) {
log.error("Error processing config file " + configFilename + " for object property " + op.getURI(), e);
// 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 **/
// RY ** This can probably be eliminated. It can be a map of subclass name to statements.
public class SubclassList extends BaseTemplateModel {
private static final Log log = LogFactory.getLog(SubclassList.class);

View file

@ -2,6 +2,10 @@
<#-- 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>
<#-- Get the group name -->
@ -40,10 +44,10 @@
</#list>
<#else> <#-- object property -->
<#if ! property.collatedBySubclass>
<#include "${property.template}">
<#else>
<#if property.collatedBySubclass>
<#include "objectPropertyList-collated.ftl">
<#else>
<#include "${property.template}">
</#if>
</#if>
</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",
"/js/toggle.js")}
${scripts.add("/js/imageUpload/imageUploadUtils.js")}
${scripts.add("/js/imageUpload/imageUploadUtils.js")}

View file

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