Rewrote IndividualListController to handle error conditions from within FreeMarker. Reorganized controller control flow to account for interdependencies between body and title.
This commit is contained in:
parent
f40e2d1af7
commit
fbdba79833
11 changed files with 307 additions and 280 deletions
|
@ -2,7 +2,9 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -24,6 +26,13 @@ public class AboutController extends FreeMarkerHttpServlet {
|
|||
body.put("aboutText", portal.getAboutText());
|
||||
body.put("acknowledgeText", portal.getAcknowledgeText());
|
||||
|
||||
// Test of #list directive in template on undefined, null, or empty values
|
||||
// Basic idea: empty list okay, null or undefined value not okay
|
||||
// List<String> apples = new ArrayList<String>(); // no error
|
||||
// List<String> apples = null; // error
|
||||
// body.put("apples", apples);
|
||||
// no apples in body: error
|
||||
|
||||
String bodyTemplate = "about.ftl";
|
||||
return mergeBodyToTemplate(bodyTemplate, body);
|
||||
|
||||
|
|
|
@ -18,12 +18,11 @@ import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
|
||||
import edu.cornell.mannlib.vitro.webapp.flags.PortalFlag;
|
||||
import edu.cornell.mannlib.vitro.webapp.view.VClassGroupView;
|
||||
import freemarker.template.SimpleSequence;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import freemarker.template.*;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -69,7 +68,9 @@ public class BrowseController extends FreeMarkerHttpServlet {
|
|||
|
||||
protected String getBody() {
|
||||
|
||||
Map body = new HashMap();
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
String bodyTemplate = "classGroups.ftl";
|
||||
String message = null;
|
||||
|
||||
// Set main page template attributes specific to this page
|
||||
// But the template should control this! Try putting in a div inside the content.
|
||||
|
@ -80,22 +81,25 @@ public class BrowseController extends FreeMarkerHttpServlet {
|
|||
|
||||
//PortalFlag portalState= vreq.getPortalFlag();
|
||||
|
||||
String message = "";
|
||||
List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), vreq.getPortal().getPortalId());
|
||||
List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), portalId);
|
||||
if (groups == null || groups.isEmpty()) {
|
||||
message = "There are not yet any items in the system.";
|
||||
body.put("message", message);
|
||||
}
|
||||
else {
|
||||
// FreeMarker will wrap vcgroups in a SimpleSequence. So do we want to create the SimpleSequence directly?
|
||||
// But, makes code less portable to another system.
|
||||
// SimpleSequence vcgroups = new SimpleSequence(groups.size());
|
||||
List<VClassGroupView> vcgroups = new ArrayList<VClassGroupView>(groups.size());
|
||||
Iterator<VClassGroup> i = groups.iterator();
|
||||
while (i.hasNext()) {
|
||||
vcgroups.add(new VClassGroupView(i.next()));
|
||||
for (VClassGroup g: groups) {
|
||||
vcgroups.add(new VClassGroupView(g));
|
||||
}
|
||||
body.put("classGroups", vcgroups);
|
||||
}
|
||||
|
||||
String bodyTemplate = "classGroups.ftl";
|
||||
if (message != null) {
|
||||
body.put("message", message);
|
||||
}
|
||||
|
||||
return mergeBodyToTemplate(bodyTemplate, body);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,17 +66,12 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
protected String appName;
|
||||
protected Map<String, Object> root = new HashMap<String, Object>();
|
||||
|
||||
// Some servlets have their own doGet() method, in which case they need to call
|
||||
// doSetup(), setTitle(), setBody(), and write() themselves. Other servlets define only
|
||||
// a getBody() and getTitle() method and use the parent doGet() method.
|
||||
public void doGet( HttpServletRequest request, HttpServletResponse response )
|
||||
throws IOException, ServletException {
|
||||
|
||||
try {
|
||||
callSuperGet(request, response); // ??
|
||||
doSetup(request, response);
|
||||
setTitle();
|
||||
setBody();
|
||||
setTitleAndBody();
|
||||
write(response);
|
||||
|
||||
} catch (Throwable e) {
|
||||
|
@ -91,88 +86,21 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
doGet(request, response);
|
||||
}
|
||||
|
||||
protected void setBody() {
|
||||
root.put("body", getBody());
|
||||
}
|
||||
|
||||
protected void setSharedVariable(String key, Object value) {
|
||||
try {
|
||||
config.setSharedVariable(key, value);
|
||||
} catch (TemplateModelException e) {
|
||||
log.error("Can't set shared variable '" + key + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTitle() {
|
||||
setSharedVariable("title", getTitle());
|
||||
}
|
||||
|
||||
protected String getTitle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getBody() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected StringWriter mergeToTemplate(String templateName, Map<String, Object> map) {
|
||||
|
||||
Template template = null;
|
||||
try {
|
||||
template = config.getTemplate(templateName);
|
||||
} catch (IOException e) {
|
||||
log.error("Cannot get template " + templateName);
|
||||
}
|
||||
StringWriter sw = new StringWriter();
|
||||
if (template != null) {
|
||||
try {
|
||||
template.process(map, sw);
|
||||
} catch (TemplateException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return sw;
|
||||
}
|
||||
|
||||
protected String mergeBodyToTemplate(String templateName, Map<String, Object> map) {
|
||||
templateName = "body/" + templateName;
|
||||
String body = mergeToTemplate(templateName, map).toString();
|
||||
return body;
|
||||
}
|
||||
|
||||
protected void write(HttpServletResponse response) {
|
||||
|
||||
String templateName = "page/default.ftl";
|
||||
StringWriter sw = mergeToTemplate(templateName, root);
|
||||
try {
|
||||
PrintWriter out = response.getWriter();
|
||||
out.print(sw);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void callSuperGet(HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
super.doGet(request,response);
|
||||
} catch (ServletException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// RY This needs to be broken out as is for FreeMarkerComponentGenerator, which should not
|
||||
// include callSuperGet(). So it's only temporary.
|
||||
// Basic setup needed by all controllers
|
||||
protected void doSetup(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
if ( !(this instanceof FreeMarkerComponentGenerator) ) {
|
||||
try {
|
||||
super.doGet(request,response);
|
||||
} catch (ServletException e) {
|
||||
log.error("Servlet exception calling VitroHttpRequest.doGet()");
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
log.error("IO exception calling VitroHttpRequest.doGet()");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
vreq = new VitroRequest(request);
|
||||
this.response = response;
|
||||
portal = vreq.getPortal();
|
||||
|
@ -211,6 +139,34 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
setSharedVariable("scripts", new ScriptList());
|
||||
}
|
||||
|
||||
// Define template locations. Template loader will look first in the theme-specific
|
||||
// location, then in the vitro location.
|
||||
// RY We cannot do this in FreeMarkerSetup because (a) the theme depends on the portal,
|
||||
// and we have multi-portal installations, and (b) we need to support theme-switching on the fly.
|
||||
// To make more efficient, we could do this once, and then have a listener that does it again
|
||||
// when theme is switched. BUT this doesn't support (a), only (b), so we have to do it on every request.
|
||||
protected final void setTemplateLoader() {
|
||||
|
||||
String themeTemplateDir = context.getRealPath(getThemeDir()) + "/ftl";
|
||||
String vitroTemplateDir = context.getRealPath("/templates/freemarker");
|
||||
|
||||
try {
|
||||
FileTemplateLoader themeFtl = new FileTemplateLoader(new File(themeTemplateDir));
|
||||
FileTemplateLoader vitroFtl = new FileTemplateLoader(new File(vitroTemplateDir));
|
||||
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
|
||||
TemplateLoader[] loaders = new TemplateLoader[] { themeFtl, vitroFtl, ctl };
|
||||
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
|
||||
config.setTemplateLoader(mtl);
|
||||
} catch (IOException e) {
|
||||
log.error("Error loading templates");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private TabMenu getTabMenu() {
|
||||
return new TabMenu(vreq, portalId);
|
||||
}
|
||||
|
||||
public String getThemeDir() {
|
||||
return portal.getThemeDir().replaceAll("/$", "");
|
||||
}
|
||||
|
@ -252,31 +208,31 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
setSharedVariable("urls", urls);
|
||||
}
|
||||
|
||||
private final void setLoginInfo() {
|
||||
private final void setLoginInfo() {
|
||||
|
||||
String loginName = null;
|
||||
int securityLevel;
|
||||
String loginName = null;
|
||||
int securityLevel;
|
||||
|
||||
HttpSession session = vreq.getSession();
|
||||
LoginFormBean loginBean = (LoginFormBean) session.getAttribute("loginHandler");
|
||||
if (loginBean != null && loginBean.testSessionLevel(vreq) > -1) {
|
||||
loginName = loginBean.getLoginName();
|
||||
securityLevel = Integer.parseInt(loginBean.getLoginRole());
|
||||
}
|
||||
if (loginName != null) {
|
||||
root.put("loginName", loginName);
|
||||
HttpSession session = vreq.getSession();
|
||||
LoginFormBean loginBean = (LoginFormBean) session.getAttribute("loginHandler");
|
||||
if (loginBean != null && loginBean.testSessionLevel(vreq) > -1) {
|
||||
loginName = loginBean.getLoginName();
|
||||
securityLevel = Integer.parseInt(loginBean.getLoginRole());
|
||||
}
|
||||
if (loginName != null) {
|
||||
root.put("loginName", loginName);
|
||||
|
||||
securityLevel = Integer.parseInt(loginBean.getLoginRole());
|
||||
if (securityLevel >= FILTER_SECURITY_LEVEL) {
|
||||
ApplicationBean appBean = vreq.getAppBean();
|
||||
if (appBean.isFlag1Active()) {
|
||||
root.put("showFlag1SearchField", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
securityLevel = Integer.parseInt(loginBean.getLoginRole());
|
||||
if (securityLevel >= FILTER_SECURITY_LEVEL) {
|
||||
ApplicationBean appBean = vreq.getAppBean();
|
||||
if (appBean.isFlag1Active()) {
|
||||
root.put("showFlag1SearchField", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void setCopyrightInfo() {
|
||||
private final void setCopyrightInfo() {
|
||||
|
||||
String copyrightText = portal.getCopyrightAnchor();
|
||||
if ( ! StringUtils.isEmpty(copyrightText) ) {
|
||||
|
@ -289,13 +245,13 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
copyright.put("url", portal.getCopyrightURL());
|
||||
root.put("copyright", copyright);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void setThemeInfo(String themeDir) {
|
||||
private final void setThemeInfo(String themeDir) {
|
||||
|
||||
// This value will be available to any template as a path for adding a new stylesheet.
|
||||
// It does not contain the context path, because the methods to generate the href
|
||||
// attribute from the string passed in by the template automatically add the context path.
|
||||
// This value will be available to any template as a path for adding a new stylesheet.
|
||||
// It does not contain the context path, because the methods to generate the href
|
||||
// attribute from the string passed in by the template automatically add the context path.
|
||||
setSharedVariable("stylesheetDir", themeDir + "/css");
|
||||
|
||||
String themeDirWithContext = getUrl(themeDir);
|
||||
|
@ -305,41 +261,107 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
|
||||
setSharedVariable("siteIconPath", themeDirWithContext + "/site_icons");
|
||||
|
||||
}
|
||||
|
||||
// Default case is to set title first, because it's used in the body. However, in some cases
|
||||
// the title is based on values computed during compilation of the body (e.g., IndividualListController).
|
||||
// Individual controllers can override this method to set title and body together. End result must be:
|
||||
// body is added to root with key "body"
|
||||
// title is set as a shared variable with key "title"
|
||||
// This can be achieved by making sure setBody() and setTitle() are called.
|
||||
protected void setTitleAndBody() {
|
||||
setTitle();
|
||||
setBody();
|
||||
}
|
||||
|
||||
protected void setBody() {
|
||||
root.put("body", getBody());
|
||||
}
|
||||
|
||||
// Define template locations. Template loader will look first in the theme-specific
|
||||
// location, then in the vitro location.
|
||||
// RY We cannot do this in FreeMarkerSetup because (a) the theme depends on the portal,
|
||||
// and we have multi-portal installations, and (b) we need to support theme-switching on the fly.
|
||||
// To make more efficient, we could do this once, and then have a listener that does it again
|
||||
// when theme is switched. BUT this doesn't support (a), only (b), so we have to do it on every request.
|
||||
protected final void setTemplateLoader() {
|
||||
protected String getBody() {
|
||||
return ""; // body should never be null
|
||||
}
|
||||
|
||||
String themeTemplateDir = context.getRealPath(getThemeDir()) + "/ftl";
|
||||
String vitroTemplateDir = context.getRealPath("/templates/freemarker");
|
||||
protected void setTitle() {
|
||||
String title = getTitle();
|
||||
// If the individual controller fails to assign a non-null, non-empty title
|
||||
if (StringUtils.isEmpty(title)) {
|
||||
title = appName;
|
||||
}
|
||||
// Title is a shared variable because it's used in both body and head elements.
|
||||
setSharedVariable("title", title);
|
||||
}
|
||||
|
||||
protected String getTitle() {
|
||||
return "";
|
||||
}
|
||||
|
||||
protected void setSharedVariable(String key, Object value) {
|
||||
try {
|
||||
FileTemplateLoader themeFtl = new FileTemplateLoader(new File(themeTemplateDir));
|
||||
FileTemplateLoader vitroFtl = new FileTemplateLoader(new File(vitroTemplateDir));
|
||||
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
|
||||
TemplateLoader[] loaders = new TemplateLoader[] { themeFtl, vitroFtl, ctl };
|
||||
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
|
||||
config.setTemplateLoader(mtl);
|
||||
} catch (IOException e) {
|
||||
log.error("Error loading templates");
|
||||
config.setSharedVariable(key, value);
|
||||
} catch (TemplateModelException e) {
|
||||
log.error("Can't set shared variable '" + key + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
protected StringWriter mergeToTemplate(String templateName, Map<String, Object> map) {
|
||||
|
||||
private TabMenu getTabMenu() {
|
||||
return new TabMenu(vreq, portalId);
|
||||
}
|
||||
Template template = null;
|
||||
try {
|
||||
template = config.getTemplate(templateName);
|
||||
} catch (IOException e) {
|
||||
log.error("Cannot get template " + templateName);
|
||||
}
|
||||
StringWriter sw = new StringWriter();
|
||||
if (template != null) {
|
||||
try {
|
||||
template.process(map, sw);
|
||||
} catch (TemplateException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return sw;
|
||||
}
|
||||
|
||||
protected String mergeBodyToTemplate(String templateName, Map<String, Object> map) {
|
||||
templateName = "body/" + templateName;
|
||||
String body = mergeToTemplate(templateName, map).toString();
|
||||
return body;
|
||||
}
|
||||
|
||||
protected void write(HttpServletResponse response) {
|
||||
|
||||
String templateName = "page/" + getPageTemplateName();
|
||||
|
||||
StringWriter sw = mergeToTemplate(templateName, root);
|
||||
try {
|
||||
PrintWriter out = response.getWriter();
|
||||
out.print(sw);
|
||||
} catch (IOException e) {
|
||||
log.error("FreeMarkerHttpServlet cannot write output");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Can be overridden by individual controllers
|
||||
protected String getPageTemplateName() {
|
||||
return "default.ftl";
|
||||
}
|
||||
|
||||
|
||||
public static boolean isConfigured() {
|
||||
return config != null;
|
||||
}
|
||||
|
||||
// TEMPORARY for transition from JSP to FreeMarker. Once transition
|
||||
// is complete and no more pages are generated in JSP, this can be removed.
|
||||
// Do this if FreeMarker is configured (i.e., not Datastar) and if we are not in
|
||||
// a FreeMarkerHttpServlet, which will generate identity, menu, and footer from the page template.
|
||||
// It's a static method because it needs to be called from JSPs that don't go through a servlet.
|
||||
// It's a static method because it needs to be called from JSPs that don't go through a servlet.
|
||||
public static void getFreeMarkerComponentsForJsp(HttpServletRequest request, HttpServletResponse response) {
|
||||
FreeMarkerComponentGenerator fcg = new FreeMarkerComponentGenerator(request, response);
|
||||
request.setAttribute("ftl_identity", fcg.getIdentity());
|
||||
|
@ -348,11 +370,7 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
|||
request.setAttribute("ftl_footer", fcg.getFooter());
|
||||
}
|
||||
|
||||
public static boolean isConfigured() {
|
||||
return config != null;
|
||||
}
|
||||
|
||||
/* ******************** Utilities ******************* */
|
||||
/* ******************** Static utilities ******************* */
|
||||
|
||||
public static String getUrl(String path) {
|
||||
if ( ! path.startsWith("/") ) {
|
||||
|
|
|
@ -2,144 +2,119 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.view.IndividualView;
|
||||
|
||||
/**
|
||||
* Generates a list of individuals for display in a template
|
||||
*/
|
||||
public class IndividualListController extends FreeMarkerHttpServlet {
|
||||
|
||||
long startTime = -1;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log log = LogFactory.getLog(IndividualListController.class.getName());
|
||||
private VClass vclass = null;
|
||||
private String title = null;
|
||||
|
||||
/**
|
||||
* This generates a list of entities and then sends that
|
||||
* off to a jsp to be displayed.
|
||||
*
|
||||
* Expected parameters:
|
||||
*
|
||||
* Expected Attributes:
|
||||
* entity - set to entity to display properties for.
|
||||
*
|
||||
* @author bdc34
|
||||
*/
|
||||
protected void setTitleAndBody() {
|
||||
setBody();
|
||||
}
|
||||
|
||||
protected String getBody() {
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
String bodyTemplate = "individualList.ftl";
|
||||
String errorMessage = null;
|
||||
String message = null;
|
||||
|
||||
// TODO Rewrite error cases to use FreeMarker templates. Restructure so we're always doing the body
|
||||
// and then calling writeOutput().
|
||||
public void doGet( HttpServletRequest req, HttpServletResponse res )
|
||||
throws IOException, ServletException {
|
||||
startTime = System.currentTimeMillis(); // TODO: remove
|
||||
try {
|
||||
super.doSetup(req, res);
|
||||
Object obj = vreq.getAttribute("vclass");
|
||||
vclass=null;
|
||||
if( obj == null ) { // look for vitroclass id parameter
|
||||
String vitroClassIdStr=req.getParameter("vclassId");
|
||||
if (vitroClassIdStr!=null && !vitroClassIdStr.equals("")) {
|
||||
vclass = null;
|
||||
if ( obj == null ) { // look for vitroclass id parameter
|
||||
String vitroClassIdStr = vreq.getParameter("vclassId");
|
||||
if ( !StringUtils.isEmpty(vitroClassIdStr)) {
|
||||
try {
|
||||
//TODO have to change this so vclass's group and entity count are populated
|
||||
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr);
|
||||
if (vclass == null) {
|
||||
log.error("Couldn't retrieve vclass "+vitroClassIdStr);
|
||||
response.sendRedirect(Routes.BROWSE + "?"+vreq.getQueryString());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new HelpException("IndividualListController: request parameter 'vclassId' must be a URI string");
|
||||
//TODO have to change this so vclass's group and entity count are populated
|
||||
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr);
|
||||
if (vclass == null) {
|
||||
log.error("Couldn't retrieve vclass " + vitroClassIdStr);
|
||||
errorMessage = "Class " + vitroClassIdStr + " not found";
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new HelpException("IndividualListController: request parameter 'vclassId' must be a URI string.");
|
||||
}
|
||||
}
|
||||
} else if (obj instanceof VClass) {
|
||||
vclass = (VClass)obj;
|
||||
} else {
|
||||
throw new HelpException("IndividualListController: attribute 'vclass' must be of type "
|
||||
+ VClass.class.getName() );
|
||||
+ VClass.class.getName() + ".");
|
||||
}
|
||||
if (vclass!=null){
|
||||
setBody();
|
||||
write(response);
|
||||
|
||||
if (vclass != null) {
|
||||
// Create list of individual view objects
|
||||
List<Individual> individualList = vreq.getWebappDaoFactory().getIndividualDao().getIndividualsByVClass(vclass);
|
||||
List<IndividualView> individuals = new ArrayList<IndividualView>(individualList.size());
|
||||
|
||||
if (individualList == null) {
|
||||
// RY Is this really an error?
|
||||
log.error("individuals list is null");
|
||||
message = "No individuals to display.";
|
||||
} else {
|
||||
for (Individual i: individualList) {
|
||||
individuals.add(new IndividualView(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Set title and subtitle. Title will be retrieved later in getTitle().
|
||||
VClassGroup classGroup = vclass.getGroup();
|
||||
if (classGroup == null) {
|
||||
title = vclass.getName();
|
||||
} else {
|
||||
title = classGroup.getPublicName();
|
||||
body.put("subtitle", vclass.getName());
|
||||
}
|
||||
|
||||
body.put("individuals", individuals);
|
||||
}
|
||||
// RY Rewrite error cases for FreeMarker, not JSP
|
||||
|
||||
} catch (HelpException help){
|
||||
doHelp(response);
|
||||
errorMessage = "Request attribute 'vclass' or request parameter 'vclassId' must be set before calling. Its value must be a class uri.";
|
||||
} catch (Throwable e) {
|
||||
vreq.setAttribute("javax.servlet.jsp.jspException",e);
|
||||
RequestDispatcher rd = req.getRequestDispatcher("/error.jsp");
|
||||
rd.forward(vreq, response);
|
||||
}
|
||||
}
|
||||
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException,IOException {
|
||||
doGet(request, response);
|
||||
}
|
||||
|
||||
protected String getBody() {
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
// Create list of individuals
|
||||
List<Individual> individualList = vreq.getWebappDaoFactory().getIndividualDao().getIndividualsByVClass(vclass);
|
||||
List<IndividualView> individuals = new ArrayList<IndividualView>(individualList.size());
|
||||
Iterator<Individual> i = individualList.iterator();
|
||||
while (i.hasNext()) {
|
||||
individuals.add(new IndividualView(i.next()));
|
||||
}
|
||||
body.put("individuals", individuals);
|
||||
|
||||
// But the JSP version includes url rewriting via URLRewritingHttpServletResponse
|
||||
// RY *** FIX - define getUrl method of IndividualView
|
||||
body.put("individualUrl", getUrl("/entity?home=" + portalId + "&uri="));
|
||||
|
||||
if (individuals == null) {
|
||||
log.error("individuals list is null");
|
||||
bodyTemplate = "error.ftl";
|
||||
}
|
||||
|
||||
// Use instead of getTitle(), because we have a subtitle too
|
||||
String title = "";
|
||||
VClassGroup classGroup=vclass.getGroup();
|
||||
if (classGroup==null) {
|
||||
title = vclass.getName();
|
||||
} else {
|
||||
title = classGroup.getPublicName();
|
||||
setSharedVariable("subTitle", vclass.getName());
|
||||
if (errorMessage != null) {
|
||||
bodyTemplate = "errorMessage.ftl";
|
||||
body.put("errorMessage", errorMessage);
|
||||
} else if (message != null) {
|
||||
body.put("message", message);
|
||||
}
|
||||
setSharedVariable("title", title);
|
||||
|
||||
String templateName = "individualList.ftl";
|
||||
return mergeBodyToTemplate(templateName, body);
|
||||
setTitle();
|
||||
|
||||
return mergeBodyToTemplate(bodyTemplate, body);
|
||||
}
|
||||
|
||||
// RY Rewrite as a template
|
||||
private void doHelp(HttpServletResponse res)
|
||||
throws IOException, ServletException {
|
||||
ServletOutputStream out = res.getOutputStream();
|
||||
res.setContentType("text/html; charset=UTF-8");
|
||||
out.println("<html><body><h2>Quick Notes on using EntityList:</h2>");
|
||||
out.println("<p>request.attributes 'entities' must be set by servlet before calling."
|
||||
+" It must be a List of Entity objects </p>");
|
||||
out.println("</body></html>");
|
||||
protected String getTitle() {
|
||||
// The title is determined during compilation of the body, so we put it in an instance variable
|
||||
// to be retrieved later.
|
||||
return title;
|
||||
}
|
||||
|
||||
private class HelpException extends Throwable{
|
||||
private class HelpException extends Throwable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public HelpException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public class Routes {
|
|||
public static final String BROWSE = "/browse";
|
||||
public static final String COMMENT_FORM = "/comments";
|
||||
public static final String INDIVIDUAL = "/individual";
|
||||
public static final String INDIVIDUAL_LIST = "/entitylist"; // "/individuallist";
|
||||
public static final String INDIVIDUAL_LIST = "/individuallist"; // "/entitylist"; "/individuallist";
|
||||
public static final String SEARCH = "/search";
|
||||
public static final String TERMS_OF_USE = "/termsOfUse";
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ public class IndividualView extends ViewObject {
|
|||
return individual.getName();
|
||||
}
|
||||
|
||||
// RY However, the moniker should undergo p:process but the class name shouldn't!
|
||||
// So, it needs to be callable from Java.
|
||||
public String getTagline() {
|
||||
String tagline = individual.getMoniker();
|
||||
return StringUtils.isEmpty(tagline) ? individual.getVClass().getName() : tagline;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#-- Comment form -->
|
||||
<#-- Contact form -->
|
||||
|
||||
<div class="staticPageBackground feedbackForm">
|
||||
|
||||
|
|
7
webapp/web/templates/freemarker/body/error.ftl
Normal file
7
webapp/web/templates/freemarker/body/error.ftl
Normal file
|
@ -0,0 +1,7 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#-- Template for general system error. -->
|
||||
|
||||
<p>There was an error in the system.</p>
|
||||
|
||||
<p>Return to the <a href="${urls.home}">home page</a>.</p>
|
7
webapp/web/templates/freemarker/body/errorMessage.ftl
Normal file
7
webapp/web/templates/freemarker/body/errorMessage.ftl
Normal file
|
@ -0,0 +1,7 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#-- Standard template to display an error message generated from any controller. Keeps this out of individual templates. -->
|
||||
|
||||
<#if errorMessage??>
|
||||
<p>${errorMessage}</p>
|
||||
</#if>
|
|
@ -7,16 +7,21 @@
|
|||
<div class="individualList">
|
||||
<h2>${title}</h2>
|
||||
<#if subtitle??>
|
||||
<h4>${subTitle}"</h4>
|
||||
<h4>${subtitle}</h4>
|
||||
</#if>
|
||||
|
||||
<#-- RY NEED TO ACCOUNT FOR p:process stuff -->
|
||||
<ul>
|
||||
<#list individuals as individual>
|
||||
<li>
|
||||
<a href="${individual.profileUrl}">${individual.name}</a> ${individual.tagline}
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
<#if message??>
|
||||
<p>${message}</p>
|
||||
<#else>
|
||||
<#-- RY NEED TO ACCOUNT FOR p:process stuff -->
|
||||
<ul>
|
||||
<#list individuals as individual>
|
||||
<li>
|
||||
<a href="${individual.profileUrl}">${individual.name}</a> ${individual.tagline}
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue