KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jstl > el > ForEachTag


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.jstl.el;
30
31 import com.caucho.el.Expr;
32 import com.caucho.jsp.PageContextImpl;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.util.EnumIterator;
35 import com.caucho.util.L10N;
36 import com.caucho.util.NullIterator;
37
38 import javax.el.ELContext;
39 import javax.servlet.jsp.JspException JavaDoc;
40 import javax.servlet.jsp.JspTagException JavaDoc;
41 import javax.servlet.jsp.jstl.core.LoopTag;
42 import javax.servlet.jsp.jstl.core.LoopTagStatus;
43 import javax.servlet.jsp.tagext.IterationTag JavaDoc;
44 import javax.servlet.jsp.tagext.TagSupport JavaDoc;
45 import java.lang.reflect.Array JavaDoc;
46 import java.util.Collection JavaDoc;
47 import java.util.Enumeration JavaDoc;
48 import java.util.Iterator JavaDoc;
49 import java.util.Map JavaDoc;
50
51 public class ForEachTag extends TagSupport JavaDoc
52   implements IterationTag JavaDoc, LoopTag, LoopTagStatus {
53   private static L10N L = new L10N(ForEachTag.class);
54   
55   protected Expr _itemsExpr;
56   
57   protected Expr _beginExpr;
58   protected Expr _endExpr;
59   protected Expr _stepExpr;
60   
61   protected String JavaDoc _var;
62   protected String JavaDoc _varStatus;
63
64   // runtime values
65
protected Iterator _iterator;
66   
67   protected int _begin;
68   protected int _end;
69   protected int _step;
70
71   protected Object JavaDoc _initialVar;
72   protected Object JavaDoc _current;
73   protected int _index;
74   protected int _count;
75
76   /**
77    * Sets the collection expression.
78    */

79   public void setItems(Expr items)
80   {
81     _itemsExpr = items;
82   }
83
84   /**
85    * Sets the beginning index.
86    */

87   public void setBegin(Expr begin)
88   {
89     _beginExpr = begin;
90   }
91
92   /**
93    * Sets the ending index.
94    */

95   public void setEnd(Expr end)
96   {
97     _endExpr = end;
98   }
99
100   /**
101    * Sets the step index.
102    */

103   public void setStep(Expr step)
104   {
105     _stepExpr = step;
106   }
107
108   /**
109    * Sets the iteration variable.
110    */

111   public void setVar(String JavaDoc var)
112   {
113     _var = var;
114   }
115
116   /**
117    * Sets the status variable.
118    */

119   public void setVarStatus(String JavaDoc var)
120   {
121     _varStatus = var;
122   }
123
124   /**
125    * Process the tag.
126    */

127   public int doStartTag()
128     throws JspException JavaDoc
129   {
130     try {
131       _iterator = null;
132       _index = 0;
133       _count = 0;
134
135       PageContextImpl pageContext = (PageContextImpl) this.pageContext;
136       ELContext env = pageContext.getELContext();
137
138       if (_beginExpr != null)
139     _begin = (int) _beginExpr.evalLong(env);
140       else
141     _begin = -1;
142
143       if (_endExpr != null)
144     _end = (int) _endExpr.evalLong(env);
145       else
146     _end = Integer.MAX_VALUE;
147
148       if (_stepExpr != null)
149     _step = (int) _stepExpr.evalLong(env);
150       else
151     _step = 0;
152     
153       Object JavaDoc items = null;
154
155       if (_itemsExpr != null) {
156     items = _itemsExpr.evalObject(env);
157
158     _iterator = getIterator(items);
159
160     while (_index < _begin && _iterator.hasNext()) {
161       _index++;
162       _iterator.next();
163     }
164       }
165       else if (_beginExpr == null)
166     throw new JspException JavaDoc(L.l("c:forEach must specify `items' or `begin'"));
167       else if (_endExpr == null)
168     throw new JspException JavaDoc(L.l("c:forEach must specify `items' or `begin'"));
169       else {
170     _iterator = new RangeIterator(_begin, _end);
171     _end = -1;
172       }
173
174       if (_varStatus != null)
175     pageContext.setAttribute(_varStatus, this);
176
177       if (_var != null)
178     _initialVar = pageContext.getAttribute(_var);
179
180       return doAfterBody();
181     } catch (Exception JavaDoc e) {
182       throw new JspException JavaDoc(e);
183     }
184   }
185
186   public int doAfterBody() throws JspException JavaDoc
187   {
188     if (_iterator == null) {
189       if (_var != null)
190     pageContext.setAttribute(_var, _initialVar);
191     
192       return SKIP_BODY;
193     }
194     else if (_iterator.hasNext()) {
195       int stepCount;
196
197       if (_step <= 0 || _count == 0)
198         stepCount = 1;
199       else
200         stepCount = _step;
201
202       for (; stepCount > 0; stepCount--) {
203         if (! _iterator.hasNext()) {
204       if (_var != null)
205         pageContext.setAttribute(_var, _initialVar);
206     
207           return SKIP_BODY;
208     }
209         
210         _index++;
211         _current = _iterator.next();
212       }
213
214       _count++;
215
216       if (_var != null)
217         pageContext.setAttribute(_var, _current);
218
219       if (_index - 1 <= _end || _end < 0)
220         return EVAL_BODY_AGAIN;
221       else {
222     if (_var != null)
223       pageContext.setAttribute(_var, _initialVar);
224     
225         return SKIP_BODY;
226       }
227     }
228     else {
229       if (_var != null)
230     pageContext.setAttribute(_var, _initialVar);
231     
232       return SKIP_BODY;
233     }
234   }
235
236   // LoopTag
237

238   /**
239    * Returns the status.
240    */

241   public LoopTagStatus getLoopStatus()
242   {
243     return this;
244   }
245     
246
247   // LoopTagStatus
248

249   /**
250    * Returns the current object.
251    */

252   public Object JavaDoc getCurrent()
253   {
254     return _current;
255   }
256
257   /**
258    * Returns the index.
259    */

260   public int getIndex()
261   {
262     return _index - 1;
263   }
264
265   /**
266    * Returns the number of objects returned.
267    */

268   public int getCount()
269   {
270     return _count;
271   }
272
273   /**
274    * Returns true if this is the first item.
275    */

276   public boolean isFirst()
277   {
278     return _count == 1;
279   }
280
281   /**
282    * Returns true if this is the last item.
283    */

284   public boolean isLast()
285   {
286     if (_iterator == null || ! _iterator.hasNext())
287       return true;
288     else if (_step > 0 && _step + _index > _end)
289       return true;
290     else
291       return false;
292   }
293
294   /**
295    * Returns the begin index.
296    */

297   public Integer JavaDoc getBegin()
298   {
299     if (_beginExpr != null && _itemsExpr != null)
300       return new Integer JavaDoc(_begin);
301     else
302       return null;
303   }
304   
305   /**
306    * Returns the end index.
307    */

308   public Integer JavaDoc getEnd()
309   {
310     if (_endExpr != null && _itemsExpr != null)
311       return new Integer JavaDoc(_end);
312     else
313       return null;
314   }
315   
316   /**
317    * Returns the step index.
318    */

319   public Integer JavaDoc getStep()
320   {
321     if (_stepExpr != null)
322       return new Integer JavaDoc(_step);
323     else
324       return null;
325   }
326
327   public static Iterator getIterator(Object JavaDoc items)
328     throws JspTagException JavaDoc
329   {
330     if (items == null)
331       return NullIterator.create();
332     else if (items instanceof Map JavaDoc)
333       return ((Map JavaDoc) items).entrySet().iterator();
334     else if (items instanceof Collection JavaDoc)
335       return ((Collection JavaDoc) items).iterator();
336     else if (items.getClass().isArray())
337       return new ArrayIterator(items);
338     else if (items instanceof Iterator)
339       return (Iterator) items;
340     else if (items instanceof Enumeration JavaDoc)
341       return new EnumIterator((Enumeration JavaDoc) items);
342     else if (items instanceof String JavaDoc)
343       return new StringIterator((String JavaDoc) items);
344     else
345       throw new JspTagException JavaDoc(L.l("unknown items value `{0}'", items));
346   }
347
348   public static class ArrayIterator implements Iterator {
349     private Object JavaDoc array;
350     private int index;
351     private int length;
352
353     ArrayIterator(Object JavaDoc array)
354     {
355       this.array = array;
356       this.length = Array.getLength(array);
357     }
358     
359     public boolean hasNext()
360     {
361       return index < length;
362     }
363     
364     public Object JavaDoc next()
365     {
366       if (index < length)
367         return Array.get(array, index++);
368       else
369         return null;
370     }
371     
372     public void remove()
373     {
374       throw new UnsupportedOperationException JavaDoc();
375     }
376   }
377
378   public static class StringIterator implements Iterator {
379     private String JavaDoc _value;
380     private int _length;
381     private int _i;
382     private CharBuffer _cb = new CharBuffer();
383
384     StringIterator(String JavaDoc value)
385     {
386       _value = value;
387       _length = value.length();
388     }
389     
390     public boolean hasNext()
391     {
392       return _i < _length;
393     }
394     
395     public Object JavaDoc next()
396     {
397       _cb.clear();
398
399       char ch = 0;
400       for (; _i < _length && (ch = _value.charAt(_i)) != ','; _i++)
401         _cb.append(ch);
402
403       _i++;
404
405       return _cb.toString();
406     }
407     
408     public void remove()
409     {
410       throw new UnsupportedOperationException JavaDoc();
411     }
412   }
413
414   public static class RangeIterator implements Iterator {
415     private int _end;
416     private int _i;
417
418     RangeIterator(int begin, int end)
419     {
420       _i = begin;
421       _end = end;
422     }
423     
424     public boolean hasNext()
425     {
426       return _i <= _end;
427     }
428     
429     public Object JavaDoc next()
430     {
431       if (_i <= _end)
432         return new Integer JavaDoc(_i++);
433       else
434         return null;
435     }
436     
437     public void remove()
438     {
439       throw new UnsupportedOperationException JavaDoc();
440     }
441   }
442 }
443
Popular Tags