You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2006/10/25 23:52:41 UTC
svn commit: r467775 - in
/cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks:
BlockCallStack.java BlockConnection.java BlockContext.java
components/BlockPathModule.java components/BlockPropertyModule.java
Author: danielf
Date: Wed Oct 25 14:52:40 2006
New Revision: 467775
URL: http://svn.apache.org/viewvc?view=rev&rev=467775
Log:
Hopefully fixed the bug described in JIRA COCOON-1939 - Stack overflow when inheriting from block that alread inherits from another one.
The solution is the one that I proposed in the JIRA issue. Not much testing though.
Modified:
cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockCallStack.java
cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockConnection.java
cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockContext.java
cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPathModule.java
cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPropertyModule.java
Modified: cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockCallStack.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockCallStack.java?view=diff&rev=467775&r1=467774&r2=467775
==============================================================================
--- cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockCallStack.java (original)
+++ cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockCallStack.java Wed Oct 25 14:52:40 2006
@@ -31,6 +31,16 @@
/** The block stack */
private static final ThreadLocal blockStack = new ThreadLocal();
+
+ /** Keep track on if it is an ordinary or a super call */
+ private static class BlockCallStackInfo {
+ public BlockCallStackInfo(ServletContext servletContext, boolean superCall) {
+ this.servletContext = servletContext;
+ this.superCall = superCall;
+ }
+ public ServletContext servletContext;
+ public boolean superCall;
+ };
/**
* This hook must be called each time a block is entered.
@@ -42,6 +52,24 @@
*/
public static void enterBlock(ServletContext context)
throws ServletException {
+ enterBlock(context, false);
+ }
+
+ /**
+ * This hook must be called each time a super block is entered.
+ *
+ * <p>This method should never raise an exception, except when the
+ * parameters are not set!</p>
+ *
+ * @throws ServletException if block is null
+ */
+ public static void enterSuperBlock(ServletContext context)
+ throws ServletException {
+ enterBlock(context, true);
+ }
+
+ private static void enterBlock(ServletContext context, boolean superCall)
+ throws ServletException {
if (null == context) {
throw new ServletException("Block is not set.");
}
@@ -51,7 +79,8 @@
stack = new Stack();
blockStack.set(stack);
}
- stack.push(context);
+ BlockCallStackInfo info = new BlockCallStackInfo(context, superCall);
+ stack.push(info);
}
/**
@@ -65,10 +94,32 @@
stack.pop();
}
+ /**
+ * Use this method for getting the context that should be used for
+ * resolving a polymorphic block protocol call
+ * @return a servlet context
+ */
+ public static ServletContext getBaseBlockContext() {
+ final Stack stack = (Stack)blockStack.get();
+ if (stack != null) {
+ for(int i = stack.size() - 1; i >= 0; i--) {
+ BlockCallStackInfo info = (BlockCallStackInfo) stack.elementAt(i);
+ if (!info.superCall)
+ return info.servletContext;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Use this method for getting the context that should be used for
+ * resolving a block protocol call to a super block
+ * @return a servlet context
+ */
public static ServletContext getCurrentBlockContext() {
final Stack stack = (Stack)blockStack.get();
if (stack != null && !stack.isEmpty()) {
- return (ServletContext)stack.peek();
+ return ((BlockCallStackInfo)stack.peek()).servletContext;
}
return null;
}
Modified: cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockConnection.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockConnection.java?view=diff&rev=467775&r1=467774&r2=467775
==============================================================================
--- cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockConnection.java (original)
+++ cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockConnection.java Wed Oct 25 14:52:40 2006
@@ -68,10 +68,6 @@
this.logger = logger;
- this.context = BlockCallStack.getCurrentBlockContext();
- if (this.context == null)
- throw new MalformedURLException("Must be used in a block context " + url);
-
URI blockURI = null;
try {
blockURI = parseBlockURI(new URI(url.toString()));
@@ -79,6 +75,16 @@
throw new MalformedURLException("Malformed URI in block source " +
e.getMessage());
}
+
+ // Super calls are resolved relative the current context and ordinary
+ // calls relative the last non super call in the call chain
+ if (BlockContext.SUPER.equals(this.blockName))
+ this.context = BlockCallStack.getCurrentBlockContext();
+ else
+ this.context = BlockCallStack.getBaseBlockContext();
+
+ if (this.context == null)
+ throw new MalformedURLException("Must be used in a block context " + url);
this.request = new BlockCallHttpServletRequest(blockURI);
this.response = new BlockCallHttpServletResponse();
Modified: cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockContext.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockContext.java?view=diff&rev=467775&r1=467774&r2=467775
==============================================================================
--- cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockContext.java (original)
+++ cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/BlockContext.java Wed Oct 25 14:52:40 2006
@@ -378,22 +378,22 @@
RequestDispatcher dispatcher =
this.context.getRequestDispatcher(((HttpServletRequest)request).getPathInfo());
if (dispatcher != null) {
- if (!this.superCall) {
- try {
+ try {
+ if (!this.superCall) {
// It is important to set the current block each time
// a new block is entered, this is used for the block
// protocol
BlockCallStack.enterBlock(this.context);
- dispatcher.forward(request, response);
- } finally {
- BlockCallStack.leaveBlock();
- }
- } else {
- // A super block should be called in the context of
- // the called block to get polymorphic calls resolved
- // in the right way. Therefore no new current block is
- // set.
+ } else {
+ // A super block should be called in the context of
+ // the called block to get polymorphic calls resolved
+ // in the right way. We still need to register the
+ // current context for resolving super calls relative it.
+ BlockCallStack.enterSuperBlock(this.context);
+ }
dispatcher.forward(request, response);
+ } finally {
+ BlockCallStack.leaveBlock();
}
} else {
// Cannot happen
Modified: cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPathModule.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPathModule.java?view=diff&rev=467775&r1=467774&r2=467775
==============================================================================
--- cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPathModule.java (original)
+++ cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPathModule.java Wed Oct 25 14:52:40 2006
@@ -41,7 +41,7 @@
public Object getAttribute( String name, Configuration modeConf, Map objectModel )
throws ConfigurationException {
Environment env = EnvironmentHelper.getCurrentEnvironment();
- BlockContext blockContext = (BlockContext) BlockCallStack.getCurrentBlockContext();
+ BlockContext blockContext = (BlockContext) BlockCallStack.getBaseBlockContext();
String absoluteURI = null;
/* No relative block paths yet
String baseURI = env.getURIPrefix();
Modified: cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPropertyModule.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPropertyModule.java?view=diff&rev=467775&r1=467774&r2=467775
==============================================================================
--- cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPropertyModule.java (original)
+++ cocoon/trunk/core/cocoon-blocks-fw/cocoon-blocks-fw-impl/src/main/java/org/apache/cocoon/blocks/components/BlockPropertyModule.java Wed Oct 25 14:52:40 2006
@@ -35,7 +35,7 @@
public Object getAttribute( String name, Configuration modeConf, Map objectModel )
throws ConfigurationException {
- return BlockCallStack.getCurrentBlockContext().getInitParameter(name);
+ return BlockCallStack.getBaseBlockContext().getInitParameter(name);
}
public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)