Hey fellas,

I did some stuff to enchance the Context chaining.  This is my first 
submission, so let me know if I'm way out of line...

There are some ugly bits in here due to the fact that the innerContext 
is defined as a Context, not an AbstractContext.  Does anyone object to 
making the innerContext an AbstractContext?  If not, I can take the 
exceptions out of this code...


Index: src/java/org/apache/velocity/context/AbstractContext.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-velocity/src/java/org/apache/velocity/context/AbstractContext.java,v
retrieving revision 1.4
diff -u -r1.4 AbstractContext.java
--- src/java/org/apache/velocity/context/AbstractContext.java   2001/03/28 03:01:04    
 1.4
+++ src/java/org/apache/velocity/context/AbstractContext.java   2001/04/28 01:50:43
@@ -298,7 +298,115 @@
          return innerContext;
      }

-}
+    /**
+     *  Sets the chained Context.
+     *  Note: using this method can potentially cause a loop in the 
Context chain.
+     *  The preferred method of dealing with the Context chain is 
through the addChainedContext() and removeChainedContext() methods, as 
those methods do checks to prevent a closed chain.
+     *
+     *  @param context The context to be chained.
+     *  @return The old chained Context if one existed, 
<code>null</code> if not.
+     */
+    public Context setChainedContext(Context c)
+    {
+        Context oldContext = innerContext;
+        innerContext = c;
+        return oldContext;
+    }
+
+    /**
+     *  Adds a Context to the end of the Context chain.
+     *  If the provided context is already on the Context chain, it is 
not added again.
+     *
+     *  @param context The context to be added to the chain.
+     *  @return <code>true</code> is the context was added, 
<code>false</code> otherwise.
+     *  @throws UnsupportedOperationException if a context on the chain 
does not support this action.
+     */
+    public boolean addChainedContext(Context c)
+    {
+        // Make sure adding this context will not create an infinite loop
+        Context con = c;
+        while(con != null)
+        {
+            if(con == this)
+            {
+                return false;
+            }
+
+            if(!(con instanceof AbstractContext))
+            {
+                throw new UnsupportedOperationException("It could not 
be determined if adding the supplied Context would cause a loop in the 
Context chain.");
+            }
+            else
+            {
+                con = ((AbstractContext)con).getChainedContext();
+            }
+        }
+
+        if(innerContext == null)
+        {
+            innerContext = c;
+            return true;
+        }

+        if(!(innerContext instanceof AbstractContext))
+        {
+            throw new UnsupportedOperationException("Some Context on 
the chain does not support this operation.");
+        }

+        return ((AbstractContext)innerContext).addChainedContext(c);
+    }

+    /**
+     *  Removes a Context from the Context chain.
+     *  All Contexts following the removed context are moved one step 
closer to the head of the chain.
+     *
+     *  @param context The context to be removed from the chain.
+     *  @param severChain
+     *  @return <code>true</code> is the context was removed, 
<code>false</code> otherwise.
+     *  @throws UnsupportedOperationException if a context on the chain 
does not support this action.
+     */
+    public boolean removeChainedContext(Context c)
+    {
+        return removeChainedContext(c, true);
+    }
+
+    /**
+     *  Removes a Context from the Context chain.
+     *
+     *  @param context The context to be removed from the chain.
+     *  @param severChain
+     *  If true, the chain is severed at the removed context.
+     *  If false, all Contexts following the removed context are moved 
one step closer to the head of the chain.
+     *  @return <code>true</code> is the context was found and removed, 
<code>false</code> otherwise.
+     *  @throws UnsupportedOperationException if a context on the chain 
does not support this action.
+     */
+    public boolean removeChainedContext(Context c, boolean severChain)
+    {
+        if(innerContext == null)
+        {
+            return false;
+        }
+
+        if(innerContext == c)
+        {
+            if(severChain)
+            {
+                innerContext = null;
+            }
+            else
+            {
+                if(!(innerContext instanceof AbstractContext))
+                {
+                    throw new UnsupportedOperationException("Some 
Context on the chain does not support this operation.");
+                }
+                innerContext = 
((AbstractContext)innerContext).getChainedContext();
+            }
+            return true;
+        }
+        else
+        {
+            return 
((AbstractContext)innerContext).removeChainedContext(c, severChain);
+        }
+    }
+
+}

-- 
Patrick E. Whitesell
[EMAIL PROTECTED]

***************************************
This e-mail message may contain confidential and/or legally privileged 
information. If you are not the intended recipient(s), or the employee 
or agent responsible for delivery of this message to the intended 
recipient(s), you are hereby notified that any dissemination, 
distribution or copying of this e-mail message is strictly prohibited.If 
you have received this message in error, please immediately notify the 
sender and delete this e-mail message from your computer. DO NOT FORWARD 
THIS E-MAIL MESSAGE WITHOUT THE PERMISSION OF THE SENDER.

Reply via email to