Revision: 1382
          http://stripes.svn.sourceforge.net/stripes/?rev=1382&view=rev
Author:   bengunter
Date:     2011-01-03 19:35:58 +0000 (Mon, 03 Jan 2011)

Log Message:
-----------
STS-788: Fix broken layouts for included pages. The layout code works by 
executing include requests for the pages that define layout definitions and 
components. When pages are included by other means outside the layout tags 
(e.g., jsp:include) if those pages contain layout tags they must start the 
layout process anew instead of trying to use the context from the page that 
included them.

Modified Paths:
--------------
    
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentRenderer.java
    
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
    
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java

Modified: 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentRenderer.java
===================================================================
--- 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentRenderer.java
  2011-01-02 22:48:15 UTC (rev 1381)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentRenderer.java
  2011-01-03 19:35:58 UTC (rev 1382)
@@ -91,8 +91,8 @@
      * 
      * @return True if the named component was found and it indicated that it 
successfully rendered;
      *         otherwise, false.
-     * @throws IOException If thrown by {...@link PageContext#include(String)}
-     * @throws ServletException If thrown by {...@link 
PageContext#include(String)}
+     * @throws IOException If thrown by {...@link 
LayoutContext#doInclude(PageContext, String)}
+     * @throws ServletException If thrown by {...@link 
LayoutContext#doInclude(PageContext, String)}
      */
     public boolean write() throws ServletException, IOException {
         final PageContext pageContext = getPageContext();
@@ -130,7 +130,7 @@
                 log.debug("Start execute \"", this.component, "\" in ",
                         currentContext.getRenderPage(), " -> ", 
currentContext.getDefinitionPage(),
                         " from ", context.getRenderPage(), " -> ", 
context.getDefinitionPage());
-                pageContext.include(context.getRenderPage(), false);
+                currentContext.doInclude(pageContext, context.getRenderPage());
                 log.debug("End execute \"", this.component, "\" in ",
                         currentContext.getRenderPage(), " -> ", 
currentContext.getDefinitionPage(),
                         " from ", context.getRenderPage(), " -> ", 
context.getDefinitionPage());

Modified: 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
===================================================================
--- 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
    2011-01-02 22:48:15 UTC (rev 1381)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
    2011-01-03 19:35:58 UTC (rev 1382)
@@ -14,12 +14,14 @@
  */
 package net.sourceforge.stripes.tag.layout;
 
+import java.io.IOException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import javax.servlet.ServletException;
 import javax.servlet.jsp.PageContext;
 
 import net.sourceforge.stripes.util.Log;
@@ -36,7 +38,7 @@
     private static final Log log = Log.getInstance(LayoutContext.class);
 
     /** The attribute name by which the stack of layout contexts can be found 
in the request. */
-    public static final String REQ_ATTR_NAME = "stripes.layout.Context";
+    public static final String LAYOUT_CONTEXT_KEY = 
LayoutContext.class.getName() + "#Context";
 
     /**
      * Create a new layout context for the given render tag and push it onto 
the stack of layout
@@ -60,7 +62,7 @@
             context.previous = previous;
         }
 
-        pageContext.getRequest().setAttribute(REQ_ATTR_NAME, context);
+        pageContext.setAttribute(LAYOUT_CONTEXT_KEY, context);
         return context;
     }
 
@@ -70,7 +72,15 @@
      * @param pageContext The JSP page context to search for the layout 
context stack.
      */
     public static LayoutContext lookup(PageContext pageContext) {
-        return (LayoutContext) 
pageContext.getRequest().getAttribute(REQ_ATTR_NAME);
+        LayoutContext context = (LayoutContext) 
pageContext.getAttribute(LAYOUT_CONTEXT_KEY);
+        if (context == null) {
+            context = (LayoutContext) 
pageContext.getRequest().getAttribute(LAYOUT_CONTEXT_KEY);
+            if (context != null) {
+                pageContext.setAttribute(LAYOUT_CONTEXT_KEY, context);
+                pageContext.getRequest().removeAttribute(LAYOUT_CONTEXT_KEY);
+            }
+        }
+        return context;
     }
 
     /**
@@ -83,7 +93,7 @@
     public static LayoutContext pop(PageContext pageContext) {
         LayoutContext context = lookup(pageContext);
         log.debug("Pop context ", context.getRenderPage(), " -> ", 
context.getDefinitionPage());
-        pageContext.getRequest().setAttribute(REQ_ATTR_NAME, context.previous);
+        pageContext.setAttribute(LAYOUT_CONTEXT_KEY, context.previous);
         if (context.previous != null) {
             context.previous.next = null;
             context.previous = null;
@@ -149,6 +159,29 @@
         }
     }
 
+    /**
+     * <p>
+     * Called when a layout tag needs to execute a page in order to execute 
another layout tag.
+     * Special handling is implemented to ensure the included page is aware of 
the current layout
+     * context while also ensuring that pages included by other means (e.g., 
{...@code jsp:include} or
+     * {...@code c:import}) are <em>not</em> aware of the current layout 
context.
+     * </p>
+     * <p>
+     * This method calls {...@link PageContext#include(String, boolean)} with 
{...@code false} as the
+     * second parameter so that the response is not flushed before the include 
request executes.
+     * </p>
+     */
+    public void doInclude(PageContext pageContext, String relativeUrlPath) 
throws ServletException,
+            IOException {
+        try {
+            pageContext.getRequest().setAttribute(LAYOUT_CONTEXT_KEY, this);
+            pageContext.include(relativeUrlPath, false);
+        }
+        finally {
+            pageContext.getRequest().removeAttribute(LAYOUT_CONTEXT_KEY);
+        }
+    }
+
     /** Get the render tag that created this context. */
     public LayoutRenderTag getRenderTag() { return renderTag; }
 

Modified: 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java
===================================================================
--- 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java
  2011-01-02 22:48:15 UTC (rev 1381)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java
  2011-01-03 19:35:58 UTC (rev 1382)
@@ -152,7 +152,7 @@
                     log.debug("Start layout exec in ", 
context.getDefinitionPage());
                     boolean silent = context.getOut().isSilent();
                     context.getOut().setSilent(true, pageContext);
-                    pageContext.include(getName(), false);
+                    context.doInclude(pageContext, getName());
                     context.getOut().setSilent(silent, pageContext);
                     log.debug("End layout exec in ", 
context.getDefinitionPage());
                 }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to