View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.jelly.tags.core;
18  
19  import java.util.Iterator;
20  
21  import org.apache.commons.jelly.JellyTagException;
22  import org.apache.commons.jelly.MissingAttributeException;
23  import org.apache.commons.jelly.TagSupport;
24  import org.apache.commons.jelly.XMLOutput;
25  import org.apache.commons.jelly.expression.Expression;
26  import org.apache.commons.jelly.impl.BreakException;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  /***
31    * Iterates over a collection, iterator or an array of objects.
32    * Uses the same syntax as the <a href="http://java.sun.com/products/jsp/jstl/">JSTL</a>
33    * <code>forEach</code> tag does.
34    *
35    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
36    * @version $Revision: 1.28 $
37    */
38  public class ForEachTag extends TagSupport {
39  
40      /*** The Log to which logging calls will be made. */
41      private static final Log log = LogFactory.getLog(ForEachTag.class);
42  
43      /*** Holds the variable name to export for the item being iterated over. */
44      private Expression items;
45  
46      /***
47       * If specified then the current item iterated through will be defined
48       * as the given variable name.
49       */
50      private String var;
51  
52      /***
53       * If specified then the current index counter will be defined
54       * as the given variable name.
55       */
56      private String indexVar;
57  
58      /*** The starting index value */
59      private int begin;
60  
61      /*** The ending index value */
62      private int end = Integer.MAX_VALUE;
63  
64      /*** The index increment step */
65      private int step = 1;
66  
67      /*** The iteration index */
68      private int index;
69  
70      public ForEachTag() {
71      }
72  
73      // Tag interface
74  
75      //-------------------------------------------------------------------------
76      public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException {
77  
78          if (log.isDebugEnabled()) {
79              log.debug("running with items: " + items);
80          }
81  
82          try {
83              if (items != null) {
84                  Iterator iter = items.evaluateAsIterator(context);
85                  if (log.isDebugEnabled()) {
86                      log.debug("Iterating through: " + iter);
87                  }
88  
89                  // ignore the first items of the iterator
90                  for (index = 0; index < begin && iter.hasNext(); index++ ) {
91                      iter.next();
92                  }
93  
94                  while (iter.hasNext() && index < end) {
95                      Object value = iter.next();
96                      if (var != null) {
97                          context.setVariable(var, value);
98                      }
99                      if (indexVar != null) {
100                         context.setVariable(indexVar, new Integer(index));
101                     }
102                     invokeBody(output);
103 
104                     // now we need to move to next index
105                     index++;
106                     for ( int i = 1; i < step; i++, index++ ) {
107                         if ( ! iter.hasNext() ) {
108                            return;
109                         }
110                         iter.next();
111                     }
112                 }
113             }
114             else {
115                 if ( end == Integer.MAX_VALUE && begin == 0 ) {
116                     throw new MissingAttributeException( "items" );
117                 }
118                 else {
119                     String varName = var;
120                     if ( varName == null ) {
121                         varName = indexVar;
122                     }
123 
124                     for (index = begin; index <= end; index += step ) {
125 
126                         if (varName != null) {
127                             Object value = new Integer(index);
128                             context.setVariable(varName, value);
129                         }
130                         invokeBody(output);
131                     }
132                 }
133             }
134         }
135         catch (BreakException e) {
136             if (log.isDebugEnabled()) {
137                 log.debug("loop terminated by break: " + e, e);
138             }
139         }
140     }
141 
142     // Properties
143     //-------------------------------------------------------------------------
144 
145     /***
146      * Sets the expression used to iterate over.
147      * This expression could resolve to an Iterator, Collection, Map, Array,
148      * Enumeration or comma separated String.
149      */
150     public void setItems(Expression items) {
151         this.items = items;
152     }
153 
154     /*** Sets the variable name to export for the item being iterated over
155      */
156     public void setVar(String var) {
157         this.var = var;
158     }
159 
160     /*** Sets the variable name to export the current index counter to
161      */
162     public void setIndexVar(String indexVar) {
163         this.indexVar = indexVar;
164     }
165 
166     /*** Sets the starting index value
167      */
168     public void setBegin(int begin) {
169         this.begin = begin;
170     }
171 
172     /*** Sets the ending index value
173      */
174     public void setEnd(int end) {
175         this.end = end;
176     }
177 
178     /*** Sets the index increment step
179      */
180     public void setStep(int step) {
181         this.step = step;
182     }
183 
184     /***
185      * Sets the variable name to export the current index to.
186      * This does the same thing as #setIndexVar(), but is consistent
187      * with the <a href="http://java.sun.com/products/jsp/jstl/">JSTL</a>
188      * syntax.
189      */
190     public void setVarStatus(String var) {
191         setIndexVar( var );
192     }
193 }