Author: musachy
Date: Sat Jun 30 08:57:13 2007
New Revision: 552165

URL: http://svn.apache.org/viewvc?view=rev&rev=552165
Log:
WW-1661 Implementation of Freemarker caching for Struts2
* Will be set to false by default
* Set to false when devMode is true
* Set struts.freemarker.templatesCache=true to enable it

Modified:
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java?view=diff&rev=552165&r1=552164&r2=552165
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java 
(original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java 
Sat Jun 30 08:57:13 2007
@@ -75,6 +75,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_CACHE_TEMPLATES = 
"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/trunk/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java?view=diff&rev=552165&r1=552164&r2=552165
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
 (original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
 Sat Jun 30 08:57:13 2007
@@ -22,6 +22,8 @@
 
 import java.io.IOException;
 import java.io.Writer;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -33,12 +35,13 @@
 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;
-import com.opensymphony.xwork2.util.ClassLoaderUtil;
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ClassLoaderUtil;
 import com.opensymphony.xwork2.util.ValueStack;
 
 import freemarker.template.Configuration;
@@ -51,6 +54,10 @@
     static Class bodyContent = null;
     private FreemarkerManager freemarkerManager;
 
+    private HashMap<String, freemarker.template.Template> templates = new 
HashMap<String, freemarker.template.Template>();
+    private HashSet<String> missingTemplates = new HashSet<String>();
+    private boolean freemarkerCaching = false;
+
     static {
         try {
             bodyContent = 
ClassLoaderUtil.loadClass("javax.servlet.jsp.tagext.BodyContent",
@@ -71,7 +78,7 @@
     }
     
     public void renderTemplate(TemplateRenderingContext templateContext) 
throws Exception {
-        // get the various items required from the stack
+       // get the various items required from the stack
         ValueStack stack = templateContext.getStack();
         Map context = stack.getContext();
         ServletContext servletContext = (ServletContext) 
context.get(ServletActionContext.SERVLET_CONTEXT);
@@ -91,13 +98,32 @@
         for (Iterator iterator = templates.iterator(); iterator.hasNext();) {
             Template t = (Template) iterator.next();
             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 +179,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 (freemarker.template.Template) templates.get(templateName);
+        }
+    }
+    
+    /**
+     * Enables or disables Struts caching of Freemarker templates. By default 
disabled.
+     * Set struts.freemarker.templatesCache=true to enable cache
+     * @param caching true if the template engine should cache freemarker 
template
+     * internally
+     */
+    @Inject(StrutsConstants.STRUTS_FREEMARKER_CACHE_TEMPLATES)
+    public void setCacheTemplates(String cacheTemplates) {
+        freemarkerCaching = "true".equals(cacheTemplates);
     }
 }

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java?view=diff&rev=552165&r1=552164&r2=552165
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java
 (original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java
 Sat Jun 30 08:57:13 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_CACHE_TEMPLATES, "false");
             // Convert struts properties into ones that xwork expects
             props.setProperty("devMode", "true");
         } else {

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties?view=diff&rev=552165&r1=552164&r2=552165
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/default.properties
 Sat Jun 30 08:57:13 2007
@@ -145,6 +145,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=true
+
 ### See the StrutsBeanWrapper javadocs for more information
 struts.freemarker.wrapper.altMap=true
 


Reply via email to