NIHVIVO-650 Some reorganization of template model classes. Fix for link list display on individual profile page.

This commit is contained in:
rjy7 2010-09-22 18:06:57 +00:00
parent 9d84a7114a
commit 68e5ebefc2
11 changed files with 125 additions and 109 deletions

View file

@ -81,7 +81,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
try { try {
VitroRequest vreq = new VitroRequest(request); VitroRequest vreq = new VitroRequest(request);
BaseTemplateModel.setVitroRequest(vreq);
Configuration config = getConfig(vreq); Configuration config = getConfig(vreq);
vreq.setAttribute("freemarkerConfig", config); vreq.setAttribute("freemarkerConfig", config);

View file

@ -76,10 +76,7 @@ public class IndividualController extends FreemarkerHttpServlet {
@Override @Override
protected ResponseValues processRequest(VitroRequest vreq) { protected ResponseValues processRequest(VitroRequest vreq) {
try { try {
cleanUpSession(vreq);
HttpSession session = vreq.getSession();
cleanUpSession(session);
// get URL without hostname or servlet context // get URL without hostname or servlet context
String url = vreq.getRequestURI().substring(vreq.getContextPath().length()); String url = vreq.getRequestURI().substring(vreq.getContextPath().length());
@ -114,11 +111,13 @@ public class IndividualController extends FreemarkerHttpServlet {
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
int securityLevel = getSecurityLevel(session); body.put("editStatus", getEditingData(vreq));
UrlBuilder urlBuilder = new UrlBuilder(vreq.getPortal());
body.put("editStatus", getEditingData(vreq, securityLevel, individual, urlBuilder)); body.put("title", individual.getName());
body.put("title", individual.getName());
body.putAll(getIndividualData(vreq, individual)); body.put("relatedSubject", getRelatedSubject(vreq));
body.put("individual", getIndividualTemplateModel(vreq, individual));
return new TemplateResponseValues(TEMPLATE_INDIVIDUAL, body); return new TemplateResponseValues(TEMPLATE_INDIVIDUAL, body);
@ -128,8 +127,9 @@ public class IndividualController extends FreemarkerHttpServlet {
} }
} }
private void cleanUpSession(HttpSession session) { private void cleanUpSession(VitroRequest vreq) {
// Session cleanup: anytime we are at an entity page we shouldn't have an editing config or submission // Session cleanup: anytime we are at an entity page we shouldn't have an editing config or submission
HttpSession session = vreq.getSession();
session.removeAttribute("editjson"); session.removeAttribute("editjson");
EditConfiguration.clearAllConfigsInSession(session); EditConfiguration.clearAllConfigsInSession(session);
EditSubmission.clearAllEditSubmissionsInSession(session); EditSubmission.clearAllEditSubmissionsInSession(session);
@ -149,27 +149,31 @@ public class IndividualController extends FreemarkerHttpServlet {
} }
private Map<String, Object> getEditingData(VitroRequest vreq, int securityLevel, Individual individual, UrlBuilder urlBuilder) { // Set template values related to access privileges
// Set values related to access privileges // RY We may want to define an EditingIndividualTemplateModel class, with methods like getAdminPanel() and
// getEditLinks(property). The constructor would take an individual and a loginFormBean object, both of which
// are needed to generate property edit links. Another idea is to subclass IndividualTemplateModel with
// EditableIndividualTemplateModel, and define editing-related methods there. However, that means in the
// template we will have expressions like individual.adminPanel or individual.editingLinks(property),
// which might seem opaque to template authors.
private Map<String, Object> getEditingData(VitroRequest vreq) {
int securityLevel = getSecurityLevel(vreq.getSession());
Map<String, Object> editingData = new HashMap<String, Object>(); Map<String, Object> editingData = new HashMap<String, Object>();
editingData.put("showEditLinks", VitroRequestPrep.isSelfEditing(vreq) || securityLevel >= LoginFormBean.NON_EDITOR); editingData.put("showEditLinks", VitroRequestPrep.isSelfEditing(vreq) || securityLevel >= LoginFormBean.NON_EDITOR);
boolean showAdminPanel = securityLevel >= LoginFormBean.EDITOR; boolean showAdminPanel = securityLevel >= LoginFormBean.EDITOR;
editingData.put("showAdminPanel", showAdminPanel); editingData.put("showAdminPanel", showAdminPanel);
if (showAdminPanel) {
editingData.put("editingUrl", urlBuilder.getPortalUrl("/entityEdit", "uri", individual.getURI()));
}
return editingData; return editingData;
} }
private Map<String, Object> getIndividualData(VitroRequest vreq, Individual individual) throws ServletException, IOException { private Map<String, Object> getRelatedSubject(VitroRequest vreq) {
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = null;
IndividualDao iwDao = vreq.getWebappDaoFactory().getIndividualDao(); IndividualDao iwDao = vreq.getWebappDaoFactory().getIndividualDao();
ObjectPropertyDao opDao = vreq.getWebappDaoFactory().getObjectPropertyDao(); ObjectPropertyDao opDao = vreq.getWebappDaoFactory().getObjectPropertyDao();
// Check if a "relatedSubjectUri" parameter has been supplied, and, // Check if a "relatedSubjectUri" parameter has been supplied, and,
@ -178,22 +182,30 @@ public class IndividualController extends FreemarkerHttpServlet {
// be displayed in the context of their relationship to another. // be displayed in the context of their relationship to another.
String relatedSubjectUri = vreq.getParameter("relatedSubjectUri"); String relatedSubjectUri = vreq.getParameter("relatedSubjectUri");
if (relatedSubjectUri != null) { if (relatedSubjectUri != null) {
Individual relatedSubjectInd = iwDao.getIndividualByURI(relatedSubjectUri); Individual relatedSubjectInd = iwDao.getIndividualByURI(relatedSubjectUri);
if (relatedSubjectInd != null) { if (relatedSubjectInd != null) {
Map<String, Object> relatedSubject = new HashMap<String, Object>(); map = new HashMap<String, Object>();
relatedSubject.put("name", relatedSubjectInd.getName()); map.put("name", relatedSubjectInd.getName());
relatedSubject.put("url", (new IndividualTemplateModel(relatedSubjectInd)).getProfileUrl()); map.put("url", (new IndividualTemplateModel(relatedSubjectInd, vreq)).getProfileUrl());
String relatingPredicateUri = vreq.getParameter("relatingPredicateUri"); String relatingPredicateUri = vreq.getParameter("relatingPredicateUri");
if (relatingPredicateUri != null) { if (relatingPredicateUri != null) {
ObjectProperty relatingPredicateProp = opDao.getObjectPropertyByURI(relatingPredicateUri); ObjectProperty relatingPredicateProp = opDao.getObjectPropertyByURI(relatingPredicateUri);
if (relatingPredicateProp != null) { if (relatingPredicateProp != null) {
relatedSubject.put("relatingPredicateDomainPublic", relatingPredicateProp.getDomainPublic()); map.put("relatingPredicateDomainPublic", relatingPredicateProp.getDomainPublic());
} }
} }
map.put("relatedSubject", relatedSubject); }
}
} }
return map;
}
private IndividualTemplateModel getIndividualTemplateModel(VitroRequest vreq, Individual individual)
throws ServletException, IOException {
IndividualDao iwDao = vreq.getWebappDaoFactory().getIndividualDao();
int securityLevel = getSecurityLevel(vreq.getSession());
individual.setKeywords(iwDao.getKeywordsForIndividualByMode(individual.getURI(),"visible")); individual.setKeywords(iwDao.getKeywordsForIndividualByMode(individual.getURI(),"visible"));
individual.sortForDisplay(); individual.sortForDisplay();
@ -237,18 +249,11 @@ public class IndividualController extends FreemarkerHttpServlet {
// if (customView!=null) { // if (customView!=null) {
// // insert test for whether a css files of the same name exists, and populate the customCss string for use when construction the header // // insert test for whether a css files of the same name exists, and populate the customCss string for use when construction the header
// } // }
map.put("individual", new IndividualTemplateModel(individual));
//setup highlighter for search terms //setup highlighter for search terms
//checkForSearch(vreq, individual); //checkForSearch(vreq, individual);
return new IndividualTemplateModel(individual, vreq);
if( individual.getURI().startsWith( vreq.getWebappDaoFactory().getDefaultNamespace() )){
map.put("entityLinkedDataURL", individual.getURI() + "/" + individual.getLocalName() + ".rdf");
}
return map;
} }
private ResponseValues doRdf(VitroRequest vreq, Individual individual, private ResponseValues doRdf(VitroRequest vreq, Individual individual,
@ -266,15 +271,6 @@ public class IndividualController extends FreemarkerHttpServlet {
return new RdfResponseValues(rdfFormat, newModel); return new RdfResponseValues(rdfFormat, newModel);
} }
private void doRedirect(HttpServletRequest req, HttpServletResponse res,
String redirectURL) {
// It seems like there must be a better way to do this
String hn = req.getHeader("Host");
res.setHeader("Location", res.encodeURL( "http://" + hn + req.getContextPath() + redirectURL ));
res.setStatus(res.SC_SEE_OTHER);
}
private static Pattern LINKED_DATA_URL = Pattern.compile("^/individualfm/([^/]*)$"); private static Pattern LINKED_DATA_URL = Pattern.compile("^/individualfm/([^/]*)$");
private static Pattern NS_PREFIX_URL = Pattern.compile("^/individualfm/([^/]*)/([^/]*)$"); private static Pattern NS_PREFIX_URL = Pattern.compile("^/individualfm/([^/]*)/([^/]*)$");
@ -666,17 +662,5 @@ public class IndividualController extends FreemarkerHttpServlet {
return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_NOT_FOUND); return new TemplateResponseValues(Template.TITLED_ERROR_MESSAGE.toString(), body, HttpServletResponse.SC_NOT_FOUND);
} }
private String forURL(String frag) {
String result = null;
try {
result = URLEncoder.encode(frag, "UTF-8");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException("UTF-8 not supported", ex);
}
return result;
}
private class HelpException extends Throwable{}
private class EntityNotFoundException extends Throwable{}
} }

View file

@ -64,16 +64,13 @@ public class IndividualListController extends FreemarkerHttpServlet {
if (vclass != null) { if (vclass != null) {
// Create list of individual view objects // Create list of individual view objects
List<Individual> individualList = vreq.getWebappDaoFactory().getIndividualDao().getIndividualsByVClass(vclass); List<Individual> individualList = vreq.getWebappDaoFactory().getIndividualDao().getIndividualsByVClass(vclass);
List<IndividualTemplateModel> individuals = new ArrayList<IndividualTemplateModel>(individualList.size());
if (individualList == null) { if (individualList == null) {
// RY Is this really an error? // RY Is this really an error?
log.error("individuals list is null"); log.error("individuals list is null");
message = "No individuals to display."; message = "No individuals to display.";
} else { } else {
for (Individual i: individualList) { body.put("individuals", IndividualTemplateModel.getIndividualTemplateModelList(individualList, vreq));
individuals.add(new IndividualTemplateModel(i));
}
} }
// Set title and subtitle. Title will be retrieved later in getTitle(). // Set title and subtitle. Title will be retrieved later in getTitle().
@ -85,9 +82,8 @@ public class IndividualListController extends FreemarkerHttpServlet {
title = classGroup.getPublicName(); title = classGroup.getPublicName();
body.put("subtitle", vclass.getName()); body.put("subtitle", vclass.getName());
} }
body.put("title", title); body.put("title", title);
body.put("individuals", individuals);
} }
} catch (HelpException help){ } catch (HelpException help){

View file

@ -29,6 +29,7 @@ public class UrlBuilder {
BROWSE("/browse"), BROWSE("/browse"),
CONTACT("/contact"), CONTACT("/contact"),
INDIVIDUAL("/individual"), INDIVIDUAL("/individual"),
INDIVIDUAL_EDIT("/entityEdit"),
INDIVIDUAL_LIST("/individuallist"), INDIVIDUAL_LIST("/individuallist"),
LOGIN("/siteAdmin"), LOGIN("/siteAdmin"),
LOGOUT("/login_process.jsp"), LOGOUT("/login_process.jsp"),
@ -145,6 +146,10 @@ public class UrlBuilder {
public String getPortalUrl(Route route, ParamMap params) { public String getPortalUrl(Route route, ParamMap params) {
return getPortalUrl(route.path(), params); return getPortalUrl(route.path(), params);
} }
public String getPortalUrl(Route route, String...params) {
return getPortalUrl(route.path(), params);
}
public static class ParamMap extends HashMap<String, String> { public static class ParamMap extends HashMap<String, String> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View file

@ -265,11 +265,7 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
new SimpleLuceneHighlighter(query,analyzer) ); new SimpleLuceneHighlighter(query,analyzer) );
// Convert search result individuals to template model objects // Convert search result individuals to template model objects
List<IndividualTemplateModel> individuals = new ArrayList<IndividualTemplateModel>(beans.size()); body.put("individuals", IndividualTemplateModel.getIndividualTemplateModelList(beans, vreq));
for (Individual i : beans) {
individuals.add(new IndividualTemplateModel(i));
}
body.put("individuals", individuals);
body.put("querytext", qtxt); body.put("querytext", qtxt);
body.put("title", qtxt+" - "+portal.getAppName()+" Search Results" ); body.put("title", qtxt+" - "+portal.getAppName()+" Search Results" );

View file

@ -19,7 +19,6 @@ public abstract class BaseTemplateModel {
private static final Log log = LogFactory.getLog(BaseTemplateModel.class); private static final Log log = LogFactory.getLog(BaseTemplateModel.class);
protected static ServletContext servletContext = null; protected static ServletContext servletContext = null;
protected static VitroRequest vreq = null;
// Wrap UrlBuilder method so templates can call ${item.url} // Wrap UrlBuilder method so templates can call ${item.url}
public String getUrl(String path) { public String getUrl(String path) {
@ -44,14 +43,6 @@ public abstract class BaseTemplateModel {
servletContext = context; servletContext = context;
} }
public static VitroRequest getVitroRequest() {
return vreq;
}
public static void setVitroRequest(VitroRequest vrequest) {
vreq = vrequest;
}
public String dump() { public String dump() {
return toString(); // fallback when subclass doesn't define a class-specific dump() return toString(); // fallback when subclass doesn't define a class-specific dump()
} }

View file

@ -12,9 +12,10 @@ import org.openrdf.model.impl.URIImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Link; import edu.cornell.mannlib.vitro.webapp.beans.Link;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
import edu.cornell.mannlib.vitro.webapp.web.ViewFinder; import edu.cornell.mannlib.vitro.webapp.web.ViewFinder;
import edu.cornell.mannlib.vitro.webapp.web.ViewFinder.ClassView; import edu.cornell.mannlib.vitro.webapp.web.ViewFinder.ClassView;
@ -24,10 +25,22 @@ public class IndividualTemplateModel extends BaseTemplateModel {
private static final String PATH = Route.INDIVIDUAL.path(); private static final String PATH = Route.INDIVIDUAL.path();
private Individual individual; protected Individual individual;
protected VitroRequest vreq;
protected UrlBuilder urlBuilder;
public IndividualTemplateModel(Individual individual) { // private PropertyListTemplateModel propertyList;
// RY The IndividualTemplateModel object needs access to the request object.
// The only other template model that does is MainMenu. We could provide an
// interface for RequestAware template models, but they still wouldn't share any code.
// If they both derive from a common RequestAwareTemplateModel class, we might be
// locking ourselves in too tightly to that class hierarchy.
public IndividualTemplateModel(Individual individual, VitroRequest vreq) {
this.individual = individual; this.individual = individual;
this.vreq = vreq;
// Needed for getting portal-sensitive urls. Remove if multi-portal support is removed.
this.urlBuilder = new UrlBuilder(vreq.getPortal());
} }
/* These methods perform some manipulation of the data returned by the Individual methods */ /* These methods perform some manipulation of the data returned by the Individual methods */
@ -60,15 +73,6 @@ public class IndividualTemplateModel extends BaseTemplateModel {
return isPerson() ? getUrl(Route.VISUALIZATION.path(), "uri", getUri()) : null; return isPerson() ? getUrl(Route.VISUALIZATION.path(), "uri", getUri()) : null;
} }
// RY We should not have references to a specific ontology in the vitro code!
// Figure out how to move this out of here.
// We could subclass IndividualTemplateModel in the VIVO code and add the isPerson()
// and getVisualizationUrl() methods there, but we still need to know whether to
// instantiate the IndividualTemplateModel or the VivoIndividualTemplateModel class.
public boolean isPerson() {
return individual.isVClass("http://xmlns.com/foaf/0.1/Person");
}
public String getImageUrl() { public String getImageUrl() {
String imageUrl = individual.getImageUrl(); String imageUrl = individual.getImageUrl();
return imageUrl == null ? null : getUrl(imageUrl); return imageUrl == null ? null : getUrl(imageUrl);
@ -78,7 +82,26 @@ public class IndividualTemplateModel extends BaseTemplateModel {
String thumbUrl = individual.getThumbUrl(); String thumbUrl = individual.getThumbUrl();
return thumbUrl == null ? null : getUrl(thumbUrl); return thumbUrl == null ? null : getUrl(thumbUrl);
} }
public String getLinkedDataUrl() {
String defaultNamespace = vreq.getWebappDaoFactory().getDefaultNamespace();
String uri = getUri();
return uri.startsWith(defaultNamespace) ? uri + "/" + getLocalName() + ".rdf" : null;
}
public String getEditUrl() {
return urlBuilder.getPortalUrl(Route.INDIVIDUAL_EDIT, "uri", getUri());
}
// RY We should not have references to a specific ontology in the vitro code!
// Figure out how to move this out of here.
// We could subclass IndividualTemplateModel in the VIVO code and add the isPerson()
// and getVisualizationUrl() methods there, but we still need to know whether to
// instantiate the IndividualTemplateModel or the VivoIndividualTemplateModel class.
public boolean isPerson() {
return individual.isVClass("http://xmlns.com/foaf/0.1/Person");
}
public String getSearchView() { public String getSearchView() {
return getView(ClassView.SEARCH); return getView(ClassView.SEARCH);
} }
@ -149,4 +172,21 @@ public class IndividualTemplateModel extends BaseTemplateModel {
return individual.getKeywords(); return individual.getKeywords();
} }
public String getKeywordString() {
// Since this is a display method, the implementation should be moved out of IndividualImpl to here.
return individual.getKeywordString();
}
public String getLocalName() {
return individual.getLocalName();
}
public static List<IndividualTemplateModel> getIndividualTemplateModelList(List<Individual> individuals, VitroRequest vreq) {
List<IndividualTemplateModel> models = new ArrayList<IndividualTemplateModel>(individuals.size());
for (Individual individual : individuals) {
models.add(new IndividualTemplateModel(individual, vreq));
}
return models;
}
} }

View file

@ -15,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
public class MainMenu extends Menu { public class MainMenu extends Menu {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(MainMenu.class.getName()); private static final Log log = LogFactory.getLog(MainMenu.class);
protected VitroRequest vreq; protected VitroRequest vreq;

View file

@ -59,18 +59,23 @@
<#if individual.links?has_content> <#if individual.links?has_content>
<div id="dprop-vitro-links" class="propsItem ${editingClass}"> <div id="dprop-vitro-links" class="propsItem ${editingClass}">
<ul class="externalLinks properties"> <ul class="externalLinks properties">
<#list individual.links as link> <@l.firstLastList>
<@l.firstLastList> <#list individual.links as link>
<li> <li>
<span class="statementWrap"> <span class="statementWrap">
<a class="externalLink" href="${link.url}">${link.anchor}</a> <a class="externalLink" href="${link.url}">${link.anchor}</a>
</span> </span>
</li> </li>
</@l.firstLastList> </#list>
</#list> </@l.firstLastList>
</ul> </ul>
</div> </div>
</#if> </#if>
<#-- Keywords -->
<#if individual.keywords?has_content>
<p id="keywords">Keywords: ${individual.keywordString}</p>
</#if>
</div> <!-- #contents --> </div> <!-- #contents -->
</div> <!-- #personWrap --> </div> <!-- #personWrap -->

View file

@ -25,9 +25,9 @@
<a href="${individual.profileUrl}">${individual.name}</a> <a href="${individual.profileUrl}">${individual.name}</a>
<ul class="individualData"> <ul class="individualData">
<@l.firstLastList> <@l.firstLastList>
<#if individual.moniker??><li>${individual.moniker}</li>,</#if> <#if individual.moniker??><li>${individual.moniker}</li></#if>
<#list individual.links as link> <#list individual.links as link>
<li><a class="externalLink" href="${link.url}">${link.anchor}</a></li>, <li><a class="externalLink" href="${link.url}">${link.anchor}</a></li>
</#list> </#list>
</@l.firstLastList> </@l.firstLastList>
</ul> </ul>

View file

@ -5,7 +5,7 @@
<div class="admin top"> <div class="admin top">
<h3 class="toggle">Admin Panel</h3> <h3 class="toggle">Admin Panel</h3>
<div class="panelContents"> <div class="panelContents">
<a href="${editStatus.editingUrl}"> edit this individual</a> <a href="${individual.editUrl}"> edit this individual</a>
<p>Resource URI: ${individual.uri}</p> <p>Resource URI: ${individual.uri}</p>
</div> </div>
</div> </div>