From 38e068da57caeeb6a9630d224fae52e578b79a71 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Fri, 4 Mar 2011 06:51:59 +0000 Subject: [PATCH] Solves WW-3330 - <@s.action> broken in sitemesh freemarker decorator page git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1077833 13f79535-47bb-0310-9956-ffa450edef68 --- .../views/freemarker/FreemarkerResult.java | 35 +++++++++++-------- .../sitemesh/FreemarkerPageFilter.java | 32 +++++++++++------ .../sitemesh/StrutsSiteMeshFactory.java | 28 +++++++++++++++ 3 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/StrutsSiteMeshFactory.java diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java index 5fe0b3a6f..c6fb408b7 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java @@ -21,25 +21,11 @@ package org.apache.struts2.views.freemarker; -import java.io.CharArrayWriter; -import java.io.IOException; -import java.io.Writer; -import java.util.Locale; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.ServletActionContext; -import org.apache.struts2.dispatcher.StrutsResultSupport; -import org.apache.struts2.views.util.ResourceUtil; - import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.LocaleProvider; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; - import freemarker.template.Configuration; import freemarker.template.ObjectWrapper; import freemarker.template.Template; @@ -47,6 +33,19 @@ import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; +import org.apache.commons.lang.ObjectUtils; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsStatics; +import org.apache.struts2.dispatcher.StrutsResultSupport; +import org.apache.struts2.views.util.ResourceUtil; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.Locale; /** @@ -330,11 +329,19 @@ public class FreemarkerResult extends StrutsResultSupport { response.setContentType(contentType); } + } else if(isInsideActionTag()){ + //trigger com.opensymphony.module.sitemesh.filter.PageResponseWrapper.deactivateSiteMesh() + response.setContentType(response.getContentType()); } return true; } + private boolean isInsideActionTag() { + Object attribute = ServletActionContext.getRequest().getAttribute(StrutsStatics.STRUTS_ACTION_TAG_INVOCATION); + return (Boolean) ObjectUtils.defaultIfNull(attribute, Boolean.FALSE); + } + /** * @return true write to the stream only when template processing completed successfully (false by default) */ diff --git a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerPageFilter.java b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerPageFilter.java index 446846341..6e97cf8e2 100644 --- a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerPageFilter.java +++ b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerPageFilter.java @@ -21,34 +21,44 @@ package org.apache.struts2.sitemesh; -import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext; -import com.opensymphony.sitemesh.webapp.SiteMeshFilter; -import com.opensymphony.sitemesh.DecoratorSelector; -import com.opensymphony.module.sitemesh.Factory; import com.opensymphony.module.sitemesh.Config; +import com.opensymphony.module.sitemesh.Factory; +import com.opensymphony.sitemesh.DecoratorSelector; +import com.opensymphony.sitemesh.webapp.SiteMeshFilter; +import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext; import com.opensymphony.xwork2.inject.Inject; - -import javax.servlet.*; - import org.apache.struts2.views.freemarker.FreemarkerManager; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; + /** * Core Filter for integrating SiteMesh + Freemarker into * a Java web application. */ public class FreemarkerPageFilter extends SiteMeshFilter { - @Inject(required=false) + /* + * @see com.opensymphony.module.sitemesh.Factory.SITEMESH_FACTORY + */ + private static final String SITEMESH_FACTORY = "sitemesh.factory"; + + @Inject(required = false) public static void setFreemarkerManager(FreemarkerManager mgr) { OldDecorator2NewStrutsFreemarkerDecorator.setFreemarkerManager(mgr); } private FilterConfig filterConfig; - public void init(FilterConfig filterConfig) { - this.filterConfig = filterConfig; + public void init(FilterConfig filterConfig) { + this.filterConfig = filterConfig; super.init(filterConfig); - } + ServletContext sc = filterConfig.getServletContext(); + Factory instance = (Factory) sc.getAttribute(SITEMESH_FACTORY); + if (instance == null) { + sc.setAttribute(SITEMESH_FACTORY, new StrutsSiteMeshFactory(new Config(filterConfig))); + } + } protected DecoratorSelector initDecoratorSelector(SiteMeshWebAppContext webAppContext) { Factory factory = Factory.getInstance(new Config(filterConfig)); diff --git a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/StrutsSiteMeshFactory.java b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/StrutsSiteMeshFactory.java new file mode 100644 index 000000000..e4d49255e --- /dev/null +++ b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/StrutsSiteMeshFactory.java @@ -0,0 +1,28 @@ +package org.apache.struts2.sitemesh; + +import com.opensymphony.module.sitemesh.Config; +import com.opensymphony.module.sitemesh.factory.DefaultFactory; +import org.apache.commons.lang.ObjectUtils; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsStatics; + + +public class StrutsSiteMeshFactory extends DefaultFactory { + + public StrutsSiteMeshFactory(Config config) { + super(config); + } + + /** + * Determine whether a Page of given content-type should be parsed or not, avoiding inner action parsing. + */ + @Override + public boolean shouldParsePage(String contentType) { + return !isInsideActionTag() && super.shouldParsePage(contentType); + } + + private boolean isInsideActionTag() { + Object attribute = ServletActionContext.getRequest().getAttribute(StrutsStatics.STRUTS_ACTION_TAG_INVOCATION); + return (Boolean) ObjectUtils.defaultIfNull(attribute, Boolean.FALSE); + } +}