From 838713d6696d20663f1249387e4579003882f2d7 Mon Sep 17 00:00:00 2001 From: rjy7 Date: Mon, 13 Dec 2010 15:27:22 +0000 Subject: [PATCH] NIHVIVO-1333 Display of uncollated object property statements with default view --- .../freemarker/FreemarkerHttpServlet.java | 17 ++-- .../freemarker/IndividualController.java | 11 ++- .../freemarker/SamplesController.java | 2 + .../controller/freemarker/UrlBuilder.java | 32 +++++++ .../dao/ObjectPropertyStatementDao.java | 3 +- .../ObjectPropertyStatementDaoFiltering.java | 8 +- .../jena/ObjectPropertyStatementDaoJena.java | 64 +++++++++++--- .../individual/IndividualTemplateModel.java | 29 +------ .../ObjectPropertyStatementTemplateModel.java | 85 +++++++++++++++++-- .../ObjectPropertyTemplateModel.java | 1 + .../individual/PropertyListBuilder.java | 8 +- ...UncollatedObjectPropertyTemplateModel.java | 20 ++--- .../body/individual/individual-properties.ftl | 7 +- .../freemarker/body/individual/individual.ftl | 3 + .../objectPropertyList-collated.ftl | 5 ++ .../individual/objectPropertyList-default.ftl | 2 +- .../web/templates/freemarker/body/samples.ftl | 2 + .../web/views/objectPropertyList-default.xml | 4 +- 18 files changed, 220 insertions(+), 83 deletions(-) create mode 100644 webapp/web/templates/freemarker/body/individual/objectPropertyList-collated.ftl diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java index 21e87bc0e..15b28f174 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java @@ -204,11 +204,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { writePage(root, config, vreq, response); } - private void processSetupTemplate(Configuration config, HttpServletRequest request, Map map) { - TemplateProcessingHelper helper = new TemplateProcessingHelper(config, request, getServletContext()); - helper.processTemplate(Template.SETUP.toString(), map); - } - protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values) throws ServletException, IOException { String redirectUrl = values.getRedirectUrl(); @@ -331,12 +326,20 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { return urls; } + protected BeansWrapper getNonDefaultBeansWrapper(int exposureLevel) { + BeansWrapper wrapper = new DefaultObjectWrapper(); + // Too bad exposure levels are ints instead of enum values; what happens if + // we send an int that's not a defined exposure level? + wrapper.setExposureLevel(exposureLevel); + return wrapper; + } + private TemplateModel getStylesheetList(String themeDir) { // For script and stylesheet lists, use an object wrapper that exposes write methods, // instead of the configuration's object wrapper, which doesn't. The templates can // add stylesheets and scripts to the lists by calling their add() methods. - BeansWrapper wrapper = new DefaultObjectWrapper(); + BeansWrapper wrapper = getNonDefaultBeansWrapper(BeansWrapper.EXPOSE_SAFE); try { // Here themeDir SHOULD NOT have the context path already added to it. return wrapper.wrap(new Stylesheets(themeDir)); @@ -351,7 +354,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { // For script and stylesheet lists, use an object wrapper that exposes write methods, // instead of the configuration's object wrapper, which doesn't. The templates can // add stylesheets and scripts to the lists by calling their add() methods. - BeansWrapper wrapper = new DefaultObjectWrapper(); + BeansWrapper wrapper = getNonDefaultBeansWrapper(BeansWrapper.EXPOSE_SAFE); try { return wrapper.wrap(new Scripts(themeDir)); } catch (TemplateModelException e) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java index 8993df4e7..30d70fcc1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java @@ -58,6 +58,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; import edu.cornell.mannlib.vitro.webapp.web.ContentType; import edu.cornell.mannlib.vitro.webapp.web.jsptags.StringProcessorTag; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel; +import freemarker.ext.beans.BeansWrapper; /** * Handles requests for entity information. @@ -118,8 +119,14 @@ public class IndividualController extends FreemarkerHttpServlet { body.put("relatedSubject", getRelatedSubject(vreq)); - IndividualTemplateModel ind = getIndividualTemplateModel(vreq, individual); - body.put("individual", ind); + IndividualTemplateModel ind = getIndividualTemplateModel(vreq, individual); + /* We need to expose non-getters in displaying the individual's property list, + * since it requires calls to methods with parameters. + * This is still safe, because we are only putting BaseTemplateModel objects + * into the data model. No real data can be modified. + * RY Not sure this will be needed; postpone. + */ + body.put("individual", ind); //getNonDefaultBeansWrapper(BeansWrapper.EXPOSE_SAFE).wrap(ind)); String template = getIndividualTemplate(individual); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SamplesController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SamplesController.java index 63105935c..a79881ff4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SamplesController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SamplesController.java @@ -89,6 +89,8 @@ public class SamplesController extends FreemarkerHttpServlet { body.put("bookTitle", "Pride and Prejudice"); body.put("bookTitle", "Persuasion"); + body.put("year", "2001"); + body.put("title", "Freemarker Samples"); return new TemplateResponseValues(TEMPLATE_DEFAULT, body); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java index 6e09fddab..6ffd1f011 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java @@ -6,12 +6,19 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; 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 org.openrdf.model.URI; +import org.openrdf.model.impl.URIImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Portal; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.filters.PortalPickerFilter; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; @@ -236,6 +243,31 @@ public class UrlBuilder { public static String getPath(Route route, ParamMap params) { return getPath(route.path(), params); } + + public static String getIndividualProfileUrl(Individual individual, WebappDaoFactory wadf) { + String profileUrl = null; + String individualUri = individual.getURI(); + URI uri = new URIImpl(individualUri); + String namespace = uri.getNamespace(); + String defaultNamespace = wadf.getDefaultNamespace(); + + String localName = individual.getLocalName(); + + if (defaultNamespace.equals(namespace)) { + profileUrl = getUrl(Route.INDIVIDUAL.path() + "/" + localName); + } else { + List externallyLinkedNamespaces = wadf.getApplicationDao().getExternallyLinkedNamespaces(); + if (externallyLinkedNamespaces.contains(namespace)) { + log.debug("Found externally linked namespace " + namespace); + profileUrl = namespace + "/" + localName; + } else { + ParamMap params = new ParamMap("uri", individualUri); + profileUrl = getUrl("/individual", params); + } + } + + return profileUrl; + } public static String urlEncode(String url) { String encoding = "ISO-8859-1"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java index 6964293f3..d15a0482b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java @@ -3,6 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.dao; import java.util.List; +import java.util.Map; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; @@ -29,5 +30,5 @@ public interface ObjectPropertyStatementDao { int insertNewObjectPropertyStatement(ObjectPropertyStatement objPropertyStmt ); - public List getObjectPropertyStatementsForIndividualByProperty(Individual subject, ObjectProperty property, String query); + public List> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String query); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java index ba7d758ef..3bf301ca7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java @@ -4,9 +4,9 @@ package edu.cornell.mannlib.vitro.webapp.dao.filtering; import java.util.ArrayList; import java.util.List; +import java.util.Map; import net.sf.jga.algorithms.Filter; - import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; @@ -84,9 +84,9 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec @Override // RY What about filtering? - public List getObjectPropertyStatementsForIndividualByProperty( - Individual subject, ObjectProperty property, String query) { - return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subject, property, query); + public List> getObjectPropertyStatementsForIndividualByProperty( + String subjectUri, String propertyUri, String query) { + return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, query); } } \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index a122014f1..96da26d98 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -4,9 +4,13 @@ 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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; @@ -15,7 +19,9 @@ import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolutionMap; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; @@ -32,6 +38,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent; public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements ObjectPropertyStatementDao { + protected static final Log log = LogFactory.getLog(ObjectPropertyStatementDaoJena.class); + public ObjectPropertyStatementDaoJena(WebappDaoFactoryJena wadf) { super(wadf); } @@ -237,9 +245,13 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec @Override /* - * SPARQL-based method for getting the individual's values for a single data property. + * SPARQL-based method for getting values related to a single object property. + * We cannot return a List here, the way the corresponding method of + * DataPropertyStatementDaoJena returns a List. We need to accomodate + * 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 getObjectPropertyStatementsForIndividualByProperty(Individual subject, ObjectProperty property, String queryString) { + public List> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String queryString) { log.debug("Object property query string: " + queryString); @@ -250,9 +262,6 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec log.error("could not create SPARQL query for query string " + th.getMessage()); log.error(queryString); } - - String subjectUri = subject.getURI(); - String propertyUri = property.getURI(); QuerySolutionMap bindings = new QuerySolutionMap(); bindings.add("subject", ResourceFactory.createResource(subjectUri)); @@ -260,15 +269,44 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec // Run the SPARQL query to get the properties QueryExecution qexec = QueryExecutionFactory.create(query, getOntModelSelector().getFullModel(), bindings); - ResultSet results = qexec.execSelect(); - - List statements = new ArrayList(); + return executeQueryToObjectValueCollection(qexec); + } + + protected List> executeQueryToObjectValueCollection( + QueryExecution qexec) { + List> rv = new ArrayList>(); + ResultSet results = qexec.execSelect(); while (results.hasNext()) { - QuerySolution sol = results.next(); - Resource resource = sol.getResource("object"); - ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, propertyUri, resource.getURI()); - statements.add(ops); + QuerySolution soln = results.nextSolution(); + rv.add(querySolutionToObjectValueMap(soln)); + } + return rv; + } + + protected Map querySolutionToObjectValueMap( QuerySolution soln){ + Map map = new HashMap(); + Iterator 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(); + }else if( node.isURIResource() ){ + Resource resource = node.asResource(); + return getWebappDaoFactory().getIndividualDao().getIndividualByURI(resource.getURI()); + }else if( node.isAnon() ){ + Resource resource = node.asResource(); + return resource.getId().getLabelString(); //get b-node id + }else{ + return ""; } - return statements; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java index ffa0f221a..0ee63f3ca 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java @@ -40,36 +40,9 @@ public class IndividualTemplateModel extends BaseTemplateModel { } /* These methods perform some manipulation of the data returned by the Individual methods */ -// RY Individiual.getMoniker() was already trying to do this, but due to errors in the code it was not. -// That's fixed now. -// public String getTagline() { -// String tagline = individual.getMoniker(); -// return StringUtils.isEmpty(tagline) ? individual.getVClass().getName() : tagline; -// } public String getProfileUrl() { - String profileUrl = null; - String individualUri = individual.getURI(); - - URI uri = new URIImpl(individualUri); - String namespace = uri.getNamespace(); - WebappDaoFactory wadf = vreq.getWebappDaoFactory(); - String defaultNamespace = wadf.getDefaultNamespace(); - - if (defaultNamespace.equals(namespace)) { - profileUrl = getUrl(PATH + "/" + individual.getLocalName()); - } else { - List externallyLinkedNamespaces = wadf.getApplicationDao().getExternallyLinkedNamespaces(); - if (externallyLinkedNamespaces.contains(namespace)) { - log.debug("Found externally linked namespace " + namespace); - profileUrl = namespace + "/" + individual.getLocalName(); - } else { - ParamMap params = new ParamMap("uri", individualUri); - profileUrl = getUrl("/individual", params); - } - } - - return profileUrl; + return UrlBuilder.getIndividualProfileUrl(individual, vreq.getWebappDaoFactory()); } public String getVisualizationUrl() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java index 85cfb1ceb..6dc42d267 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java @@ -2,29 +2,100 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; +import java.util.HashMap; +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.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; public class ObjectPropertyStatementTemplateModel extends BaseTemplateModel { private static final Log log = LogFactory.getLog(ObjectPropertyStatementTemplateModel.class); - private ObjectPropertyStatement statement; + private String subjectUri; // we'll use these to make the edit links + private String propertyUri; + private Map data; + private WebappDaoFactory wdf; - ObjectPropertyStatementTemplateModel(ObjectPropertyStatement statement) { - this.statement = statement; + ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, Map data, WebappDaoFactory wdf) { + this.subjectUri = subjectUri; + this.propertyUri = propertyUri; + this.wdf = wdf; + this.data = new HashMap(data.size()); + // See comments above StatementIndividual 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 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 + * 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: + * 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. + * + * 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. + */ + public class StatementObject { + + private Individual individual; + + StatementObject(Individual individual) { + this.individual = individual; + } + + public String getName() { + return individual.getName(); + } + + public String getMoniker() { + return individual.getMoniker(); + } + + public String getUrl() { + return UrlBuilder.getIndividualProfileUrl(individual, wdf); + } + } + /* Access methods for templates */ - - public Individual getObject() { - return statement.getObject(); + + public Object get(String 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() { return null; } 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 653b8cc8b..0c7fdc3e1 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 @@ -3,6 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; import java.io.File; +import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyListBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyListBuilder.java index 6035b3363..79ddf0c23 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyListBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyListBuilder.java @@ -79,9 +79,11 @@ public class PropertyListBuilder { } // Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones - // If we're going to create a new template model object property with a name, - // don't need to set editLabel, can just do this: - //propertyList.addAll(subject.getPopulatedDataPropertyList()); + // rjy7 Currently we are getting the list of properties in one sparql query, then doing a separate query + // to get values for each property. This could be optimized by doing a single query to get a map of properties to + // DataPropertyStatements. Note that this does not apply to object properties, because the queries + // can be customized and thus differ from property to property. So it's easier for now to keep the + // two working in parallel. List dataPropertyList = subject.getPopulatedDataPropertyList(); for (DataProperty dp : dataPropertyList) { dp.setLabel(dp.getPublicName()); 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 b7b2e6cbf..ee8561abf 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 @@ -4,13 +4,13 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; import java.util.ArrayList; 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.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -23,23 +23,21 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat UncollatedObjectPropertyTemplateModel(ObjectProperty op, Individual subject, WebappDaoFactory wdf) { super(op, subject, wdf); ObjectPropertyStatementDao opDao = wdf.getObjectPropertyStatementDao(); - List opStatements = opDao.getObjectPropertyStatementsForIndividualByProperty(subject, op, getQueryString()); - statements = new ArrayList(); - for (ObjectPropertyStatement ops : opStatements) { - statements.add(new ObjectPropertyStatementTemplateModel(ops)); + String subjectUri = subject.getURI(); + String propertyUri = op.getURI(); + List> statementData = opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getQueryString()); + statements = new ArrayList(statementData.size()); + for (Map map : statementData) { + statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, propertyUri, map, wdf)); } } + /* Access methods for templates */ + public List getStatements() { return statements; } -// public List getStatements() { -// return subclassList; -// } - - /* Access methods for templates */ - @Override public boolean isCollatedBySubclass() { return false; diff --git a/webapp/web/templates/freemarker/body/individual/individual-properties.ftl b/webapp/web/templates/freemarker/body/individual/individual-properties.ftl index 132246b59..65021b247 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-properties.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-properties.ftl @@ -2,8 +2,6 @@ <#-- Template for property listing on individual profile page --> -<#assign propertyGroups = individual.propertyList> - <#list propertyGroups as group> <#-- Get the group name --> @@ -42,9 +40,10 @@ <#else> <#-- object property --> -

Collated? ${property.collatedBySubclass?string("yes", "no")}

- <#if ! property.collatedBySubclass> <#-- temporary, till we handle collated props --> + <#if ! property.collatedBySubclass> <#include "${property.template}"> + <#else> + <#include "objectPropertyList-collated.ftl"> diff --git a/webapp/web/templates/freemarker/body/individual/individual.ftl b/webapp/web/templates/freemarker/body/individual/individual.ftl index b4114f311..2d4cb10fc 100644 --- a/webapp/web/templates/freemarker/body/individual/individual.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual.ftl @@ -12,6 +12,9 @@ <#if editStatus.showAdminPanel> <#include "individual-adminPanel.ftl"> + +<#-- Manolo, please do not remove this line. Thanks! --> +<#assign propertyGroups = individual.propertyList>
diff --git a/webapp/web/templates/freemarker/body/individual/objectPropertyList-collated.ftl b/webapp/web/templates/freemarker/body/individual/objectPropertyList-collated.ftl new file mode 100644 index 000000000..4b694457e --- /dev/null +++ b/webapp/web/templates/freemarker/body/individual/objectPropertyList-collated.ftl @@ -0,0 +1,5 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Template for collated object property statement list --> + +

Display of collated object property statements is in progress.

\ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/individual/objectPropertyList-default.ftl b/webapp/web/templates/freemarker/body/individual/objectPropertyList-default.ftl index 45f67f91a..666ab3a08 100644 --- a/webapp/web/templates/freemarker/body/individual/objectPropertyList-default.ftl +++ b/webapp/web/templates/freemarker/body/individual/objectPropertyList-default.ftl @@ -4,6 +4,6 @@ <#list property.statements as statement>
- statement ${statement_index +1} + ${statement.object.name} ${statement.object.moniker!}
\ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/samples.ftl b/webapp/web/templates/freemarker/body/samples.ftl index 9049d2ad9..f7aa908f8 100644 --- a/webapp/web/templates/freemarker/body/samples.ftl +++ b/webapp/web/templates/freemarker/body/samples.ftl @@ -46,6 +46,8 @@

Berries: ${berries}

+

${year?number?c}

+ <@dump var="now" /> <@dump var="urls" /> <@dump var="fruit" /> diff --git a/webapp/web/views/objectPropertyList-default.xml b/webapp/web/views/objectPropertyList-default.xml index 596f0e0ca..b1f22334c 100644 --- a/webapp/web/views/objectPropertyList-default.xml +++ b/webapp/web/views/objectPropertyList-default.xml @@ -1,8 +1,8 @@ - - SELECT ?object WHERE { + + SELECT ?object { ?subject ?property ?object . }