Revision: 1284
          http://stripes.svn.sourceforge.net/stripes/?rev=1284&view=rev
Author:   bengunter
Date:     2010-09-28 18:24:42 +0000 (Tue, 28 Sep 2010)

Log Message:
-----------
STS-391: Instead of storing a stack of contexts in request scope, store the 
current context and treat each context as a node in a doubly-linked list.

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/LayoutDefinitionTag.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
  2010-09-27 15:34:08 UTC (rev 1283)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentRenderer.java
  2010-09-28 18:24:42 UTC (rev 1284)
@@ -15,7 +15,6 @@
 package net.sourceforge.stripes.tag.layout;
 
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.LinkedList;
 
 import javax.servlet.ServletException;
@@ -116,21 +115,12 @@
         final String component = context.getComponent();
         final boolean silent = context.getOut().isSilent();
         final LayoutContext currentSource = getSourceContext();
-
-        // Never use a context that sits higher up the stack than the current 
source
         log.debug("Render component \"", componentName, "\" in ", currentPage);
-        LinkedList<LayoutContext> stack = LayoutContext.getStack(pageContext, 
true);
-        Iterator<LayoutContext> iter = stack.descendingIterator();
-        if (currentSource != null) {
-            while (iter.hasNext() && iter.next() != currentSource)
-                ;
-        }
 
         // Descend the stack from here, trying each context where the 
