You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by nb...@apache.org on 2008/08/18 20:29:34 UTC
svn commit: r686842 - in /velocity/engine/trunk/src:
java/org/apache/velocity/runtime/defaults/
java/org/apache/velocity/runtime/directive/ test/org/apache/velocity/test/
Author: nbubna
Date: Mon Aug 18 11:29:31 2008
New Revision: 686842
URL: http://svn.apache.org/viewvc?rev=686842&view=rev
Log:
VELOCITY-612 add #break for #foreach (thanks to Jarkko Viinamaki)
Added:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java (with props)
velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java (with props)
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/directive.properties
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/directive.properties
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/directive.properties?rev=686842&r1=686841&r2=686842&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/directive.properties (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/directive.properties Mon Aug 18 11:29:31 2008
@@ -20,3 +20,4 @@
directive.4=org.apache.velocity.runtime.directive.Macro
directive.5=org.apache.velocity.runtime.directive.Literal
directive.6=org.apache.velocity.runtime.directive.Evaluate
+directive.7=org.apache.velocity.runtime.directive.Break
\ No newline at end of file
Added: 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=686842&view=auto
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java (added)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java Mon Aug 18 11:29:31 2008
@@ -0,0 +1,112 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+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.runtime.RuntimeServices;
+import org.apache.velocity.runtime.parser.node.ASTReference;
+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.
+ *
+ * @author <a href="mailto:wyla@removethis.sci.fi">Jarkko Viinamaki</a>
+ * @version $Id$
+ */
+public class Break extends Directive
+{
+ /**
+ * Return name of this directive.
+ * @return The name of this directive.
+ */
+ public String getName()
+ {
+ return "break";
+ }
+
+ /**
+ * Return type of this directive.
+ * @return The type of this directive.
+ */
+ public int getType()
+ {
+ return LINE;
+ }
+
+ /**
+ * simple init - init the tree and get the elementKey from
+ * the AST
+ * @param rs
+ * @param context
+ * @param node
+ * @throws TemplateInitException
+ */
+ public void init(RuntimeServices rs, InternalContextAdapter context, Node node)
+ throws TemplateInitException
+ {
+ super.init(rs, context, node);
+ }
+
+ /**
+ * Break directive does not actually do any rendering.
+ *
+ * This directive throws a BreakException (RuntimeException) 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.
+ *
+ * @param context
+ * @param writer
+ * @param node
+ * @return true if the directive rendered successfully.
+ * @throws IOException
+ * @throws MethodInvocationException
+ * @throws ResourceNotFoundException
+ * @throws ParseErrorException
+ */
+ public boolean render(InternalContextAdapter context,
+ Writer writer, Node node)
+ throws IOException, MethodInvocationException, ResourceNotFoundException,
+ ParseErrorException
+ {
+ throw new BreakException();
+ }
+
+ public static class BreakException extends RuntimeException
+ {
+
+ }
+}
Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
------------------------------------------------------------------------------
svn:keywords = Revision
Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Break.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=686842&r1=686841&r2=686842&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 Aug 18 11:29:31 2008
@@ -499,28 +499,37 @@
while (!maxNbrLoopsExceeded && i.hasNext())
{
- // TODO: JDK 1.4+ -> valueOf()
+ // TODO: JDK 1.4+ -> Integer.valueOf()
context.localPut(counterName , new Integer(counter));
context.localPut(hasNextName, Boolean.valueOf(i.hasNext()));
Object value = i.next();
context.localPut(elementKey, value);
- /*
- * If the value is null, use the special null holder context
- */
- if( value == null )
+ try
{
- if( nullHolderContext == null )
+ /*
+ * If the value is null, use the special null holder context
+ */
+ if (value == null)
{
- // lazy instantiation
- nullHolderContext = new NullHolderContext(elementKey, context);
+ if (nullHolderContext == null)
+ {
+ // lazy instantiation
+ nullHolderContext = new NullHolderContext(elementKey, context);
+ }
+ node.jjtGetChild(3).render(nullHolderContext, writer);
+ }
+ else
+ {
+ node.jjtGetChild(3).render(context, writer);
}
- node.jjtGetChild(3).render(nullHolderContext, writer);
}
- else
+ catch (Break.BreakException ex)
{
- node.jjtGetChild(3).render(context, writer);
+ // encountered #break directive inside #foreach loop
+ break;
}
+
counter++;
// Determine whether we're allowed to continue looping.
Added: velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java?rev=686842&view=auto
==============================================================================
--- velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java (added)
+++ velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java Mon Aug 18 11:29:31 2008
@@ -0,0 +1,102 @@
+package org.apache.velocity.test;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.SystemLogChute;
+
+/**
+ * This class tests the break directive within Foreach loop.
+ */
+public class ForeachBreakTestCase extends TestCase
+{
+ private VelocityEngine engine;
+ private VelocityContext context;
+
+ public ForeachBreakTestCase(String name)
+ {
+ super(name);
+ }
+
+ public void setUp()
+ throws Exception
+ {
+ engine = new VelocityEngine();
+
+ // make the engine's log output go to the test-report
+ SystemLogChute log = new SystemLogChute();
+ log.setEnabledLevel(SystemLogChute.INFO_ID);
+ log.setSystemErrLevel(SystemLogChute.WARN_ID);
+ engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, log);
+
+ context = new VelocityContext();
+ }
+
+ /**
+ * Tests break directive with a couple of iterations.
+ */
+ public void testConditionalBreakDirective()
+ {
+ assertEvalEquals("1, 2, 3, 4, 5",
+ "#foreach($i in [1..10])$i#if($i > 4)#break#end, #end");
+ }
+
+ /**
+ * Tests break directive with immediate break.
+ */
+ public void testUnconditionalBreakDirective()
+ {
+ assertEvalEquals("1", "#foreach($i in [1..5])$i#break #end");
+ }
+
+ public void testNestedForeach()
+ {
+ assertEvalEquals("~~~, ~~, ~, ",
+ "#foreach($i in [1..3])#foreach($j in [2..4])#if($i*$j >= 8)#break#end~#end, #end");
+ }
+
+ protected void assertEvalEquals(String expected, String template)
+ {
+ try
+ {
+ String result = evaluate(template);
+ assertEquals(expected, result);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String evaluate(String template) throws Exception
+ {
+ StringWriter writer = new StringWriter();
+ // use template as its own name, since our templates are short
+ engine.evaluate(context, writer, template, template);
+ return writer.toString();
+ }
+}
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java
------------------------------------------------------------------------------
svn:keywords = Revision
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/ForeachBreakTestCase.java
------------------------------------------------------------------------------
svn:mime-type = text/plain