1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
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
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 }