Author: byron
Date: Tue Feb 17 16:02:08 2009
New Revision: 745130
URL: http://svn.apache.org/viewvc?rev=745130&view=rev
Log:
VELOCITY-696 Add 'index' keyword to Foread directive to define an index variable
Modified:
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/Foreach.java
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/BlockMacroTestCase.java
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/ForeachTestCase.java
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/LocalDirectiveTestCase.java
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/TemplateTestCase.java
Modified:
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/Foreach.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/Foreach.java?rev=745130&r1=745129&r2=745130&view=diff
==============================================================================
---
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/Foreach.java
(original)
+++
velocity/engine/branches/2.0_Exp/src/java/org/apache/velocity/runtime/directive/Foreach.java
Tue Feb 17 16:02:08 2009
@@ -166,11 +166,21 @@
*/
elementKey = sn.getFirstToken().image.substring(1);
}
+
+ // If we have more then 3 argument then the user has specified an
+ // index value, i.e.; #foreach($a in $b index $c)
+ if (node.jjtGetNumChildren() > 4)
+ {
+ // The index variable name is at position 4
+ counterName = ((ASTReference) node.jjtGetChild(4)).getRootString();
+ // The count value always starts at 0 when using an index.
+ counterInitialValue = 0;
+ }
/*
* make an uberinfo - saves new's later on
*/
-
+
uberInfo = new Info(this.getTemplateName(),
getLine(),getColumn());
}
@@ -252,6 +262,9 @@
int counter = counterInitialValue;
boolean maxNbrLoopsExceeded = false;
+ // Get the block ast tree which is always the last child
+ Node block = node.jjtGetChild(node.jjtGetNumChildren()-1);
+
/*
* save the element key if there is one, and the loop counter
*/
@@ -265,10 +278,11 @@
Object value = i.next();
put(context, hasNextName, Boolean.valueOf(i.hasNext()));
put(context, elementKey, value);
+
try
{
- node.jjtGetChild(3).render(context, writer);
+ block.render(context, writer);
}
catch (Break.BreakException ex)
{
@@ -339,12 +353,11 @@
throw new MacroParseException("Too few arguments to the #foreach
directive",
templateName, t);
}
- else if (argtypes.get(0) == ParserTreeConstants.JJTWORD)
+ else if (argtypes.get(0) != ParserTreeConstants.JJTREFERENCE)
{
- throw new MacroParseException("Argument 1 of #foreach is of the
wrong type",
+ throw new MacroParseException("Expected argument 1 of #foreach to
be a reference",
templateName, t);
- }
-
+ }
else if (argtypes.get(1) != ParserTreeConstants.JJTWORD)
{
throw new MacroParseException("Expected word 'in' at argument
position 2 in #foreach",
@@ -355,6 +368,20 @@
throw new MacroParseException("Argument 3 of #foreach is of the
wrong type",
templateName, t);
}
- }
-
+
+ // If #foreach is defining an index variable make sure it has the
'index $var' combo.
+ if (argtypes.size() > 3)
+ {
+ if (argtypes.get(3) != ParserTreeConstants.JJTWORD)
+ {
+ throw new MacroParseException("Expected word 'index' at
argument position 4 in #foreach",
+ templateName, t);
+ }
+ else if (argtypes.size() == 4 || argtypes.get(4) !=
ParserTreeConstants.JJTREFERENCE)
+ {
+ throw new MacroParseException("Expected a reference after
'index' in #foreach",
+ templateName, t);
+ }
+ }
+ }
}
Modified:
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/BlockMacroTestCase.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/BlockMacroTestCase.java?rev=745130&r1=745129&r2=745130&view=diff
==============================================================================
---
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/BlockMacroTestCase.java
(original)
+++
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/BlockMacroTestCase.java
Tue Feb 17 16:02:08 2009
@@ -29,7 +29,6 @@
public BlockMacroTestCase(String name)
{
super(name);
- DEBUG=true;
}
public void testMultipleBodyContentIncludes() throws Exception
Modified:
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/ForeachTestCase.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/ForeachTestCase.java?rev=745130&r1=745129&r2=745130&view=diff
==============================================================================
---
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/ForeachTestCase.java
(original)
+++
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/ForeachTestCase.java
Tue Feb 17 16:02:08 2009
@@ -57,6 +57,19 @@
assertEvalEquals("1 2 3 ", "#foreach ($item in [1..10])$item #end");
}
+
+ public void testIndexKeyword()
+ {
+ assertEvalEquals("041526", "#set($b = [4, 5, 6])#foreach($a in $b
index $c)$c$a#end");
+ assertEvalEquals("444546545556646566", "#set($b = [4, 5,
6])#foreach($a in $b index $c)#foreach($x in $b index $c)$a$x#end#end");
+ }
+
+ public void testIndexErrors()
+ {
+ assertEvalException("#foreach($a in b)#end");
+ assertEvalException("#foreach($a in $b index)#end");
+ assertEvalException("#foreach($a in $b index blaa)#end");
+ }
/**
* Tests proper method execution during a Foreach loop over a Collection
Modified:
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/LocalDirectiveTestCase.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/LocalDirectiveTestCase.java?rev=745130&r1=745129&r2=745130&view=diff
==============================================================================
---
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/LocalDirectiveTestCase.java
(original)
+++
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/LocalDirectiveTestCase.java
Tue Feb 17 16:02:08 2009
@@ -30,7 +30,6 @@
public LocalDirectiveTestCase(String name)
{
super(name);
- DEBUG = true;
}
public void testSimple() throws Exception
Modified:
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/TemplateTestCase.java
URL:
http://svn.apache.org/viewvc/velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/TemplateTestCase.java?rev=745130&r1=745129&r2=745130&view=diff
==============================================================================
---
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/TemplateTestCase.java
(original)
+++
velocity/engine/branches/2.0_Exp/src/test/org/apache/velocity/test/TemplateTestCase.java
Tue Feb 17 16:02:08 2009
@@ -31,6 +31,7 @@
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.FieldMethodizer;
+import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.apache.velocity.test.provider.BoolObj;
import org.apache.velocity.test.provider.NullToStringObject;
@@ -100,7 +101,11 @@
* Sets up the test.
*/
protected void setUp ()
+ throws Exception
{
+ super.setUp();
+ engine.setProperty(RuntimeConstants.COUNTER_INITIAL_VALUE, 1);
+
provider = new TestProvider();
al = provider.getCustomers();
h = new Hashtable();