Revision: 1390
http://stripes.svn.sourceforge.net/stripes/?rev=1390&view=rev
Author: bengunter
Date: 2011-01-06 18:09:14 +0000 (Thu, 06 Jan 2011)
Log Message:
-----------
STS-788: Fixed issues reported by S?\195?\169bastien Lesaint.
- When a new layout context is created, it calls pushBody(Writer) to insert the
LayoutWriter which controls output. However, after the layout process was
completed, it was not calling popBody(). This caused problems when the layout
tags were executing within another tag (like stripes:form) that had pushed a
BodyContent.
- The render tag documentation does not state that it must be the outermost
output-producing tag in a page. (The definition tag documentation does.) I
changed the render tag so it not longer clears the output buffer and returns
EVAL_PAGE instead of SKIP_PAGE to make it compatible with the old
implementation. To hide any stray render tag contents, it now implements
BodyTag and returns EVAL_BODY_BUFFERED for component registration phase,
discarding the body content afterward, and EVAL_BODY_INCLUDE for component
render phase. In the latter case, the undesirable output is discarded by the
LayoutWriter.
Modified Paths:
--------------
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/LayoutContext.java
===================================================================
---
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
2011-01-06 14:12:59 UTC (rev 1389)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutContext.java
2011-01-06 18:09:14 UTC (rev 1390)
@@ -93,11 +93,17 @@
public static LayoutContext pop(PageContext pageContext) {
LayoutContext context = lookup(pageContext);
log.debug("Pop context ", context.getRenderPage(), " -> ",
context.getDefinitionPage());
+
pageContext.setAttribute(LAYOUT_CONTEXT_KEY, context.previous);
- if (context.previous != null) {
+
+ if (context.previous == null) {
+ pageContext.popBody();
+ }
+ else {
context.previous.next = null;
context.previous = null;
}
+
return context;
}
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-06 14:12:59 UTC (rev 1389)
+++
branches/1.5.x/stripes/src/net/sourceforge/stripes/tag/layout/LayoutRenderTag.java
2011-01-06 18:09:14 UTC (rev 1390)
@@ -14,10 +14,11 @@
*/
package net.sourceforge.stripes.tag.layout;
-import java.io.IOException;
-
import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.BodyContent;
+import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.DynamicAttributes;
+import javax.servlet.jsp.tagext.Tag;
import net.sourceforge.stripes.exception.StripesJspException;
import net.sourceforge.stripes.exception.StripesRuntimeException;
@@ -31,12 +32,13 @@
* @author Tim Fennell, Ben Gunter
* @since Stripes 1.1
*/
-public class LayoutRenderTag extends LayoutTag implements DynamicAttributes {
+public class LayoutRenderTag extends LayoutTag implements BodyTag,
DynamicAttributes {
private static final Log log = Log.getInstance(LayoutRenderTag.class);
private String name;
private LayoutContext context;
private boolean contextIsNew, silent;
+ private BodyContent bodyContent;
/** Gets the name of the layout to be used. */
public String getName() { return name; }
@@ -116,10 +118,27 @@
// Render tags never output their contents directly
context.getOut().setSilent(true, pageContext);
- return EVAL_BODY_INCLUDE;
+ return contextIsNew ? EVAL_BODY_BUFFERED : EVAL_BODY_INCLUDE;
}
/**
+ * Set the tag's body content. Called by the JSP engine during component
registration phase,
+ * when {...@link #doStartTag()} returns {...@link
BodyTag#EVAL_BODY_BUFFERED}
+ */
+ public void setBodyContent(BodyContent bodyContent) {
+ this.bodyContent = bodyContent;
+ }
+
+ /** Does nothing. */
+ public void doInitBody() throws JspException {
+ }
+
+ /** Returns {...@link Tag#SKIP_BODY}. */
+ public int doAfterBody() throws JspException {
+ return SKIP_BODY;
+ }
+
+ /**
* After the first pass (see {...@link
LayoutContext#isComponentRenderPhase()}):
* <ul>
* <li>Ensure the layout rendered successfully by checking {...@link
LayoutContext#isRendered()}.</li>
@@ -134,18 +153,6 @@
try {
LayoutContext context = getContext();
if (contextIsNew) {
- // Substitution of the layout writer for the regular JSP
writer does not work for
- // the initial render tag. Its body evaluation still uses the
original JSP writer
- // for output. Clear the output buffer before executing the
definition page.
- if (isOuterLayoutTag()) {
- try {
- context.getOut().clear();
- }
- catch (IOException e) {
- log.debug("Could not clear output buffer: ",
e.getMessage());
- }
- }
-
log.debug("End layout init in ", context.getRenderPage());
try {
@@ -185,14 +192,17 @@
// Restore output's silent flag
context.getOut().setSilent(silent, pageContext);
-
- // Skip the rest of the page if this is the outer-most render tag
- return isOuterLayoutTag() ? SKIP_PAGE : EVAL_PAGE;
+ return EVAL_PAGE;
}
finally {
this.context = null;
this.contextIsNew = false;
this.silent = false;
+
+ if (this.bodyContent != null) {
+ this.bodyContent.clearBody();
+ this.bodyContent = 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