NIHVIVO-3547 Move the "stylesheets", "scripts", and "headscripts" variables from the FreemarkerConfiguration, where they are effectively singletons, to the data model map, where they are created for each separate request.
This commit is contained in:
parent
70e3bd6503
commit
6bce20b84e
4 changed files with 26 additions and 57 deletions
|
@ -36,7 +36,6 @@ public class FreemarkerComponentGenerator extends FreemarkerHttpServlet {
|
|||
VitroRequest vreq = new VitroRequest(request);
|
||||
FreemarkerConfiguration config = getConfig(vreq);
|
||||
vreq.setAttribute("freemarkerConfig", config);
|
||||
config.resetRequestSpecificSharedVariables();
|
||||
Map<String, Object> map = getPageTemplateValues(vreq);
|
||||
|
||||
request.setAttribute("ftl_head", getHead("head", map, config, vreq));
|
||||
|
|
|
@ -5,14 +5,12 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
@ -21,8 +19,6 @@ import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
|||
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags.TagsWrapper;
|
||||
import freemarker.cache.ClassTemplateLoader;
|
||||
import freemarker.cache.FileTemplateLoader;
|
||||
import freemarker.cache.MultiTemplateLoader;
|
||||
|
@ -31,7 +27,6 @@ import freemarker.ext.beans.BeansWrapper;
|
|||
import freemarker.template.Configuration;
|
||||
import freemarker.template.DefaultObjectWrapper;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateModel;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
public class FreemarkerConfiguration extends Configuration {
|
||||
|
@ -42,9 +37,6 @@ public class FreemarkerConfiguration extends Configuration {
|
|||
private final ServletContext context;
|
||||
private final ApplicationBean appBean;
|
||||
private final String appName;
|
||||
private final Tags stylesheets;
|
||||
private final Tags scripts;
|
||||
private final Tags headScripts;
|
||||
|
||||
FreemarkerConfiguration(String themeDir, VitroRequest vreq, ServletContext context) {
|
||||
|
||||
|
@ -53,10 +45,6 @@ public class FreemarkerConfiguration extends Configuration {
|
|||
this.appBean = vreq.getAppBean();
|
||||
this.appName = appBean.getApplicationName();
|
||||
|
||||
this.stylesheets = new Tags();
|
||||
this.scripts = new Tags();
|
||||
this.headScripts = new Tags();
|
||||
|
||||
String buildEnv = ConfigurationProperties.getBean(context).getProperty("Environment.build");
|
||||
log.debug("Current build environment: " + buildEnv);
|
||||
if ("development".equals(buildEnv)) { // Set Environment.build = development in deploy.properties
|
||||
|
@ -100,25 +88,10 @@ public class FreemarkerConfiguration extends Configuration {
|
|||
|
||||
}
|
||||
|
||||
/** Some template variables are shared so that they are accessible to
|
||||
* all templates, but they are request-specific and so need to be
|
||||
* reset at the beginning of a new request.
|
||||
*
|
||||
* This is public for now because it's accessed by propDelete.jsp.
|
||||
* Once the property deletion is integrated into Freemarker and generated
|
||||
* with a Freemarker page, the visibility can be reduced to package.
|
||||
*/
|
||||
public void resetRequestSpecificSharedVariables() {
|
||||
stylesheets.reset();
|
||||
scripts.reset();
|
||||
headScripts.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* These are values that are accessible to all
|
||||
* templates loaded by the Configuration's TemplateLoader. They
|
||||
* should be application- rather than request-specific, or else get
|
||||
* reset with a new request.
|
||||
* should be application- rather than request-specific.
|
||||
* @param VitroRequest vreq
|
||||
*/
|
||||
private void setSharedVariables(VitroRequest vreq) {
|
||||
|
@ -131,10 +104,6 @@ public class FreemarkerConfiguration extends Configuration {
|
|||
sharedVariables.put("themeDir", themeDir);
|
||||
sharedVariables.put("currentTheme", themeDir.substring(themeDir.lastIndexOf('/')+1));
|
||||
|
||||
sharedVariables.put("stylesheets", wrapTagList(stylesheets));
|
||||
sharedVariables.put("scripts", wrapTagList(scripts));
|
||||
sharedVariables.put("headScripts", wrapTagList(headScripts));
|
||||
|
||||
sharedVariables.putAll(getDirectives());
|
||||
sharedVariables.putAll(getMethods());
|
||||
sharedVariables.put("siteTagline", appBean.getShortHand());
|
||||
|
@ -177,23 +146,6 @@ public class FreemarkerConfiguration extends Configuration {
|
|||
return urls;
|
||||
}
|
||||
|
||||
/** Script and stylesheet lists are wrapped with a specialized BeansWrapper
|
||||
* that exposes certain write methods, instead of the configuration's object wrapper,
|
||||
* which doesn't. The templates can then add stylesheets and scripts to the lists
|
||||
* by calling their add() methods.
|
||||
* @param Tags tags
|
||||
* @return TemplateModel
|
||||
*/
|
||||
private TemplateModel wrapTagList(Tags tags) {
|
||||
try {
|
||||
BeansWrapper wrapper = new TagsWrapper();
|
||||
return wrapper.wrap(tags); // this is a StringModel
|
||||
} catch (TemplateModelException e) {
|
||||
log.error("Error creating Tags template model");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> getDirectives() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("dump", new freemarker.ext.dump.DumpDirective());
|
||||
|
|
|
@ -37,6 +37,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Res
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
|
||||
import freemarker.ext.beans.BeansWrapper;
|
||||
|
@ -101,7 +102,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
|
||||
FreemarkerConfiguration config = getConfig(vreq);
|
||||
vreq.setAttribute("freemarkerConfig", config);
|
||||
config.resetRequestSpecificSharedVariables();
|
||||
|
||||
responseValues = processRequest(vreq);
|
||||
doResponse(vreq, response, responseValues);
|
||||
|
@ -444,6 +444,12 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective());
|
||||
map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective());
|
||||
|
||||
// Add these accumulator objects. They will collect tags so the template can write them
|
||||
// at the appropriate location.
|
||||
map.put("stylesheets", new Tags().wrap());
|
||||
map.put("scripts", new Tags().wrap());
|
||||
map.put("headScripts", new Tags().wrap());
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ import org.apache.commons.lang.StringUtils;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.web.beanswrappers.ReadOnlyBeansWrapper;
|
||||
import freemarker.ext.beans.BeansWrapper;
|
||||
import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision;
|
||||
import freemarker.template.TemplateModel;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
public class Tags extends BaseTemplateModel {
|
||||
|
||||
|
@ -27,10 +27,22 @@ public class Tags extends BaseTemplateModel {
|
|||
this.tags = tags;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
tags.clear();
|
||||
public TemplateModel wrap() {
|
||||
try {
|
||||
return new TagsWrapper().wrap(this);
|
||||
} catch (TemplateModelException e) {
|
||||
log.error("Error creating Tags template model");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Script and stylesheet lists are wrapped with a specialized BeansWrapper
|
||||
* that exposes certain write methods, instead of the configuration's object wrapper,
|
||||
* which doesn't. The templates can then add stylesheets and scripts to the lists
|
||||
* by calling their add() methods.
|
||||
* @param Tags tags
|
||||
* @return TemplateModel
|
||||
*/
|
||||
static public class TagsWrapper extends BeansWrapper {
|
||||
|
||||
public TagsWrapper() {
|
||||
|
@ -67,7 +79,7 @@ public class Tags extends BaseTemplateModel {
|
|||
}
|
||||
|
||||
public String list() {
|
||||
return StringUtils.join(tags, "");
|
||||
return StringUtils.join(tags, "\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue