Revision: 1372
http://stripes.svn.sourceforge.net/stripes/?rev=1372&view=rev
Author: bengunter
Date: 2010-12-28 23:25:13 +0000 (Tue, 28 Dec 2010)
Log Message:
-----------
Fix for STS-788: Layout issues after upgrade from 1.5.3. This fixes the second
case where a component definition appears within a render within another
component definition. The component path is now tracked for each layout context
so that all the components that must execute for a nested component to execute
will execute during the component render phase.
Modified Paths:
--------------
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentTag.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/LayoutComponentTag.java
===================================================================
---
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentTag.java
2010-12-28 19:06:45 UTC (rev 1371)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutComponentTag.java
2010-12-28 23:25:13 UTC (rev 1372)
@@ -14,6 +14,8 @@
*/
package net.sourceforge.stripes.tag.layout;
+import java.util.Iterator;
+import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.jsp.JspException;
@@ -68,6 +70,42 @@
}
/**
+ * True if this tag is a component that must execute so that the current
component tag can
+ * execute. That is, this tag is a parent of the current component.
+ *
+ * @throws StripesJspException if thrown by {...@link #getContext()}.
+ */
+ protected boolean isPathComponent() throws StripesJspException {
+ List<String> path = getContext().getComponentPath();
+ return path == null ? false : isPathComponent(this, path.iterator());
+ }
+
+ /**
+ * Recursive method called from {...@link #isPathComponent()} that returns
true if the specified
+ * tag's name is present in the component path iterator at the same
position where this tag
+ * occurs in the render/component tag tree. For example, if the path
iterator contains the
+ * component names {...@code ["foo", "bar"]} then this method will return
true if the tag's name is
+ * {...@code "bar"} and it is a child of a render tag that is a child of a
component tag whose name
+ * is {...@code "foo"}.
+ *
+ * @param tag The tag to check
+ * @param path The path to the check the tag against
+ * @return
+ */
+ protected boolean isPathComponent(LayoutComponentTag tag, Iterator<String>
path) {
+ LayoutTag parent = tag.getLayoutParent();
+ if (parent instanceof LayoutRenderTag) {
+ parent = parent.getLayoutParent();
+ if (parent == null || parent instanceof LayoutComponentTag
+ && isPathComponent((LayoutComponentTag) parent, path) &&
path.hasNext()) {
+ return tag.getName().equals(path.next());
+ }
+ }
+
+ return false;
+ }
+
+ /**
* True if this tag is the component to be rendered on this pass from
* {...@link LayoutDefinitionTag}.
*
@@ -109,6 +147,11 @@
context.getOut().setSilent(false, pageContext);
return EVAL_BODY_INCLUDE;
}
+ else if (isPathComponent()) {
+ log.debug("Silently execute '", getName(), "' in ",
context.getRenderPage());
+ context.getOut().setSilent(true, pageContext);
+ return EVAL_BODY_INCLUDE;
+ }
else {
log.debug("No-op for ", getName(), " in ",
context.getRenderPage());
}
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-12-28 19:06:45 UTC (rev 1371)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
2010-12-28 23:25:13 UTC (rev 1372)
@@ -14,7 +14,10 @@
*/
package net.sourceforge.stripes.tag.layout;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import javax.servlet.jsp.PageContext;
@@ -94,6 +97,7 @@
private Map<String,LayoutComponentRenderer> components = new
HashMap<String,LayoutComponentRenderer>();
private Map<String,Object> parameters = new HashMap<String,Object>();
private String renderPage, component;
+ private List<String> componentPath;
private boolean componentRenderPhase, rendered;
/**
@@ -105,6 +109,22 @@
public LayoutContext(LayoutRenderTag renderTag) {
this.renderTag = renderTag;
this.renderPage = renderTag.getCurrentPagePath();
+
+ LinkedList<String> path = null;
+ for (LayoutTag parent = renderTag.getLayoutParent(); parent instanceof
LayoutComponentTag;) {
+ if (path == null)
+ path = new LinkedList<String>();
+
+ path.addFirst(((LayoutComponentTag) parent).getName());
+
+ parent = parent.getLayoutParent();
+ parent = parent instanceof LayoutRenderTag ?
parent.getLayoutParent() : null;
+ }
+
+ if (path != null) {
+ this.componentPath = Collections.unmodifiableList(path);
+ log.debug("Path is ", this.componentPath);
+ }
}
/** Get the previous layout context from the stack. */
@@ -165,6 +185,12 @@
/** Set the name of the component to be rendered during the current phase
of execution. */
public void setComponent(String component) { this.component = component; }
+ /**
+ * Get the list of components in the render page that must execute so that
the render tag that
+ * created this context can execute.
+ */
+ public List<String> getComponentPath() { return componentPath; }
+
/** Get the layout writer to which the layout is rendered. */
public LayoutWriter getOut() { return out; }
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-12-28 19:06:45 UTC (rev 1371)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java
2010-12-28 23:25:13 UTC (rev 1372)
@@ -20,6 +20,7 @@
import javax.servlet.jsp.tagext.DynamicAttributes;
import net.sourceforge.stripes.exception.StripesJspException;
+import net.sourceforge.stripes.exception.StripesRuntimeException;
import net.sourceforge.stripes.util.Log;
/**
@@ -50,7 +51,7 @@
boolean contextIsNew = false;
if (context == null || !context.isComponentRenderPhase()
- || context.isComponentRenderPhase() &&
isChildOfComponent()) {
+ || context.isComponentRenderPhase() &&
isChildOfCurrentComponent()) {
context = LayoutContext.push(this);
contextIsNew = true;
}
@@ -62,6 +63,19 @@
return context;
}
+ /** Returns true if this tag is a child of the current component tag. */
+ public boolean isChildOfCurrentComponent() {
+ try {
+ LayoutTag parent = getLayoutParent();
+ return parent instanceof LayoutComponentTag
+ && ((LayoutComponentTag) parent).isCurrentComponent();
+ }
+ catch (StripesJspException e) {
+ // This exception would have been thrown before this tag ever
executed
+ throw new StripesRuntimeException("Something has happened that
should never happen", e);
+ }
+ }
+
/** True if this is the outermost layout tag, the one that initiated the
render process. */
public boolean isOuterLayoutTag() {
return getLayoutParent() == null;
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