component is registered
-        while (iter.hasNext()) {
+        for (LayoutContext source = currentSource == null ? context : 
currentSource.getPrevious(); source != null; source = source.getPrevious()) {
             // Skip contexts where the desired component is not registered or 
which would invoke the
             // current page again.
-            final LayoutContext source = iter.next();
             if (!source.getComponents().containsKey(componentName)
                     || source.getRenderPage().equals(currentPage)) {
                 log.trace("Not rendering \"", componentName, "\" in context ", 
source

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
    2010-09-27 15:34:08 UTC (rev 1283)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
    2010-09-28 18:24:42 UTC (rev 1284)
@@ -15,10 +15,8 @@
 package net.sourceforge.stripes.tag.layout;
 
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.Map;
 
-import javax.servlet.ServletRequest;
 import javax.servlet.jsp.PageContext;
 
 import net.sourceforge.stripes.util.Log;
@@ -35,45 +33,31 @@
     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.ContextStack";
+    public static final String REQ_ATTR_NAME = "stripes.layout.Context";
 
     /**
-     * Look up the stack of layout contexts a JSP page context. If {...@code 
create} is true and no
-     * stack is found then one will be created and placed in the page context.
-     * 
-     * @param pageContext The JSP page context to search for the layout 
context stack.
-     * @param create If true and no stack is found, then create and save a new 
stack.
-     */
-    @SuppressWarnings("unchecked")
-    public static LinkedList<LayoutContext> getStack(PageContext pageContext, 
boolean create) {
-        ServletRequest request = pageContext.getRequest();
-        LinkedList<LayoutContext> stack = (LinkedList<LayoutContext>) request
-                .getAttribute(REQ_ATTR_NAME);
-        if (create && stack == null) {
-            stack = new LinkedList<LayoutContext>();
-            request.setAttribute(REQ_ATTR_NAME, stack);
-        }
-        return stack;
-    }
-
-    /**
      * Create a new layout context for the given render tag and push it onto 
the stack of layout
      * contexts in a JSP page context.
      */
     public static LayoutContext push(LayoutRenderTag renderTag) {
         LayoutContext context = new LayoutContext(renderTag);
         log.debug("Push context ", context.getRenderPage(), " -> ", 
context.getDefinitionPage());
+
         PageContext pageContext = renderTag.getPageContext();
-        LinkedList<LayoutContext> stack = getStack(pageContext, true);
-        if (stack.isEmpty()) {
+        LayoutContext previous = lookup(pageContext);
+        if (previous == null) {
             // Create a new layout writer and push a new body
             context.out = new LayoutWriter(pageContext.getOut());
             pageContext.pushBody(context.out);
         }
         else {
-            context.out = stack.getLast().out;
+            // Link the two nodes
+            context.out = previous.out;
+            previous.next = context;
+            context.previous = previous;
         }
-        stack.add(context);
+
+        pageContext.getRequest().setAttribute(REQ_ATTR_NAME, context);
         return context;
     }
 
@@ -83,10 +67,17 @@
      * @param pageContext The JSP page context to search for the layout 
context stack.
      */
     public static LayoutContext lookup(PageContext pageContext) {
-        LinkedList<LayoutContext> stack = getStack(pageContext, false);
-        return stack == null || stack.isEmpty() ? null : stack.getLast();
+        return (LayoutContext) 
pageContext.getRequest().getAttribute(REQ_ATTR_NAME);
     }
 
+    /** Locate and return the outermost layout context, starting with the 
given one. */
+    public static LayoutContext getOuterContext(LayoutContext context) {
+        LayoutContext outer = context;
+        while (outer.getPrevious() != null)
+            outer = outer.getPrevious();
+        return outer;
+    }
+
     /**
      * Remove the current layout context from the stack of layout contexts.
      * 
@@ -95,12 +86,17 @@
      *         or was empty.
      */
     public static LayoutContext pop(PageContext pageContext) {
-        LinkedList<LayoutContext> stack = getStack(pageContext, false);
-        LayoutContext context = stack == null || stack.isEmpty() ? null : 
stack.removeLast();
+        LayoutContext context = lookup(pageContext);
         log.debug("Pop context ", context.getRenderPage(), " -> ", 
context.getDefinitionPage());
+        pageContext.getRequest().setAttribute(REQ_ATTR_NAME, context.previous);
+        if (context.previous != null) {
+            context.previous.next = null;
+            context.previous = null;
+        }
         return context;
     }
 
+    private LayoutContext previous, next;
     private LayoutRenderTag renderTag;
     private LayoutWriter out;
     private Map<String,LayoutComponentRenderer> components = new 
HashMap<String,LayoutComponentRenderer>();
@@ -119,6 +115,12 @@
         this.renderPage = renderTag.getCurrentPagePath();
     }
 
+    /** Get the previous layout context from the stack. */
+    public LayoutContext getPrevious() { return previous; }
+
+    /** Get the next layout context from the stack. */
+    public LayoutContext getNext() { return next; }
+
     /** 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/LayoutDefinitionTag.java
===================================================================
--- 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutDefinitionTag.java
      2010-09-27 15:34:08 UTC (rev 1283)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutDefinitionTag.java
      2010-09-28 18:24:42 UTC (rev 1284)
@@ -14,7 +14,6 @@
  */
 package net.sourceforge.stripes.tag.layout;
 
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -77,10 +76,9 @@
             pageContext.setAttribute(entry.getKey(), entry.getValue());
         }
 
-        // Put component renders into the page context, even those from 
previous contexts
-        Iterator<LayoutContext> iter = LayoutContext.getStack(pageContext, 
false).iterator();
-        while (iter.hasNext()) {
-            for (Entry<String, LayoutComponentRenderer> entry : 
iter.next().getComponents().entrySet()) {
+        // Put component renderers into the page context, even those from 
previous contexts
+        for (LayoutContext c = LayoutContext.getOuterContext(context); c != 
null; c = c.getNext()) {
+            for (Entry<String, LayoutComponentRenderer> entry : 
c.getComponents().entrySet()) {
                 entry.getValue().pushPageContext(pageContext);
                 pageContext.setAttribute(entry.getKey(), entry.getValue());
             }
@@ -102,9 +100,8 @@
             LayoutContext context = getContext();
             if (!renderPhase) {
                 // Pop our page context off the renderers' page context stack
-                Iterator<LayoutContext> iter = 
LayoutContext.getStack(pageContext, false).iterator();
-                while (iter.hasNext()) {
-                    for (LayoutComponentRenderer renderer : 
iter.next().getComponents().values()) {
+                for (LayoutContext c = LayoutContext.getOuterContext(context); 
c != null; c = c.getNext()) {
+                    for (LayoutComponentRenderer renderer : 
c.getComponents().values()) {
                         renderer.popPageContext();
                     }
                 }

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
  2010-09-27 15:34:08 UTC (rev 1283)
+++ 
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java
  2010-09-28 18:24:42 UTC (rev 1284)
@@ -81,7 +81,7 @@
     @Override
     public int doStartTag() throws JspException {
         LayoutContext context = getContext();
-        outer = LayoutContext.getStack(pageContext, true).getFirst() == 
context;
+        outer = context.getPrevious() == null;
         silent = context.getOut().isSilent();
 
         if (contextIsNew) {


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

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to