Author: byron
Date: Wed Feb 18 02:19:02 2009
New Revision: 745358

URL: http://svn.apache.org/viewvc?rev=745358&view=rev
Log:
VELOCITY-699 added optional #return directive to contributions directory

Added:
    
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/contrib/
    
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/contrib/Return.java
Modified:
    
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java

Modified: 
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java?rev=745358&r1=745357&r2=745358&view=diff
==============================================================================
--- 
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
 (original)
+++ 
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
 Wed Feb 18 02:19:02 2009
@@ -33,6 +33,7 @@
 import org.apache.velocity.runtime.Renderable;
 import org.apache.velocity.runtime.RuntimeConstants;
 import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.directive.contrib.Return;
 import org.apache.velocity.runtime.log.Log;
 import org.apache.velocity.runtime.parser.ParserTreeConstants;
 import org.apache.velocity.runtime.parser.Token;
@@ -306,6 +307,11 @@
                   Log.formatFileString(node));
                 throw e;
             }
+            catch (Return.ReturnThrowable r)
+            {
+              return true;  // Simply return and continue rendering.
+            }
+            
         }
         else if (strictRef)
         {

Added: 
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/contrib/Return.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/contrib/Return.java?rev=745358&view=auto
==============================================================================
--- 
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/contrib/Return.java
 (added)
+++ 
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/contrib/Return.java
 Wed Feb 18 02:19:02 2009
@@ -0,0 +1,67 @@
+package org.apache.velocity.runtime.directive.contrib;
+
+import java.io.Writer;
+
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.exception.TemplateInitException;
+import org.apache.velocity.exception.VelocityException;
+import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.directive.Directive;
+import org.apache.velocity.runtime.log.Log;
+import org.apache.velocity.runtime.parser.node.ASTDirective;
+import org.apache.velocity.runtime.parser.node.Node;
+
+/**
+ * This class implements the #return directive, used for returning from within
+ * a #macro.  Specifying the #return directive inside a macro will end 
rendering
+ * within the macro and resume rendering at the point of the macro call.
+ */
+public class Return extends Directive
+{
+  @Override
+  public String getName()
+  {
+    return "return";
+  }
+
+  @Override
+  public int getType()
+  {
+    return LINE;
+  }
+  
+  public void init(RuntimeServices rs, InternalContextAdapter context, Node 
thisnode)
+      throws TemplateInitException
+  {
+     super.init(rs, context, thisnode);
+     
+     // Make sure the #return directive is within a macro block.
+     Node node = thisnode;
+     while (! (node instanceof ASTDirective) 
+         || ! ((ASTDirective)node).getDirectiveName().equals("macro"))
+     {
+         node = node.jjtGetParent();
+         if (node == null)
+         {
+             // We are not in a macro definition, so throw an exception.
+             throw new VelocityException("#return must be within a #macro 
block at " 
+                 + Log.formatFileString(this));
+         }
+     }
+  }  
+  
+  public boolean render(InternalContextAdapter context, Writer writer, Node 
node)
+  {
+      // Throw the ReturnThrowable to be caught at the macro call level.
+      throw new ReturnThrowable();
+  }
+
+  /**
+   * Implements a Throwable we can pass up the stack without disturbing
+   * other catches of other throwables.
+   * @see org.apache.velocity.runtime.directive.Stop
+   */
+  public static class ReturnThrowable extends Error
+  {
+  }
+}


Reply via email to