Handle custom search views used on individual list page.
This commit is contained in:
parent
a4f652ddbf
commit
c2fa2c4e37
9 changed files with 143 additions and 39 deletions
|
@ -25,7 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Routes;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
||||||
import edu.cornell.mannlib.vitro.webapp.view.fileList.ScriptList;
|
import edu.cornell.mannlib.vitro.webapp.view.fileList.ScriptList;
|
||||||
import edu.cornell.mannlib.vitro.webapp.view.fileList.StylesheetList;
|
import edu.cornell.mannlib.vitro.webapp.view.fileList.StylesheetList;
|
||||||
|
@ -180,15 +180,15 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
|
||||||
root.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
|
root.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
|
||||||
}
|
}
|
||||||
|
|
||||||
urls.put("about", urlBuilder.getPortalUrl(Routes.ABOUT));
|
urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT));
|
||||||
if (ContactMailServlet.getSmtpHostFromProperties() != null) {
|
if (ContactMailServlet.getSmtpHostFromProperties() != null) {
|
||||||
urls.put("contact", urlBuilder.getPortalUrl(Routes.CONTACT));
|
urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT));
|
||||||
}
|
}
|
||||||
urls.put("search", urlBuilder.getPortalUrl(Routes.SEARCH));
|
urls.put("search", urlBuilder.getPortalUrl(Route.SEARCH));
|
||||||
urls.put("termsOfUse", urlBuilder.getPortalUrl(Routes.TERMS_OF_USE));
|
urls.put("termsOfUse", urlBuilder.getPortalUrl(Route.TERMS_OF_USE));
|
||||||
urls.put("login", urlBuilder.getPortalUrl(Routes.LOGIN));
|
urls.put("login", urlBuilder.getPortalUrl(Route.LOGIN));
|
||||||
urls.put("logout", urlBuilder.getLogoutUrl());
|
urls.put("logout", urlBuilder.getLogoutUrl());
|
||||||
urls.put("siteAdmin", urlBuilder.getPortalUrl(Routes.LOGIN));
|
urls.put("siteAdmin", urlBuilder.getPortalUrl(Route.LOGIN));
|
||||||
|
|
||||||
setSharedVariable("urls", urls);
|
setSharedVariable("urls", urls);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
|
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet;
|
import edu.cornell.mannlib.vitro.webapp.view.ViewObject;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.DefaultObjectWrapper;
|
import freemarker.template.DefaultObjectWrapper;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
|
@ -52,7 +52,7 @@ public class FreeMarkerSetup implements ServletContextListener {
|
||||||
|
|
||||||
FreeMarkerHttpServlet.config = cfg;
|
FreeMarkerHttpServlet.config = cfg;
|
||||||
FreeMarkerHttpServlet.context = sc;
|
FreeMarkerHttpServlet.context = sc;
|
||||||
|
ViewObject.context = sc;
|
||||||
UrlBuilder.contextPath = sc.getContextPath();
|
UrlBuilder.contextPath = sc.getContextPath();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,22 +18,17 @@ public class UrlBuilder {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(UrlBuilder.class.getName());
|
private static final Log log = LogFactory.getLog(UrlBuilder.class.getName());
|
||||||
|
|
||||||
|
protected static String contextPath = null;
|
||||||
|
private static boolean addPortalParam = PortalPickerFilter.isPortalPickingActive();
|
||||||
|
|
||||||
private Portal portal;
|
private Portal portal;
|
||||||
|
|
||||||
// This is static so that getUrl() can be static and refer to contextPath.
|
public enum Route {
|
||||||
// getUrl() is static so that view objects can call it without
|
|
||||||
// having to instantiate an object and inject knowledge of the context path, which
|
|
||||||
// they don't have.
|
|
||||||
protected static String contextPath = null;
|
|
||||||
|
|
||||||
private static boolean isMultiPortal = PortalPickerFilter.isPortalPickingActive();
|
|
||||||
|
|
||||||
public enum Routes {
|
|
||||||
ABOUT("/about"),
|
ABOUT("/about"),
|
||||||
BROWSE("/browse"),
|
BROWSE("/browse"),
|
||||||
CONTACT("/contact"),
|
CONTACT("/contact"),
|
||||||
INDIVIDUAL("/individual"),
|
INDIVIDUAL("/individual"),
|
||||||
INDIVIDUAL_LIST("/entitylist"), // "/individuallist"
|
INDIVIDUAL_LIST("/individuallist"), // individuallist entitylist
|
||||||
SEARCH("/search"),
|
SEARCH("/search"),
|
||||||
TERMS_OF_USE("/termsOfUse"),
|
TERMS_OF_USE("/termsOfUse"),
|
||||||
|
|
||||||
|
@ -44,7 +39,7 @@ public class UrlBuilder {
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
|
|
||||||
Routes(String path) {
|
Route(String path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +70,7 @@ public class UrlBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLogoutUrl() {
|
public String getLogoutUrl() {
|
||||||
return getPortalUrl(Routes.LOGOUT.url(), new Params("loginSubmitMode", "logout"));
|
return getPortalUrl(Route.LOGOUT.url(), new Params("loginSubmitMode", "logout"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Params getPortalParam() {
|
public Params getPortalParam() {
|
||||||
|
@ -83,21 +78,21 @@ public class UrlBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPortalUrl(String path) {
|
public String getPortalUrl(String path) {
|
||||||
return isMultiPortal ? getUrl(path, getPortalParam()) : getUrl(path);
|
return addPortalParam ? getUrl(path, getPortalParam()) : getUrl(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPortalUrl(String path, Params params) {
|
public String getPortalUrl(String path, Params params) {
|
||||||
if (isMultiPortal) {
|
if (addPortalParam) {
|
||||||
params.putAll(getPortalParam());
|
params.putAll(getPortalParam());
|
||||||
}
|
}
|
||||||
return getUrl(path, params);
|
return getUrl(path, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPortalUrl(Routes route) {
|
public String getPortalUrl(Route route) {
|
||||||
return getPortalUrl(route.path());
|
return getPortalUrl(route.path());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPortalUrl(Routes route, Params params) {
|
public String getPortalUrl(Route route, Params params) {
|
||||||
return getPortalUrl(route.path(), params);
|
return getPortalUrl(route.path(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,15 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Routes;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.view.ViewFinder.ClassView;
|
||||||
|
|
||||||
public class IndividualView extends ViewObject {
|
public class IndividualView extends ViewObject {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(IndividualView.class.getName());
|
private static final Log log = LogFactory.getLog(IndividualView.class.getName());
|
||||||
|
|
||||||
private static final String PATH = Routes.INDIVIDUAL.path();
|
private static final String PATH = Route.INDIVIDUAL.path();
|
||||||
|
|
||||||
private Individual individual;
|
private Individual individual;
|
||||||
|
|
||||||
|
@ -44,13 +45,10 @@ public class IndividualView extends ViewObject {
|
||||||
return getUrl("/individual/" + individual.getLocalName());
|
return getUrl("/individual/" + individual.getLocalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getListView() {
|
public String getSearchView() {
|
||||||
// TODO
|
|
||||||
// iterate through class hierarchy looking for a custom short view. If none, use
|
ViewFinder vf = new ViewFinder(ClassView.SEARCH);
|
||||||
// default individual short view. template will just do an include on individual.shortView
|
return vf.findView(individual, context);
|
||||||
// Use individual.getVClasses() - this is the class hierarchy
|
|
||||||
// Question: what order are they returned in ? If from specific to general, break out of the iteration as soon as we find one.
|
|
||||||
return "defaultIndividualListView.ftl";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCustomView() {
|
public String getCustomView() {
|
||||||
|
|
|
@ -7,12 +7,12 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Params;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Params;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Routes;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
|
|
||||||
public class VClassView extends ViewObject {
|
public class VClassView extends ViewObject {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(VClassView.class.getName());
|
private static final Log log = LogFactory.getLog(VClassView.class.getName());
|
||||||
private static final String PATH = Routes.INDIVIDUAL_LIST.path();
|
private static final String PATH = Route.INDIVIDUAL_LIST.path();
|
||||||
|
|
||||||
private VClass vclass;
|
private VClass vclass;
|
||||||
|
|
||||||
|
|
107
webapp/src/edu/cornell/mannlib/vitro/webapp/view/ViewFinder.java
Normal file
107
webapp/src/edu/cornell/mannlib/vitro/webapp/view/ViewFinder.java
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.view;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
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.utils.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to find custom class views for individuals
|
||||||
|
* @author rjy7
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ViewFinder {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(ViewFinder.class.getName());
|
||||||
|
|
||||||
|
public enum ClassView {
|
||||||
|
DISPLAY("getCustomDisplayView", "/view/display"),
|
||||||
|
FORM("getCustomEntryForm", "/form"),
|
||||||
|
SEARCH("getCustomSearchView", "/view/search"),
|
||||||
|
SHORT("getCustomShortView", "/view/short");
|
||||||
|
|
||||||
|
private static String TEMPLATE_PATH = "/templates/freemarker/body/partials/class";
|
||||||
|
|
||||||
|
private Method method = null;
|
||||||
|
private String path = null;
|
||||||
|
|
||||||
|
ClassView(String methodName, String path) {
|
||||||
|
Class<VClass> vc = VClass.class;
|
||||||
|
this.path = path;
|
||||||
|
try {
|
||||||
|
method = vc.getMethod(methodName);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
log.error("Access denied to method " + methodName + " or class " + vc.getName());
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
log.error("Method " + methodName + " not defined for class " + vc.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Method getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getPath() {
|
||||||
|
return TEMPLATE_PATH + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassView view;
|
||||||
|
|
||||||
|
public ViewFinder(ClassView view) {
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String findView(Individual individual, ServletContext context) {
|
||||||
|
String viewName = "default.ftl";
|
||||||
|
// For now, all custom views are attached to classes.
|
||||||
|
List<VClass> vclasses = individual.getVClasses();
|
||||||
|
Method method = view.getMethod();
|
||||||
|
/* RY The logic here is incorrect. The vclasses are
|
||||||
|
* returned in a random order, whereas we need to
|
||||||
|
* traverse the class hierarchy and find the most
|
||||||
|
* specific custom view applicable to the individual.
|
||||||
|
* The logic is complex because individuals can belong
|
||||||
|
* to multiple classes, and classes can subclass multiple
|
||||||
|
* classes. If there are two competing custom views at the
|
||||||
|
* same level of specificity, what should we do? Also, if we
|
||||||
|
* are displaying a list of individuals belonging to a certain
|
||||||
|
* class, we may want to use only a custom view defined for that
|
||||||
|
* class and NOT a more specific one. See NIHVIVO-568.
|
||||||
|
*/
|
||||||
|
for (VClass vc : vclasses) {
|
||||||
|
try {
|
||||||
|
String v = (String) method.invoke(vc);
|
||||||
|
if (!StringUtils.isEmpty(v)) {
|
||||||
|
String pathToView = context.getRealPath(view.getPath() + "/" + v);
|
||||||
|
File viewFile = new File(pathToView);
|
||||||
|
if (viewFile.isFile() && viewFile.canRead()) {
|
||||||
|
viewName = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.error("Incorrect arguments passed to method " + method.getName() + " in findView().");
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
log.error("Method " + method.getName() + " cannot be accessed in findView().");
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
log.error("Exception thrown by method " + method.getName() + " in findView().");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return viewName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.view;
|
package edu.cornell.mannlib.vitro.webapp.view;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
@ -12,6 +14,8 @@ public abstract class ViewObject {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ViewObject.class.getName());
|
private static final Log log = LogFactory.getLog(ViewObject.class.getName());
|
||||||
|
|
||||||
|
public static ServletContext context = 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) {
|
||||||
return UrlBuilder.getUrl(path);
|
return UrlBuilder.getUrl(path);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<#list individuals as individual>
|
<#list individuals as individual>
|
||||||
<li>
|
<li>
|
||||||
<#include "partials/defaultIndividualListView.ftl">
|
<#include "partials/class/view/search/${individual.searchView}">
|
||||||
</li>
|
</li>
|
||||||
</#list>
|
</#list>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
Loading…
Add table
Reference in a new issue