From 6bce20b84e1a4383cef5c45ac89d25e8912cc5a8 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 13 Jan 2012 16:50:03 +0000 Subject: [PATCH] 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. --- .../FreemarkerComponentGenerator.java | 1 - .../freemarker/FreemarkerConfiguration.java | 50 +------------------ .../freemarker/FreemarkerHttpServlet.java | 8 ++- .../vitro/webapp/web/templatemodels/Tags.java | 24 ++++++--- 4 files changed, 26 insertions(+), 57 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerComponentGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerComponentGenerator.java index 0941e15b6..5cc67eba9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerComponentGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerComponentGenerator.java @@ -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 map = getPageTemplateValues(vreq); request.setAttribute("ftl_head", getHead("head", map, config, vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java index 3f54bc8df..5940db33e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java @@ -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 getDirectives() { Map map = new HashMap(); map.put("dump", new freemarker.ext.dump.DumpDirective()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java index 7928493e1..c9538e8a5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java @@ -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; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/Tags.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/Tags.java index bd96729f3..01748727b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/Tags.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/Tags.java @@ -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"); }