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,43 +12,20 @@ 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);
}
/**
* @return Under serious error conditions this will return null.
*/
public static FreemarkerConfigurationLoader getFreemarkerConfigurationLoader(ServletContext context){
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 = getThemeDir(vreq.getAppBean()); String themeDir = getThemeDir(vreq.getAppBean());
return getConfigForTheme(themeDir, vreq); return getConfigForTheme(themeDir, vreq, context);
} }
protected String getThemeDir(ApplicationBean appBean) { private static String getThemeDir(ApplicationBean appBean) {
if (appBean == null) { if (appBean == null) {
log.error("Cannot get themeDir from null application bean"); log.error("Cannot get themeDir from null application bean");
return null; return null;
@ -62,28 +40,26 @@ public class FreemarkerConfigurationLoader {
return themeDir.replaceAll("/$", ""); return themeDir.replaceAll("/$", "");
} }
protected FreemarkerConfiguration getConfigForTheme(String themeDir, VitroRequest vreq) { /**
* The Configuration is theme-specific because:
/* The Configuration is theme-specific because: *
* 1. The template loader is theme-specific, since it specifies a theme directory to load templates from. * 1. The template loader is theme-specific, since it specifies a theme
* directory to load templates from.
*
* 2. Shared variables like stylesheets are theme-specific. * 2. Shared variables like stylesheets are theme-specific.
*/ */
@SuppressWarnings("unchecked") private static FreemarkerConfiguration getConfigForTheme(String themeDir,
Map<String, FreemarkerConfiguration> themeToConfigMap = VitroRequest vreq, ServletContext context) {
(Map<String, FreemarkerConfiguration>) context.getAttribute("themeToConfigMap"); synchronized (themeToConfigMap) {
if (themeToConfigMap.containsKey(themeDir)) {
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); return themeToConfigMap.get(themeDir);
} else { } else {
FreemarkerConfiguration config = new FreemarkerConfiguration(themeDir, vreq, context); FreemarkerConfiguration config = new FreemarkerConfiguration(
themeDir, vreq, context);
themeToConfigMap.put(themeDir, config); themeToConfigMap.put(themeDir, config);
return 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();