NIHVIVO-1341 Implement preprocessing structure to process object property statement query data before sending to template. Reorganize markup in templates to reduce repetition.
This commit is contained in:
parent
dbb07aa152
commit
b6b3499922
19 changed files with 241 additions and 169 deletions
|
@ -244,9 +244,18 @@ public class UrlBuilder {
|
|||
return getPath(route.path(), params);
|
||||
}
|
||||
|
||||
public static String getIndividualProfileUrl(String individualUri, WebappDaoFactory wadf) {
|
||||
Individual individual = wadf.getIndividualDao().getIndividualByURI(individualUri);
|
||||
return getIndividualProfileUrl(individual, individualUri, wadf);
|
||||
}
|
||||
|
||||
public static String getIndividualProfileUrl(Individual individual, WebappDaoFactory wadf) {
|
||||
String profileUrl = null;
|
||||
String individualUri = individual.getURI();
|
||||
return getIndividualProfileUrl(individual, individualUri, wadf);
|
||||
}
|
||||
|
||||
private static String getIndividualProfileUrl(Individual individual, String individualUri, WebappDaoFactory wadf) {
|
||||
String profileUrl = null;
|
||||
URI uri = new URIImpl(individualUri);
|
||||
String namespace = uri.getNamespace();
|
||||
String defaultNamespace = wadf.getDefaultNamespace();
|
||||
|
|
|
@ -30,5 +30,5 @@ public interface ObjectPropertyStatementDao {
|
|||
|
||||
int insertNewObjectPropertyStatement(ObjectPropertyStatement objPropertyStmt );
|
||||
|
||||
public List<Map<String, Object>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String query);
|
||||
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String query);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec
|
|||
|
||||
@Override
|
||||
// RY What about filtering?
|
||||
public List<Map<String, Object>> getObjectPropertyStatementsForIndividualByProperty(
|
||||
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
|
||||
String subjectUri, String propertyUri, String query) {
|
||||
return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, query);
|
||||
}
|
||||
|
|
|
@ -898,9 +898,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
|
|||
ResultSet results = qexec.execSelect();
|
||||
while (results.hasNext()) {
|
||||
QuerySolution soln = results.next();
|
||||
Resource resource = soln.getResource("property");
|
||||
String uri = resource.getURI();
|
||||
ObjectProperty prop = getObjectPropertyByURI(uri);
|
||||
ObjectProperty prop = getObjectPropertyByURI(soln.getResource("property").getURI());
|
||||
String filename = soln.getLiteral("filename").getLexicalForm();
|
||||
customListViewConfigFileMap.put(prop, filename);
|
||||
}
|
||||
|
|
|
@ -251,7 +251,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
|
|||
* custom queries that could request any data in addition to just the object of the statement.
|
||||
* However, we do need to get the object of the statement so that we have it to create editing links.
|
||||
*/
|
||||
public List<Map<String, Object>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String queryString) {
|
||||
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String queryString) {
|
||||
|
||||
log.debug("Object property query string: " + queryString);
|
||||
|
||||
|
@ -269,47 +269,16 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
|
|||
|
||||
// Run the SPARQL query to get the properties
|
||||
QueryExecution qexec = QueryExecutionFactory.create(query, getOntModelSelector().getFullModel(), bindings);
|
||||
return executeQueryToObjectValueCollection(qexec);
|
||||
}
|
||||
|
||||
protected List<Map<String, Object>> executeQueryToObjectValueCollection(
|
||||
QueryExecution qexec) {
|
||||
List<Map<String, Object>> rv = new ArrayList<Map<String, Object>>();
|
||||
ResultSet results = qexec.execSelect();
|
||||
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
|
||||
|
||||
while (results.hasNext()) {
|
||||
QuerySolution soln = results.nextSolution();
|
||||
rv.add(querySolutionToObjectValueMap(soln));
|
||||
list.add(QueryUtils.querySolutionToStringValueMap(soln));
|
||||
}
|
||||
return rv;
|
||||
return list;
|
||||
}
|
||||
|
||||
protected Map<String,Object> querySolutionToObjectValueMap( QuerySolution soln){
|
||||
Map<String,Object> map = new HashMap<String,Object>();
|
||||
Iterator<String> varNames = soln.varNames();
|
||||
while(varNames.hasNext()){
|
||||
String varName = varNames.next();
|
||||
map.put(varName, nodeToObject( soln.get(varName)));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
protected Object nodeToObject( RDFNode node ){
|
||||
if( node == null ){
|
||||
return "";
|
||||
}else if( node.isLiteral() ){
|
||||
Literal literal = node.asLiteral();
|
||||
//return literal.getValue();
|
||||
return literal.getLexicalForm();
|
||||
}else if( node.isURIResource() ){
|
||||
Resource resource = node.asResource();
|
||||
// See notes in ObjectPropertyStatementTemplateModel about why we are returning the individual
|
||||
// here instead of just the URI.
|
||||
return getWebappDaoFactory().getIndividualDao().getIndividualByURI(resource.getURI());
|
||||
}else if( node.isAnon() ){
|
||||
Resource resource = node.asResource();
|
||||
return resource.getId().getLabelString(); //get b-node id
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.hp.hpl.jena.query.QueryExecution;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
|
||||
/**
|
||||
* Utilities for executing queries and working with query results.
|
||||
*
|
||||
*/
|
||||
|
||||
public class QueryUtils {
|
||||
|
||||
protected static Map<String,Object> querySolutionToObjectValueMap( QuerySolution soln){
|
||||
Map<String,Object> map = new HashMap<String,Object>();
|
||||
Iterator<String> varNames = soln.varNames();
|
||||
while(varNames.hasNext()){
|
||||
String varName = varNames.next();
|
||||
map.put(varName, nodeToObject( soln.get(varName)));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected static Map<String,String> querySolutionToStringValueMap( QuerySolution soln ){
|
||||
Map<String,String> map = new HashMap<String,String>();
|
||||
Iterator<String> varNames = soln.varNames();
|
||||
while(varNames.hasNext()){
|
||||
String varName = varNames.next();
|
||||
map.put(varName, nodeToString( soln.get(varName)));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected static Object nodeToObject( RDFNode node ){
|
||||
if( node == null ){
|
||||
return "";
|
||||
}else if( node.isLiteral() ){
|
||||
Literal literal = node.asLiteral();
|
||||
return literal.getValue();
|
||||
}else if( node.isURIResource() ){
|
||||
Resource resource = node.asResource();
|
||||
return resource.getURI();
|
||||
}else if( node.isAnon() ){
|
||||
Resource resource = node.asResource();
|
||||
return resource.getId().getLabelString(); //get b-node id
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
protected static String nodeToString( RDFNode node ){
|
||||
if( node == null ){
|
||||
return "";
|
||||
}else if( node.isLiteral() ){
|
||||
Literal literal = node.asLiteral();
|
||||
return literal.getLexicalForm();
|
||||
}else if( node.isURIResource() ){
|
||||
Resource resource = node.asResource();
|
||||
return resource.getURI();
|
||||
}else if( node.isAnon() ){
|
||||
Resource resource = node.asResource();
|
||||
return resource.getId().getLabelString(); //get b-node id
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
|
|||
|
||||
private static final Log log = LogFactory.getLog(CollatedObjectPropertyTemplateModel.class);
|
||||
|
||||
private Map<String, List<ObjectPropertyStatementTemplateModel>> collatedStatements;
|
||||
private Map<String, List<ObjectPropertyStatementTemplateModel>> subclasses;
|
||||
//private List<SubclassList> subclassList;
|
||||
|
||||
CollatedObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) throws Exception {
|
||||
|
@ -53,16 +53,16 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
|
|||
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());
|
||||
List<Map<String, String>> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
|
||||
subclasses = 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);
|
||||
}
|
||||
// if (statementData.size() > 0) {
|
||||
// String collationTarget = getCollationTarget();
|
||||
// List<VClass> vclasses = getDirectVClasses(collationTarget, statementData);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
|
|||
/* Access methods for templates */
|
||||
|
||||
public Map<String, List<ObjectPropertyStatementTemplateModel>> getCollatedStatements() {
|
||||
return collatedStatements;
|
||||
return subclasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,24 +19,12 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
|
|||
|
||||
private String subjectUri; // we'll use these to make the edit links
|
||||
private String propertyUri;
|
||||
private Map<String, Object> data;
|
||||
private WebappDaoFactory wdf;
|
||||
private Map<String, String> data;
|
||||
|
||||
ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, Map<String, Object> data, WebappDaoFactory wdf) {
|
||||
ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, Map<String, String> data) {
|
||||
this.subjectUri = subjectUri;
|
||||
this.propertyUri = propertyUri;
|
||||
this.wdf = wdf;
|
||||
this.data = new HashMap<String, Object>(data.size());
|
||||
// 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) {
|
||||
Individual i = (Individual) value;
|
||||
this.data.put(key, new StatementObject(i));
|
||||
} else {
|
||||
this.data.put(key, value);
|
||||
}
|
||||
}
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/* This is a hopefully temporary solution to account for the fact that in the default
|
||||
|
@ -75,28 +63,7 @@ public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel {
|
|||
* 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 {
|
||||
|
||||
private Individual individual;
|
||||
|
||||
StatementObject(Individual individual) {
|
||||
this.individual = individual;
|
||||
}
|
||||
|
||||
/* Access methods for templates */
|
||||
|
||||
public String getName() {
|
||||
return individual.getName();
|
||||
}
|
||||
|
||||
public String getMoniker() {
|
||||
return individual.getMoniker();
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return UrlBuilder.getIndividualProfileUrl(individual, wdf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Access methods for templates */
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
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;
|
||||
|
@ -15,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.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
|
||||
|
@ -44,6 +47,11 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
protected String getCollationTarget() {
|
||||
return config.collationTarget;
|
||||
}
|
||||
|
||||
protected String getLinkTarget() {
|
||||
return config.linkTarget;
|
||||
}
|
||||
|
||||
|
||||
protected static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) {
|
||||
if (op.getCollateBySubclass()) {
|
||||
|
@ -58,6 +66,23 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
}
|
||||
}
|
||||
|
||||
/** Applies preprocessing to query results to prepare for template */
|
||||
protected void preprocess(List<Map<String, String>> data, WebappDaoFactory wdf) {
|
||||
/* First apply standard post-processing for all object properties */
|
||||
|
||||
// Add urls for link targets to the data
|
||||
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 */
|
||||
}
|
||||
|
||||
private class PropertyListConfig {
|
||||
|
||||
private static final String DEFAULT_CONFIG_FILE = "objectPropertyList-default.xml";
|
||||
|
@ -65,10 +90,14 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
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 static final String NODE_NAME_LINK_TARGET = "link-target";
|
||||
private static final String NODE_NAME_PREPROCESSOR = "preprocessor";
|
||||
|
||||
private String queryString;
|
||||
private String templateName;
|
||||
private String collationTarget;
|
||||
private String linkTarget; // we could easily make this a list if we ever want multiple links
|
||||
private String preprocessor;
|
||||
|
||||
PropertyListConfig(ObjectProperty op, WebappDaoFactory wdf) throws Exception {
|
||||
|
||||
|
@ -93,9 +122,13 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document doc = db.parse(configFilePath);
|
||||
// Required values
|
||||
queryString = getConfigValue(doc, NODE_NAME_QUERY);
|
||||
templateName = getConfigValue(doc, NODE_NAME_TEMPLATE);
|
||||
templateName = getConfigValue(doc, NODE_NAME_TEMPLATE);
|
||||
// Optional values
|
||||
collationTarget = getConfigValue(doc, NODE_NAME_COLLATION_TARGET);
|
||||
linkTarget = getConfigValue(doc, NODE_NAME_LINK_TARGET); // if this is null, no link will be generated
|
||||
preprocessor = getConfigValue(doc, NODE_NAME_PREPROCESSOR);
|
||||
} catch (Exception e) {
|
||||
log.error("Error processing config file " + configFilePath + " for object property " + op.getURI(), e);
|
||||
// What should we do here?
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/* $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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
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);
|
||||
|
||||
String name;
|
||||
List<ObjectPropertyStatementTemplateModel> statements;
|
||||
|
||||
SubclassList(String name) {
|
||||
this.name = name;
|
||||
this.statements = new ArrayList<ObjectPropertyStatementTemplateModel>();
|
||||
|
||||
// get the obj property statements for this subclass from the db via a sparql query
|
||||
|
||||
}
|
||||
|
||||
/* Access methods for templates */
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<ObjectPropertyStatementTemplateModel> getStatements() {
|
||||
return statements;
|
||||
}
|
||||
}
|
|
@ -25,10 +25,11 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat
|
|||
ObjectPropertyStatementDao opDao = wdf.getObjectPropertyStatementDao();
|
||||
String subjectUri = subject.getURI();
|
||||
String propertyUri = op.getURI();
|
||||
List<Map<String, Object>> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
|
||||
List<Map<String, String>> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString());
|
||||
preprocess(statementData, wdf);
|
||||
statements = new ArrayList<ObjectPropertyStatementTemplateModel>(statementData.size());
|
||||
for (Map<String, Object> map : statementData) {
|
||||
statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map, wdf));
|
||||
for (Map<String, String> map : statementData) {
|
||||
statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
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);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/* $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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/* $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;
|
||||
|
||||
/**
|
||||
* These preprocessors take a list of object property statement data derived from a
|
||||
* SPARQL query (or other source) and prepare it for insertion into the template data model.
|
||||
*
|
||||
* @author rjy7
|
||||
*
|
||||
*/
|
||||
|
||||
public interface ObjectPropertyDataPreprocessor {
|
||||
|
||||
public void preprocess(List<Map<String, String>> data);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue