Source code: org/milligan/eccles/tags/ForEachTag.java
1 package org.milligan.eccles.tags;
2
3 import org.milligan.eccles.*;
4 import java.util.Collection;
5 import java.util.Iterator;
6 import java.util.Arrays;
7 import java.util.Map;
8
9
10 /**
11 * Loop over items in a collection
12 * @author Ian Tomey
13 *
14 */
15
16 public class ForEachTag extends Tag {
17 protected static final String PROP_ITERATOR="iterator";
18
19 public ForEachTag() {
20 }
21
22 private String property = "item";
23 private String collection;
24 private String index = "forEachIndex";
25
26 public String getTagName() {
27 return "for-each";
28 }
29 public void setProperty(String property) {
30 this.property = property;
31 }
32 public String getProperty() {
33 return property;
34 }
35 public void setCollection(String collection) {
36 this.collection = collection;
37 }
38 public String getCollection() {
39 return collection;
40 }
41
42 /**
43 *
44 * @param state
45 * @return
46 * @throws EcclesException
47 */
48 public EcclesReturnValue doStartTag(RunState state) throws org.milligan.eccles.EcclesException {
49 Object coll = state.evaluate( collection, Object.class );
50 if (coll==null)
51 return SKIP_CHILDREN;
52
53 Iterator iterator=null;
54
55 // see if we have anything to do
56 if (coll.getClass().isArray())
57 iterator = Arrays.asList((Object[]) coll).iterator();
58 else if (coll instanceof Collection)
59 iterator = ((Collection) coll).iterator();
60 else if (coll instanceof Iterator)
61 iterator = (Iterator) coll;
62 else if (coll instanceof Map)
63 iterator = ((Map) coll).entrySet().iterator();
64 else
65 throw new EcclesException(state, "Object from "+collection+" is not a recognised type for iteration. type is "+coll.getClass() );
66
67 state.setPrivateProperty( PROP_ITERATOR, iterator );
68 state.setProperty( property, iterator.next() );
69
70 if ( index!=null )
71 state.setProperty( index, new Integer(0) );
72
73 return PROCESS_CHILDREN;
74 }
75
76 /**
77 *
78 * @param state
79 * @return
80 * @throws EcclesException
81 */
82 public EcclesReturnValue doAfterChildren(RunState state) throws org.milligan.eccles.EcclesException {
83 Iterator iterator = (Iterator) state.getPrivateProperty(PROP_ITERATOR);
84 if (iterator == null)
85 throw new EcclesException(state, "Iterator is null");
86
87 if (!iterator.hasNext())
88 return SKIP_CHILDREN;
89
90 state.setProperty( property, iterator.next() );
91
92 if ( index!=null ) {
93 Integer indexVal = (Integer) state.getProperty(index, false);
94 state.setProperty( index, new Integer( indexVal.intValue()+1 ) );
95 }
96
97 return PROCESS_CHILDREN;
98 }
99 public void setIndex(String index) {
100 this.index = index;
101 }
102 public String getIndex() {
103 return index;
104 }
105 }