Author: nbubna
Date: Mon Feb 23 16:21:48 2009
New Revision: 747067
URL: http://svn.apache.org/viewvc?rev=747067&view=rev
Log:
enforce #break must be in #foreach and refactor ASTStop and Break to properly
use StopCommands
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/Template.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Evaluate.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTStop.java
Modified: velocity/engine/trunk/src/java/org/apache/velocity/Template.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/Template.java?rev=747067&r1=747066&r2=747067&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/Template.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/Template.java Mon Feb 23
16:21:48 2009
@@ -39,7 +39,6 @@
import org.apache.velocity.runtime.directive.StopCommand;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.node.SimpleNode;
-import org.apache.velocity.runtime.parser.node.ASTStop.StopThrowable;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.resource.ResourceManager;
@@ -363,14 +362,6 @@
throw stop;
}
}
- catch (StopThrowable st)
- {
- // The stop throwable is thrown by ASTStop (the #stop directive)
- // The intent of the stop directive is to halt processing of the
- // the template, so we throw a Throwable that will short circuit
- // everthing between the call to render, and ASTStop. We just
needed to
- // Catch the exception, nothing else to do.
- }
catch (IOException e)
{
throw new VelocityException("IO Error rendering template '"+
name + "'", e);
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java?rev=747067&r1=747066&r2=747067&view=diff
==============================================================================
---
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
(original)
+++
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
Mon Feb 23 16:21:48 2009
@@ -57,7 +57,6 @@
import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
-import org.apache.velocity.runtime.parser.node.ASTStop.StopThrowable;
import org.apache.velocity.runtime.resource.ContentResource;
import org.apache.velocity.runtime.resource.ResourceManager;
import org.apache.velocity.util.ClassUtils;
@@ -1372,14 +1371,6 @@
throw stop;
}
}
- catch (StopThrowable st)
- {
- // The stop throwable is thrown by ASTStop (the #stop
directive)
- // The intent of the stop directive is to halt processing of
the
- // the template, so we throw a Throwable that will short
circuit
- // everthing between this call to render, and ASTStop. We just
needed to
- // Catch the exception, nothing else to do.
- }
catch (IOException e)
{
throw new VelocityException("IO Error in writer: " +
e.getMessage(), e);
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java?rev=747067&r1=747066&r2=747067&view=diff
==============================================================================
---
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
(original)
+++
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
Mon Feb 23 16:21:48 2009
@@ -21,24 +21,16 @@
import java.io.IOException;
import java.io.Writer;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.velocity.app.event.EventCartridge;
-import org.apache.velocity.context.Context;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.TemplateInitException;
-import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeServices;
-import org.apache.velocity.runtime.parser.node.ASTReference;
+import org.apache.velocity.runtime.log.Log;
+import org.apache.velocity.runtime.parser.node.ASTDirective;
import org.apache.velocity.runtime.parser.node.Node;
-import org.apache.velocity.runtime.parser.node.SimpleNode;
-import org.apache.velocity.runtime.resource.Resource;
-import org.apache.velocity.util.introspection.Info;
-import org.apache.velocity.util.introspection.IntrospectionCacheData;
/**
* Break directive used for interrupting foreach loops.
@@ -48,7 +40,7 @@
*/
public class Break extends Directive
{
- private static final RuntimeException BREAK = new BreakException();
+ private static final BreakCommand BREAK = new BreakCommand();
/**
* Return name of this directive.
* @return The name of this directive.
@@ -88,12 +80,26 @@
throws TemplateInitException
{
super.init(rs, context, node);
+
+ // Make sure the #break directive is within a foreach block.
+ Node check = node;
+ while (!(check instanceof ASTDirective) ||
+ !((ASTDirective)check).getDirectiveName().equals("foreach"))
+ {
+ check = check.jjtGetParent();
+ if (check == null)
+ {
+ // We are not in a macro definition, so throw an exception.
+ throw new VelocityException("#break must be within a #foreach
block at "
+ + Log.formatFileString(this));
+ }
+ }
}
/**
* Break directive does not actually do any rendering.
*
- * This directive throws a BreakException (RuntimeException) which
+ * This directive throws a BreakCommand which
* signals foreach directive to break out of the loop. Note that this
* directive does not verify that it is being called inside a foreach
* loop.
@@ -115,14 +121,21 @@
throw BREAK;
}
- public static class BreakException extends RuntimeException
+ /**
+ * Specialized StopCommand that stops the nearest #foreach loop.
+ */
+ public static class BreakCommand extends StopCommand
{
- public BreakException()
+ public BreakCommand()
+ {
+ // If a break is thrown during a macro or parse call, then this
exception
+ // will eventually be seen, so provide the user with some info.
+ super("closest #foreach loop");
+ }
+
+ public boolean isFor(Object that)
{
- // If a break is thrown during a macro or parse call, then this
exception
- // will be logged because this method calls catch
- // RuntimeException, so provide the user with some info.
- super("Break");
+ return (that instanceof Foreach);
}
}
}
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Evaluate.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Evaluate.java?rev=747067&r1=747066&r2=747067&view=diff
==============================================================================
---
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Evaluate.java
(original)
+++
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Evaluate.java
Mon Feb 23 16:21:48 2009
@@ -35,7 +35,6 @@
import org.apache.velocity.runtime.parser.ParserTreeConstants;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
-import org.apache.velocity.runtime.parser.node.ASTStop.StopThrowable;
import org.apache.velocity.util.introspection.Info;
/**
@@ -212,14 +211,6 @@
throw stop;
}
}
- catch (StopThrowable st)
- {
- // The stop throwable is thrown by ASTStop (the #stop
directive)
- // The intent of the stop directive is to halt processing
of the
- // the template, so we throw a Throwable that will short
circuit
- // everthing between this node, and ASTStop. We just
needed to
- // Catch the exception, nothing else to do.
- }
catch (ParseErrorException pex)
{
// convert any parsing errors to the correct line/col
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java?rev=747067&r1=747066&r2=747067&view=diff
==============================================================================
---
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
(original)
+++
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
Mon Feb 23 16:21:48 2009
@@ -397,11 +397,6 @@
throw stop;
}
}
- catch (Break.BreakException ex)
- {
- // encountered #break directive inside #foreach loop
- break;
- }
counter++;
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTStop.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTStop.java?rev=747067&r1=747066&r2=747067&view=diff
==============================================================================
---
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTStop.java
(original)
+++
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTStop.java
Mon Feb 23 16:21:48 2009
@@ -21,13 +21,17 @@
import java.io.IOException;
import java.io.Writer;
-
+import org.apache.velocity.Template;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.RuntimeInstance;
+import org.apache.velocity.runtime.directive.Evaluate;
+import org.apache.velocity.runtime.directive.StopCommand;
import org.apache.velocity.runtime.parser.Parser;
+
/**
* This class is responsible for handling the #stop directive
*
@@ -40,6 +44,8 @@
*/
public class ASTStop extends SimpleNode
{
+ private static final StopCommand STOP = new StopAllCommand();
+
/**
* @param id
*/
@@ -80,17 +86,29 @@
{
// The top level calls that render an AST node tree catch this
Throwable. By throwing
// Here we terminate rendering of this node tree.
- throw new StopThrowable();
+ throw STOP;
}
-
+
/**
- * We select to overide Error here intead of RuntimeInstance because there
are
- * certain nodes that catch RuntimeException when rendering there
children, and log
- * the event to error. But of course in the case that the template
renders an ASTStop
- * node we don't want this to happen.
+ * Specialized StopCommand that stops all merge or evaluate activity.
*/
- public static class StopThrowable extends Error
- {
+ public static class StopAllCommand extends StopCommand
+ {
+ public StopAllCommand()
+ {
+ super("Template.merge or RuntimeInstance.evaluate");
+ }
+
+ public boolean isFor(Object that)
+ {
+ return (that instanceof Template ||
+ that instanceof RuntimeInstance ||
+ //FIXME: #evaluate probably shouldn't catch #stop()
+ // since it isn't truly top-level, but that's
+ // how it was currently designed.
+ that instanceof Evaluate);
+ }
}
+
}