NIHVIVO-3200 Make the FreemarkerConfigurationLoader a static utility class with a local cache, instead of having the loader as a context attribute and the cache as another context attribute.

This commit is contained in:
j2blake 2011-10-03 20:16:55 +00:00
parent dc450cd25c
commit bded986b92
5 changed files with 52 additions and 88 deletions

View file

@ -75,10 +75,7 @@ public abstract class VitroAjaxController extends HttpServlet {
* its data through a template. * its data through a template.
*/ */
protected final Configuration getFreemarkerConfiguration(VitroRequest vreq) { protected final Configuration getFreemarkerConfiguration(VitroRequest vreq) {
ServletContext context = getServletContext(); return FreemarkerConfigurationLoader.getConfig(vreq, getServletContext());
FreemarkerConfigurationLoader loader =
FreemarkerConfigurationLoader.getFreemarkerConfigurationLoader(context);
return loader.getConfig(vreq);
} }
/** /**

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
@ -11,79 +12,54 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import freemarker.template.Configuration;
public class FreemarkerConfigurationLoader { public class FreemarkerConfigurationLoader {
private static final Log log = LogFactory.getLog(FreemarkerConfigurationLoader.class); private static final Log log = LogFactory
.getLog(FreemarkerConfigurationLoader.class);
private ServletContext context; private static final Map<String, FreemarkerConfiguration> themeToConfigMap = new HashMap<String, FreemarkerConfiguration>();
public FreemarkerConfigurationLoader(ServletContext context){ public static FreemarkerConfiguration getConfig(VitroRequest vreq,
this.context = context; ServletContext context) {
context.setAttribute("FreemarkerConfigurationLoader", this); String themeDir = getThemeDir(vreq.getAppBean());
} return getConfigForTheme(themeDir, vreq, context);
}
/** private static String getThemeDir(ApplicationBean appBean) {
* @return Under serious error conditions this will return null. if (appBean == null) {
*/ log.error("Cannot get themeDir from null application bean");
public static FreemarkerConfigurationLoader getFreemarkerConfigurationLoader(ServletContext context){ return null;
if( context!=null){ }
FreemarkerConfigurationLoader fcl = (FreemarkerConfigurationLoader)
context.getAttribute("FreemarkerConfigurationLoader");
if( fcl == null ){
log.error("Must be constructed before calling " +
"getFreemarkerConfigurationLoader(), usually this is done by FreemarkerSetup");
return null;
}
return fcl;
}else{
log.error("getFreemarkerConfigurationLoader() must not be called with a null context");
return null;
}
}
public FreemarkerConfiguration getConfig(VitroRequest vreq) { String themeDir = appBean.getThemeDir();
String themeDir = getThemeDir(vreq.getAppBean()); if (themeDir == null) {
return getConfigForTheme(themeDir, vreq); log.error("themeDir is null");
} return null;
}
protected String getThemeDir(ApplicationBean appBean) { return themeDir.replaceAll("/$", "");
if (appBean == null) { }
log.error("Cannot get themeDir from null application bean");
return null;
}
String themeDir = appBean.getThemeDir(); /**
if (themeDir == null) { * The Configuration is theme-specific because:
log.error("themeDir is null"); *
return null; * 1. The template loader is theme-specific, since it specifies a theme
} * directory to load templates from.
*
return themeDir.replaceAll("/$", ""); * 2. Shared variables like stylesheets are theme-specific.
} */
private static FreemarkerConfiguration getConfigForTheme(String themeDir,
protected FreemarkerConfiguration getConfigForTheme(String themeDir, VitroRequest vreq) { VitroRequest vreq, ServletContext context) {
synchronized (themeToConfigMap) {
/* The Configuration is theme-specific because: if (themeToConfigMap.containsKey(themeDir)) {
* 1. The template loader is theme-specific, since it specifies a theme directory to load templates from. return themeToConfigMap.get(themeDir);
* 2. Shared variables like stylesheets are theme-specific. } else {
*/ FreemarkerConfiguration config = new FreemarkerConfiguration(
@SuppressWarnings("unchecked") themeDir, vreq, context);
Map<String, FreemarkerConfiguration> themeToConfigMap = themeToConfigMap.put(themeDir, config);
(Map<String, FreemarkerConfiguration>) context.getAttribute("themeToConfigMap"); return config;
}
if( themeToConfigMap == null ) { }
log.error("The templating system is not configured correctly. Make sure that you have the FreemarkerSetup context listener in your web.xml."); }
// We'll end up with a blank page as well as errors in the log, which is probably fine.
// Doesn't seem like we should throw a checked exception in this case.
return null;
} else if (themeToConfigMap.containsKey(themeDir)) {
return themeToConfigMap.get(themeDir);
} else {
FreemarkerConfiguration config = new FreemarkerConfiguration(themeDir, vreq, context);
themeToConfigMap.put(themeDir, config);
return config;
}
}
} }

View file

@ -15,7 +15,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -25,7 +24,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAcc
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseMiscellaneousAdminPages; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseMiscellaneousAdminPages;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
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.TemplateProcessingHelper.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
@ -198,9 +196,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
} }
protected FreemarkerConfiguration getConfig(VitroRequest vreq) { protected FreemarkerConfiguration getConfig(VitroRequest vreq) {
FreemarkerConfigurationLoader loader = return FreemarkerConfigurationLoader.getConfig(vreq, getServletContext());
FreemarkerConfigurationLoader.getFreemarkerConfigurationLoader(getServletContext());
return loader.getConfig(vreq);
} }
/** /**

View file

@ -2,8 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
@ -17,18 +15,17 @@ public class FreemarkerSetup implements ServletContextListener {
private static final Log log = LogFactory.getLog(FreemarkerSetup.class); private static final Log log = LogFactory.getLog(FreemarkerSetup.class);
@Override
public void contextInitialized(ServletContextEvent event) { public void contextInitialized(ServletContextEvent event) {
ServletContext sc = event.getServletContext(); ServletContext sc = event.getServletContext();
sc.setAttribute("themeToConfigMap", new HashMap<String, FreemarkerConfiguration>());
BaseTemplateModel.setServletContext(sc); BaseTemplateModel.setServletContext(sc);
FreemarkerComponentGenerator.setServletContext(sc); FreemarkerComponentGenerator.setServletContext(sc);
UrlBuilder.contextPath = sc.getContextPath(); UrlBuilder.contextPath = sc.getContextPath();
FreemarkerConfigurationLoader loader = new FreemarkerConfigurationLoader(sc);
log.info("Freemarker templating system initialized."); log.info("Freemarker templating system initialized.");
} }
@Override
public void contextDestroyed(ServletContextEvent event) { public void contextDestroyed(ServletContextEvent event) {
// nothing to do here // nothing to do here
} }

View file

@ -405,9 +405,7 @@ public class InputElementFormattingTag extends TagSupport {
} }
//get freemarker Configuration //get freemarker Configuration
FreemarkerConfigurationLoader fConfigLoader Configuration fmConfig = FreemarkerConfigurationLoader.getConfig(vreq, pageContext.getServletContext());
= FreemarkerConfigurationLoader.getFreemarkerConfigurationLoader(pageContext.getServletContext());
Configuration fmConfig = fConfigLoader.getConfig(vreq);
/* populate the pieces */ /* populate the pieces */
String classStr = doClass(); String classStr = doClass();