NIHVIVO-1341 Preprocessing of object property data for list views
This commit is contained in:
parent
d2d91dfe77
commit
7d23fcab5a
10 changed files with 131 additions and 89 deletions
|
@ -0,0 +1,68 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
|
||||||
|
public class BaseObjectPropertyDataPreprocessor implements
|
||||||
|
ObjectPropertyDataPreprocessor {
|
||||||
|
|
||||||
|
protected ObjectPropertyTemplateModel objectPropertyTemplateModel;
|
||||||
|
protected WebappDaoFactory wdf;
|
||||||
|
|
||||||
|
public BaseObjectPropertyDataPreprocessor(ObjectPropertyTemplateModel optm, WebappDaoFactory wdf) {
|
||||||
|
this.objectPropertyTemplateModel = optm;
|
||||||
|
this.wdf = wdf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(List<Map<String, String>> data) {
|
||||||
|
for (Map<String, String> map : data) {
|
||||||
|
applyStandardPreprocessing(map);
|
||||||
|
applySpecificPreprocessing(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Standard preprocessing that applies to all views. */
|
||||||
|
protected void applyStandardPreprocessing(Map<String, String> map) {
|
||||||
|
addLinkForTarget(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void applySpecificPreprocessing(Map<String, String> map) {
|
||||||
|
/* Base class method is empty because this method is defined
|
||||||
|
* to apply subclass preprocessing.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLinkForTarget(Map<String, String> map) {
|
||||||
|
String linkTarget = objectPropertyTemplateModel.getLinkTarget();
|
||||||
|
String targetUri = map.get(linkTarget);
|
||||||
|
if (targetUri != null) {
|
||||||
|
String targetUrl = getLink(targetUri);
|
||||||
|
map.put(linkTarget + "Url", targetUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Preprocessor helper methods callable from any preprocessor */
|
||||||
|
|
||||||
|
protected String getLink(String uri) {
|
||||||
|
return UrlBuilder.getIndividualProfileUrl(uri, wdf);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMoniker(String uri) {
|
||||||
|
return getIndividual(uri).getMoniker();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getName(String uri) {
|
||||||
|
return getIndividual(uri).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Individual getIndividual(String uri) {
|
||||||
|
return wdf.getIndividualDao().getIndividualByURI(uri);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
|
||||||
|
public class DefaultObjectPropertyDataPreprocessor extends
|
||||||
|
BaseObjectPropertyDataPreprocessor {
|
||||||
|
|
||||||
|
public DefaultObjectPropertyDataPreprocessor(ObjectPropertyTemplateModel optm, WebappDaoFactory wdf) {
|
||||||
|
super(optm, wdf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
/* Apply preprocessing specific to this preprocessor */
|
||||||
|
protected void applySpecificPreprocessing(Map<String, String> map) {
|
||||||
|
addName(map);
|
||||||
|
addMoniker(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addName(Map<String, String> map) {
|
||||||
|
String name = map.get("name");
|
||||||
|
if (name == null) {
|
||||||
|
map.put("name", getName(map.get("object")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMoniker(Map<String, String> map) {
|
||||||
|
String moniker = map.get("moniker");
|
||||||
|
if (moniker == null) {
|
||||||
|
map.put("moniker", getMoniker(map.get("object")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.preprocessors;
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -15,6 +15,6 @@ import java.util.Map;
|
||||||
|
|
||||||
public interface ObjectPropertyDataPreprocessor {
|
public interface ObjectPropertyDataPreprocessor {
|
||||||
|
|
||||||
public void preprocess(List<Map<String, String>> data);
|
public void process(List<Map<String, String>> data);
|
||||||
|
|
||||||
}
|
}
|
|
@ -27,44 +27,6 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a hopefully temporary solution to account for the fact that in the default
|
|
||||||
* 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
|
|
||||||
* function: PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#>
|
|
||||||
* 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, 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).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Access methods for templates */
|
/* Access methods for templates */
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -17,7 +18,6 @@ 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.controller.freemarker.UrlBuilder;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
|
||||||
|
@ -25,6 +25,12 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ObjectPropertyTemplateModel.class);
|
private static final Log log = LogFactory.getLog(ObjectPropertyTemplateModel.class);
|
||||||
private static final String TYPE = "object";
|
private static final String TYPE = "object";
|
||||||
|
/* NB The default preprocessor is not the same as the preprocessor for the default view. The latter
|
||||||
|
* actually defines its own preprocessor, whereas the default preprocessor is used for custom views
|
||||||
|
* that don't define a preprocessor.
|
||||||
|
*/
|
||||||
|
private static final String DEFAULT_PREPROCESSOR =
|
||||||
|
"edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.BaseObjectPropertyDataPreprocessor";
|
||||||
|
|
||||||
private PropertyListConfig config;
|
private PropertyListConfig config;
|
||||||
|
|
||||||
|
@ -66,21 +72,21 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Applies preprocessing to query results to prepare for template */
|
/** Apply preprocessing to query results to prepare for template */
|
||||||
protected void preprocess(List<Map<String, String>> data, WebappDaoFactory wdf) {
|
protected void preprocess(List<Map<String, String>> data, WebappDaoFactory wdf) {
|
||||||
/* First apply standard post-processing for all object properties */
|
String preprocessorName = config.preprocessor;
|
||||||
|
if (preprocessorName == null) {
|
||||||
// Add urls for link targets to the data
|
preprocessorName = DEFAULT_PREPROCESSOR;
|
||||||
String linkTarget = config.linkTarget;
|
|
||||||
for (Map<String, String> map : data) {
|
|
||||||
String targetUri = map.get(linkTarget);
|
|
||||||
if (targetUri != null) {
|
|
||||||
String targetUrl = UrlBuilder.getIndividualProfileUrl(targetUri, wdf);
|
|
||||||
map.put(linkTarget + "Url", targetUrl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then apply custom post-processing specified in config */
|
try {
|
||||||
|
Class<?> preprocessorClass = Class.forName(preprocessorName);
|
||||||
|
Constructor<?> constructor = preprocessorClass.getConstructor(ObjectPropertyTemplateModel.class, WebappDaoFactory.class);
|
||||||
|
ObjectPropertyDataPreprocessor preprocessor = (ObjectPropertyDataPreprocessor) constructor.newInstance(this, wdf);
|
||||||
|
preprocessor.process(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PropertyListConfig {
|
private class PropertyListConfig {
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.preprocessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class BaseObjectPropertyDataPreprocessor implements
|
|
||||||
ObjectPropertyDataPreprocessor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void preprocess(List<Map<String, String>> data);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.preprocessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class DefaultObjectPropertyDataPreprocessor extends
|
|
||||||
BaseObjectPropertyDataPreprocessor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preprocess(List<Map<String, String>> data) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<link-target>object</link-target>
|
<link-target>object</link-target>
|
||||||
|
|
||||||
<preprocessor></preprocessor>
|
<preprocessor>edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DefaultObjectPropertyDataPreprocessor</preprocessor>
|
||||||
|
|
||||||
<template>shortView-default.ftl</template>
|
<template>shortView-default.ftl</template>
|
||||||
</view-config>
|
</view-config>
|
|
@ -35,7 +35,7 @@
|
||||||
<#-- data property -->
|
<#-- data property -->
|
||||||
<#if property.type == "data">
|
<#if property.type == "data">
|
||||||
<#list property.statements as statement>
|
<#list property.statements as statement>
|
||||||
<p class="data-property-statement">${statement.value}</p>
|
<li role="listitem">${statement.value}</li>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
<#-- object property -->
|
<#-- object property -->
|
||||||
|
@ -45,8 +45,7 @@
|
||||||
<#include "objectPropertyList-statements.ftl">
|
<#include "objectPropertyList-statements.ftl">
|
||||||
</#if>
|
</#if>
|
||||||
</ul>
|
</ul>
|
||||||
</article>
|
</article> <!-- end property -->
|
||||||
|
|
||||||
</#list>
|
</#list>
|
||||||
</section>
|
</section> <!-- end property-group -->
|
||||||
</#list>
|
</#list>
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
<#-- Default object property statement short view template -->
|
<#-- Default object property statement short view template -->
|
||||||
|
|
||||||
<a href="${statement.objectUrl}">${statement.name!"object name here"}</a> ${statement.moniker!"moniker here"}
|
<a href="${statement.objectUrl}">${statement.name!}</a> ${statement.moniker!}
|
||||||
|
|
Loading…
Add table
Reference in a new issue