jstrachan    2002/10/23 23:59:54

  Modified:    jelly/src/java/org/apache/commons/jelly/tags/core
                        CoreTagLibrary.java ForEachTag.java WhileTag.java
               jelly/src/test/org/apache/commons/jelly suite.jelly
  Added:       jelly/src/java/org/apache/commons/jelly/tags/core
                        BreakTag.java
               jelly/src/java/org/apache/commons/jelly/impl
                        BreakException.java
  Log:
  Adding the ability to break out of loops based on Vinay's patch.
  Throwing a BreakException will terminate a <forEach> or <while> loop, which the 
<break> tag now does (along with an optional test)
  
  
  Revision  Changes    Path
  1.21      +6 -5      
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/CoreTagLibrary.java
  
  Index: CoreTagLibrary.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/CoreTagLibrary.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- CoreTagLibrary.java       22 Oct 2002 15:13:43 -0000      1.20
  +++ CoreTagLibrary.java       24 Oct 2002 06:59:53 -0000      1.21
  @@ -104,6 +104,7 @@
           registerTag("import", ImportTag.class);
           
           // extensions to JSTL
  +        registerTag("break", BreakTag.class);
           registerTag("expr", ExprTag.class);
           registerTag("new", NewTag.class);
           registerTag("setProperties", SetPropertiesTag.class);
  
  
  
  1.17      +52 -44    
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/ForEachTag.java
  
  Index: ForEachTag.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/ForEachTag.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- ForEachTag.java   12 Oct 2002 12:25:23 -0000      1.16
  +++ ForEachTag.java   24 Oct 2002 06:59:53 -0000      1.17
  @@ -73,6 +73,7 @@
   import org.apache.commons.jelly.TagSupport;
   import org.apache.commons.jelly.XMLOutput;
   import org.apache.commons.jelly.expression.Expression;
  +import org.apache.commons.jelly.impl.BreakException;
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -126,55 +127,62 @@
               log.debug("running with items: " + items);
           }
   
  -        if (items != null) {
  -            Iterator iter = items.evaluateAsIterator(context);
  -            if (log.isDebugEnabled()) {
  -                log.debug("Iterating through: " + iter);
  -            }
  -
  -            // ignore the first items of the iterator
  -            for (index = 0; index < begin && iter.hasNext(); index++ ) {
  -                iter.next();
  -            }
  -            
  -            while (iter.hasNext() && index < end) {
  -                Object value = iter.next();
  -                if (var != null) {
  -                    context.setVariable(var, value);
  +        try {            
  +            if (items != null) {
  +                Iterator iter = items.evaluateAsIterator(context);
  +                if (log.isDebugEnabled()) {
  +                    log.debug("Iterating through: " + iter);
                   }
  -                if (indexVar != null) {
  -                    context.setVariable(indexVar, new Integer(index));
  +    
  +                // ignore the first items of the iterator
  +                for (index = 0; index < begin && iter.hasNext(); index++ ) {
  +                    iter.next();
                   }
  -                invokeBody(output);
                   
  -                // now we need to move to next index
  -                index++;
  -                for ( int i = 1; i < step; i++, index++ ) {
  -                    if ( ! iter.hasNext() ) {
  -                       return;
  +                while (iter.hasNext() && index < end) {
  +                    Object value = iter.next();
  +                    if (var != null) {
  +                        context.setVariable(var, value);
  +                    }
  +                    if (indexVar != null) {
  +                        context.setVariable(indexVar, new Integer(index));
  +                    }
  +                    invokeBody(output);
  +                    
  +                    // now we need to move to next index
  +                    index++;
  +                    for ( int i = 1; i < step; i++, index++ ) {
  +                        if ( ! iter.hasNext() ) {
  +                           return;
  +                        }
  +                        iter.next();
                       }
  -                    iter.next();
                   }
               }
  -        }
  -        else {
  -            if ( end == Integer.MAX_VALUE && begin == 0 ) {
  -                throw new MissingAttributeException( "items" );
  -            }
               else {
  -                String varName = var;
  -                if ( varName == null ) {
  -                    varName = indexVar;
  +                if ( end == Integer.MAX_VALUE && begin == 0 ) {
  +                    throw new MissingAttributeException( "items" );
                   }
  -                
  -                for (index = begin; index <= end; index += step ) {
  -                
  -                    if (varName != null) {
  -                        Object value = new Integer(index);
  -                        context.setVariable(varName, value);
  +                else {
  +                    String varName = var;
  +                    if ( varName == null ) {
  +                        varName = indexVar;
  +                    }
  +                    
  +                    for (index = begin; index <= end; index += step ) {
  +                    
  +                        if (varName != null) {
  +                            Object value = new Integer(index);
  +                            context.setVariable(varName, value);
  +                        }
  +                        invokeBody(output);
                       }
  -                    invokeBody(output);
                   }
  +            }
  +        }
  +        catch (BreakException e) {
  +            if (log.isDebugEnabled()) {
  +                log.debug("loop terminated by break: " + e, e);
               }
           }
       }
  
  
  
  1.3       +13 -4     
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/WhileTag.java
  
  Index: WhileTag.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/WhileTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- WhileTag.java     5 Oct 2002 04:30:18 -0000       1.2
  +++ WhileTag.java     24 Oct 2002 06:59:53 -0000      1.3
  @@ -73,6 +73,7 @@
   import org.apache.commons.jelly.TagSupport;
   import org.apache.commons.jelly.XMLOutput;
   import org.apache.commons.jelly.expression.Expression;
  +import org.apache.commons.jelly.impl.BreakException;
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -107,13 +108,21 @@
       public void doTag(XMLOutput output) throws MissingAttributeException, 
       Exception {
           if (test != null) {
  -            while (test.evaluateAsBoolean(getContext())) {
  +            try {
  +                while (test.evaluateAsBoolean(getContext())) {
  +                    if (log.isDebugEnabled()) {
  +                        log.debug("evaluated to true! gonna keep on chuggin!");
  +                    }
  +                    invokeBody(output);
  +                }
  +            }
  +            catch (BreakException e) {
                   if (log.isDebugEnabled()) {
  -                    log.debug("evaluated to true! gonna keep on chuggin!");
  +                    log.debug("loop terminated by break: " + e, e);
                   }
  -                invokeBody(output);
               }
  -        } else {
  +        } 
  +        else {
               throw new MissingAttributeException("test");
           }
       }
  
  
  
  1.1                  
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/BreakTag.java
  
  Index: BreakTag.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/core/BreakTag.java,v
 1.9 2002/06/11 21:41:11 jstrachan Exp $
   * $Revision: 1.9 $
   * $Date: 2002/06/11 21:41:11 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: BreakTag.java,v 1.9 2002/06/11 21:41:11 jstrachan Exp $
   */
  package org.apache.commons.jelly.tags.core;
  
  import org.apache.commons.jelly.TagSupport;
  import org.apache.commons.jelly.XMLOutput;
  import org.apache.commons.jelly.impl.BreakException;
  import org.apache.commons.jelly.expression.Expression;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /** 
   * A tag which terminates the execution of the current &lt;forEach&gt; or 
&lg;while&gt;
   * loop. This tag can take an optional boolean test attribute which if its true
   * then the break occurs otherwise the loop continues processing.
   * 
   * @author <a href="mailto:jstrachan@;apache.org">James Strachan</a>
   * @version $Revision: 1.9 $
   */
  public class BreakTag extends TagSupport {
  
      /** The expression to evaluate. */
      private Expression test;
  
      /** The Log to which logging calls will be made. */
      private static final Log log = LogFactory.getLog(BreakTag.class);
  
      public BreakTag() {
      }
  
      // Tag interface
      //------------------------------------------------------------------------- 
      public void doTag(XMLOutput output) throws Exception {
          if (test == null || test.evaluateAsBoolean(context)) {
              throw new BreakException();
          }
      }
  
      /** 
       * Sets the Jelly expression to evaluate. 
       * If this returns true then the loop is terminated
       *
       * @param test the Jelly expression to evaluate
       */
      public void setTest(Expression test) {
          this.test = test;
      }
  }
  
  
  
  1.10      +39 -0     
jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/suite.jelly
  
  Index: suite.jelly
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/suite.jelly,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- suite.jelly       21 Oct 2002 11:12:42 -0000      1.9
  +++ suite.jelly       24 Oct 2002 06:59:54 -0000      1.10
  @@ -213,4 +213,43 @@
                        expected="foo 1 barfoo 2 barfoo 3 bar"
                        actual="${foo}"/>
     </test:case>
  +  
  +     <test:case name="testBreak">
  +             
  +             <j:forEach var="i" begin="1" end="10">
  +                     <j:if test="${i==4}">
  +                             <j:break/>
  +                     </j:if>
  +             </j:forEach>
  +
  +             <test:assertTrue test="${i==4}"/> 
  +
  +             <j:while test="${i != 10}">
  +                     <j:if test="${i==6}">
  +                             <j:break/>
  +                     </j:if>
  +                     <j:set var="i" value="${i+1}"/>
  +             </j:while>
  +
  +             <test:assertTrue test="${i==6}"/> 
  +             
  +  </test:case>
  +  
  +     <test:case name="testBreakWithIf">
  +             
  +             <j:forEach var="i" begin="1" end="10">
  +                     <j:break test="${i==4}"/>
  +             </j:forEach>
  +
  +             <test:assertTrue test="${i==4}"/> 
  +
  +             <j:while test="${i != 10}">
  +                     <j:break test="${i==6}"/>
  +                     <j:set var="i" value="${i+1}"/>
  +             </j:while>
  +
  +             <test:assertTrue test="${i==6}"/> 
  +             
  +  </test:case>
  +  
   </test:suite>
  
  
  
  1.1                  
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/impl/BreakException.java
  
  Index: BreakException.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/JellyException.java,v
 1.9 2002/07/15 16:18:15 werken Exp $
   * $Revision: 1.9 $
   * $Date: 2002/07/15 16:18:15 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: .java,v 1.9 2002/07/15 16:18:15 werken Exp $
   */
  
  package org.apache.commons.jelly.impl;
  
  import org.apache.commons.jelly.JellyException;
  
  /** 
   * <p><code>BreakException</code> is used to terminate loops such as 
   * &lt;forEach&gt; and &lt;while&gt; tags.</p>
   *
   * @author <a href="mailto:jstrachan@;apache.org">James Strachan</a>
   * @version $Revision: 1.9 $
   */
  
  public class BreakException extends JellyException {
      
      public BreakException() {
          super("Break exception, terminating the parent loop");
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@;jakarta.apache.org>

Reply via email to