Updates to ViewFinder class to find custom templates
This commit is contained in:
parent
d48efa96cf
commit
ff0aa17398
4 changed files with 85 additions and 56 deletions
|
@ -30,6 +30,7 @@ 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.BreadCrumbsUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.files.Scripts;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.files.Stylesheets;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.TabMenu;
|
||||
|
@ -57,7 +58,10 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
|
||||
try {
|
||||
VitroRequest vreq = new VitroRequest(request);
|
||||
BaseTemplateModel.setVitroRequest(vreq);
|
||||
|
||||
Configuration config = getConfig(vreq);
|
||||
vreq.setAttribute("freemarkerConfig", config);
|
||||
|
||||
// We can't use shared variables in the Freemarker configuration to store anything
|
||||
// except theme-specific data, because multiple portals or apps might share the same theme. So instead
|
||||
|
@ -127,7 +131,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
config.setTemplateUpdateDelay(60); // in seconds; Freemarker default is 5
|
||||
}
|
||||
|
||||
// Specify how templates will see the data-model.
|
||||
// Specify how templates will see the data model.
|
||||
// The default wrapper exposes set methods unless exposure level is set.
|
||||
// By default we want to block exposure of set methods.
|
||||
BeansWrapper wrapper = new DefaultObjectWrapper();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
@ -14,7 +14,10 @@ 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.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
|
||||
/**
|
||||
* Class to find custom class views for individuals
|
||||
|
@ -23,23 +26,22 @@ import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
|
|||
*/
|
||||
public class ViewFinder {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ViewFinder.class.getName());
|
||||
private static final Log log = LogFactory.getLog(ViewFinder.class);
|
||||
|
||||
public enum ClassView {
|
||||
DISPLAY("getCustomDisplayView", "/view-display"),
|
||||
// NB this is not the value currently used for custom forms - we use the value on the object property
|
||||
FORM("getCustomEntryForm", "/form"),
|
||||
SEARCH("getCustomSearchView", "/view-search"),
|
||||
SHORT("getCustomShortView", "/view-short");
|
||||
|
||||
private static String TEMPLATE_PATH = "/templates/freemarker";
|
||||
DISPLAY("getCustomDisplayView", "view-display-default.ftl"),
|
||||
// NB this is not the value currently used for custom forms - we use the value on the object property.
|
||||
// This value is specifiable from the backend editor, however.
|
||||
FORM("getCustomEntryForm", "form-default.ftl"),
|
||||
SEARCH("getCustomSearchView", "view-search-default.ftl"),
|
||||
SHORT("getCustomShortView", "view-short-default.ftl");
|
||||
|
||||
private Method method = null;
|
||||
private String path = null;
|
||||
private String defaultTemplate = null;
|
||||
|
||||
ClassView(String methodName, String path) {
|
||||
ClassView(String methodName, String defaultTemplate) {
|
||||
Class<VClass> vc = VClass.class;
|
||||
this.path = path;
|
||||
this.defaultTemplate = defaultTemplate;
|
||||
try {
|
||||
method = vc.getMethod(methodName);
|
||||
} catch (SecurityException e) {
|
||||
|
@ -53,9 +55,9 @@ public class ViewFinder {
|
|||
return method;
|
||||
}
|
||||
|
||||
protected String getPath() {
|
||||
return TEMPLATE_PATH + path;
|
||||
}
|
||||
protected String getDefaultTemplate() {
|
||||
return defaultTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -65,10 +67,11 @@ public class ViewFinder {
|
|||
this.view = view;
|
||||
}
|
||||
|
||||
public String findClassView(Individual individual, ServletContext context) {
|
||||
String viewName = "default.ftl";
|
||||
List<VClass> vclasses = individual.getVClasses();
|
||||
public String findClassView(Individual individual, ServletContext context, VitroRequest vreq) {
|
||||
String templateName = view.getDefaultTemplate();
|
||||
Method method = view.getMethod();
|
||||
TemplateLoader templateLoader = ((Configuration) vreq.getAttribute("freemarkerConfig")).getTemplateLoader();
|
||||
|
||||
/* 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
|
||||
|
@ -87,27 +90,56 @@ public class ViewFinder {
|
|||
* RY 7/19/10 Use distinction between asserted and inferred vclasses
|
||||
* as a starting point: see MiscWebUtils.getCustomShortView().
|
||||
*/
|
||||
List<VClass> vclasses = individual.getVClasses();
|
||||
String customTemplate = null;
|
||||
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().");
|
||||
customTemplate = findCustomTemplateForVClass(vc, method, templateLoader);
|
||||
if (customTemplate != null) {
|
||||
templateName = customTemplate;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return viewName;
|
||||
log.debug("Using template " + templateName + " for individual " + individual.getName());
|
||||
return templateName;
|
||||
}
|
||||
|
||||
private String findCustomTemplateForVClass(VClass vclass, Method method, TemplateLoader templateLoader) {
|
||||
String customTemplate = null;
|
||||
String vClassCustomTemplate = null;
|
||||
|
||||
try {
|
||||
vClassCustomTemplate = (String) method.invoke(vclass);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.error("Incorrect arguments passed to method " + method.getName() + " in findCustomTemplateForVClass().");
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("Method " + method.getName() + " cannot be accessed in findCustomTemplateForVClass().");
|
||||
} catch (InvocationTargetException e) {
|
||||
log.error("Exception thrown by method " + method.getName() + " in findCustomTemplateForVClass().");
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(vClassCustomTemplate)) {
|
||||
log.debug("Custom template " + vClassCustomTemplate + " defined for class " + vclass.getName());
|
||||
try {
|
||||
// Make sure the template exists
|
||||
if (templateLoader.findTemplateSource(vClassCustomTemplate) != null) {
|
||||
log.debug("Found defined custom template " + vClassCustomTemplate + " for class " + vclass.getName());
|
||||
customTemplate = vClassCustomTemplate;
|
||||
} else {
|
||||
log.warn("Custom template " + vClassCustomTemplate + " for class " + vclass.getName() + " defined but does not exist.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("IOException looking for source for template " + vClassCustomTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
if (customTemplate != null) {
|
||||
log.debug("Using custom template " + customTemplate + " for class " + vclass.getName());
|
||||
} else {
|
||||
log.debug("No custom template found for class " + vclass.getName());
|
||||
}
|
||||
}
|
||||
return customTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import javax.servlet.ServletContext;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
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.Params;
|
||||
|
||||
|
@ -15,6 +16,7 @@ public abstract class BaseTemplateModel {
|
|||
private static final Log log = LogFactory.getLog(BaseTemplateModel.class.getName());
|
||||
|
||||
protected static ServletContext servletContext = null;
|
||||
protected static VitroRequest vreq = null;
|
||||
|
||||
// Wrap UrlBuilder method so templates can call ${item.url}
|
||||
public String getUrl(String path) {
|
||||
|
@ -31,28 +33,19 @@ public abstract class BaseTemplateModel {
|
|||
}
|
||||
|
||||
public static void setServletContext(ServletContext context) {
|
||||
BaseTemplateModel.servletContext = context;
|
||||
servletContext = context;
|
||||
}
|
||||
|
||||
public static VitroRequest getVitroRequest() {
|
||||
return vreq;
|
||||
}
|
||||
|
||||
public static void setVitroRequest(VitroRequest vrequest) {
|
||||
vreq = vrequest;
|
||||
}
|
||||
|
||||
public String dump() {
|
||||
return "I'm a BaseTemplateModel object";
|
||||
}
|
||||
|
||||
/*
|
||||
* public static List<?> wrapList(List<?> list, Class cl)
|
||||
* throw error if cl not a child of ViewObject
|
||||
* This block of code is going to be repeated a lot:
|
||||
List<VClassGroup> groups = // code to get the data
|
||||
List<VClassGroupView> vcgroups = new ArrayList<VClassGroupView>(groups.size());
|
||||
Iterator<VClassGroup> i = groups.iterator();
|
||||
while (i.hasNext()) {
|
||||
vcgroups.add(new VClassGroupView(i.next()));
|
||||
}
|
||||
body.put("classGroups", vcgroups);
|
||||
Can we generalize it to a generic method of ViewObject - wrapList() ?
|
||||
static method of ViewObject
|
||||
Params: groups, VClassGroupView (the name of the class) - but must be a child of ViewObject
|
||||
Return: List<viewObjectType>
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class IndividualTemplateModel extends BaseTemplateModel {
|
|||
|
||||
private String getView(ClassView view) {
|
||||
ViewFinder vf = new ViewFinder(view);
|
||||
return vf.findClassView(individual, servletContext);
|
||||
return vf.findClassView(individual, servletContext, vreq);
|
||||
}
|
||||
|
||||
public Link getPrimaryLink() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue