Author: rgielen Date: Mon Jul 30 00:05:55 2007 New Revision: 560881 URL: http://svn.apache.org/viewvc?view=rev&rev=560881 Log: WW-1661: Backporting Freemarker template caching to 2.0.x tree
Modified: struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/StrutsConstants.java struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java struts/struts2/branches/STRUTS_2_0_X/core/src/main/resources/org/apache/struts2/default.properties Modified: struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/StrutsConstants.java URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/StrutsConstants.java?view=diff&rev=560881&r1=560880&r2=560881 ============================================================================== --- struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/StrutsConstants.java (original) +++ struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/StrutsConstants.java Mon Jul 30 00:05:55 2007 @@ -76,6 +76,9 @@ /** The org.apache.struts2.views.freemarker.FreemarkerManager implementation class */ public static final String STRUTS_FREEMARKER_MANAGER_CLASSNAME = "struts.freemarker.manager.classname"; + /** Cache Freemarker templates */ + public static final String STRUTS_FREEMARKER_TEMPLATES_CACHE = "struts.freemarker.templatesCache"; + /** org.apache.struts2.views.velocity.VelocityManager implementation class */ public static final String STRUTS_VELOCITY_MANAGER_CLASSNAME = "struts.velocity.manager.classname"; Modified: struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java?view=diff&rev=560881&r1=560880&r2=560881 ============================================================================== --- struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java (original) +++ struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java Mon Jul 30 00:05:55 2007 @@ -22,9 +22,7 @@ import java.io.IOException; import java.io.Writer; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -33,6 +31,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsConstants; import org.apache.struts2.views.freemarker.FreemarkerManager; import com.opensymphony.xwork2.inject.Inject; @@ -41,8 +40,7 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.util.ValueStack; -import freemarker.template.Configuration; -import freemarker.template.SimpleHash; +import freemarker.template.*; /** * Freemarker based template engine. @@ -51,6 +49,10 @@ static Class bodyContent = null; private FreemarkerManager freemarkerManager; + private final HashMap<String, freemarker.template.Template> templates = new HashMap<String, freemarker.template.Template>(); + private final HashSet<String> missingTemplates = new HashSet<String>(); + private boolean freemarkerCaching = false; + static { try { bodyContent = ClassLoaderUtil.loadClass("javax.servlet.jsp.tagext.BodyContent", @@ -88,16 +90,35 @@ freemarker.template.Template template = null; String templateName = null; Exception exception = null; - for (Iterator iterator = templates.iterator(); iterator.hasNext();) { - Template t = (Template) iterator.next(); + for (Object template1 : templates) { + Template t = (Template) template1; templateName = getFinalTemplateName(t); - try { - // try to load, and if it works, stop at the first one - template = config.getTemplate(templateName); - break; - } catch (IOException e) { - if (exception == null) { - exception = e; + if (freemarkerCaching) { + if (!isTemplateMissing(templateName)) { + try { + template = findInCache(templateName); // look in cache first + if (template == null) { + // try to load, and if it works, stop at the first one + template = config.getTemplate(templateName); + addToCache(templateName, template); + } + break; + } catch (IOException e) { + addToMissingTemplateCache(templateName); + if (exception == null) { + exception = e; + } + } + } + } else { + try { + // try to load, and if it works, stop at the first one + template = config.getTemplate(templateName); + break; + } catch (IOException e) { + if (exception == null) { + exception = e; + } } } } @@ -153,5 +174,41 @@ protected String getSuffix() { return "ftl"; + } + + protected void addToMissingTemplateCache(String templateName) { + synchronized(missingTemplates) { + missingTemplates.add(templateName); + } + } + + protected boolean isTemplateMissing(String templateName) { + synchronized(missingTemplates) { + return missingTemplates.contains(templateName); + } + } + + protected void addToCache(String templateName, + freemarker.template.Template template) { + synchronized(templates) { + templates.put(templateName, template); + } + } + + protected freemarker.template.Template findInCache(String templateName) { + synchronized(templates) { + return templates.get(templateName); + } + } + + /** + * Enables or disables Struts caching of Freemarker templates. By default disabled. + * Set struts.freemarker.templatesCache=true to enable cache + * @param cacheTemplates "true" if the template engine should cache freemarker template + * internally + */ + @Inject(StrutsConstants.STRUTS_FREEMARKER_TEMPLATES_CACHE) + public void setCacheTemplates(String cacheTemplates) { + freemarkerCaching = "true".equals(cacheTemplates); } } Modified: struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java?view=diff&rev=560881&r1=560880&r2=560881 ============================================================================== --- struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java (original) +++ struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java Mon Jul 30 00:05:55 2007 @@ -163,6 +163,7 @@ if ("true".equalsIgnoreCase(props.getProperty(StrutsConstants.STRUTS_DEVMODE))) { props.setProperty(StrutsConstants.STRUTS_I18N_RELOAD, "true"); props.setProperty(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "true"); + props.setProperty(StrutsConstants.STRUTS_FREEMARKER_TEMPLATES_CACHE, "false"); // Convert struts properties into ones that xwork expects props.setProperty("devMode", "true"); } else { Modified: struts/struts2/branches/STRUTS_2_0_X/core/src/main/resources/org/apache/struts2/default.properties URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/resources/org/apache/struts2/default.properties?view=diff&rev=560881&r1=560880&r2=560881 ============================================================================== --- struts/struts2/branches/STRUTS_2_0_X/core/src/main/resources/org/apache/struts2/default.properties (original) +++ struts/struts2/branches/STRUTS_2_0_X/core/src/main/resources/org/apache/struts2/default.properties Mon Jul 30 00:05:55 2007 @@ -164,6 +164,10 @@ ### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager #struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager +### Enables caching of FreeMarker templates +### Has the same effect as copying the templates under WEB_APP/templates +struts.freemarker.templatesCache=false + ### See the StrutsBeanWrapper javadocs for more information struts.freemarker.wrapper.altMap=true