KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > facelets > tag > jstl > core > ForEachHandler


1 /**
2  * Licensed under the Common Development and Distribution License,
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://www.sun.com/cddl/
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */

14
15 package com.sun.facelets.tag.jstl.core;
16
17 import java.io.IOException JavaDoc;
18 import java.lang.reflect.Array JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import javax.el.ELException;
24 import javax.el.ValueExpression;
25 import javax.el.VariableMapper;
26 import javax.faces.FacesException;
27 import javax.faces.component.UIComponent;
28
29 import com.sun.facelets.FaceletContext;
30 import com.sun.facelets.FaceletException;
31 import com.sun.facelets.tag.TagAttribute;
32 import com.sun.facelets.tag.TagAttributeException;
33 import com.sun.facelets.tag.TagConfig;
34 import com.sun.facelets.tag.TagHandler;
35
36 /**
37  * @author Jacob Hookom
38  * @author Andrew Robinson
39  * @version $Id: ForEachHandler.java,v 1.8 2006/03/19 03:11:34 jhook Exp $
40  */

41 public final class ForEachHandler extends TagHandler {
42
43     private static class ArrayIterator implements Iterator JavaDoc {
44
45         protected final Object JavaDoc array;
46
47         protected int i;
48
49         protected final int len;
50
51         public ArrayIterator(Object JavaDoc src) {
52             this.i = 0;
53             this.array = src;
54             this.len = Array.getLength(src);
55         }
56
57         public boolean hasNext() {
58             return this.i < this.len;
59         }
60
61         public Object JavaDoc next() {
62             return Array.get(this.array, this.i++);
63         }
64
65         public void remove() {
66             throw new UnsupportedOperationException JavaDoc();
67         }
68     }
69
70     private final TagAttribute begin;
71
72     private final TagAttribute end;
73
74     private final TagAttribute items;
75
76     private final TagAttribute step;
77
78     private final TagAttribute tranzient;
79
80     private final TagAttribute var;
81
82     private final TagAttribute varStatus;
83
84     /**
85      * @param config
86      */

87     public ForEachHandler(TagConfig config) {
88         super(config);
89         this.items = this.getAttribute("items");
90         this.var = this.getAttribute("var");
91         this.begin = this.getAttribute("begin");
92         this.end = this.getAttribute("end");
93         this.step = this.getAttribute("step");
94         this.varStatus = this.getAttribute("varStatus");
95         this.tranzient = this.getAttribute("transient");
96
97         if (this.items == null && this.begin != null && this.end == null) {
98             throw new TagAttributeException(
99                     this.tag,
100                     this.begin,
101                     "If the 'items' attribute is not specified, but the 'begin' attribute is, then the 'end' attribute is required");
102         }
103     }
104
105     public void apply(FaceletContext ctx, UIComponent parent)
106             throws IOException JavaDoc, FacesException, FaceletException, ELException {
107         
108         int s = this.getBegin(ctx);
109         int e = this.getEnd(ctx);
110         int m = this.getStep(ctx);
111         Integer JavaDoc sO = this.begin != null ? new Integer JavaDoc(s) : null;
112         Integer JavaDoc eO = this.end != null ? new Integer JavaDoc(e) : null;
113         Integer JavaDoc mO = this.step != null ? new Integer JavaDoc(m) : null;
114         
115         boolean t = this.getTransient(ctx);
116         Object JavaDoc src = null;
117         ValueExpression srcVE = null;
118         if (this.items != null) {
119             srcVE = this.items.getValueExpression(ctx, Object JavaDoc.class);
120             src = srcVE.getValue(ctx);
121         } else {
122             byte[] b = new byte[e + 1];
123             for (int i = 0; i < b.length; i++) {
124                 b[i] = (byte) i;
125             }
126             src = b;
127         }
128         if (src != null) {
129             Iterator JavaDoc itr = this.toIterator(src);
130             if (itr != null) {
131                 int i = 0;
132
133                 // move to start
134
while (i < s && itr.hasNext()) {
135                     itr.next();
136                     i++;
137                 }
138
139                 String JavaDoc v = this.getVarName(ctx);
140                 String JavaDoc vs = this.getVarStatusName(ctx);
141                 VariableMapper vars = ctx.getVariableMapper();
142                 ValueExpression ve = null;
143                 ValueExpression vO = this.capture(v, vars);
144                 ValueExpression vsO = this.capture(vs, vars);
145                 int mi = 0;
146                 Object JavaDoc value = null;
147                 try {
148                     boolean first = true;
149                     while (i <= e && itr.hasNext()) {
150                         value = itr.next();
151
152                         // set the var
153
if (v != null) {
154                             if (t || srcVE == null) {
155                                 ctx.setAttribute(v, value);
156                             } else {
157                                 ve = this.getVarExpr(srcVE, src, value, i);
158                                 vars.setVariable(v, ve);
159                             }
160                         }
161
162                         // set the varStatus
163
if (vs != null) {
164                             IterationStatus itrS = new IterationStatus(first, !itr.hasNext(),i, sO, eO, mO);
165                             if (t || srcVE == null) {
166                                 ctx.setAttribute(vs, itrS);
167                             } else {
168                                 ve = new IterationStatusExpression(itrS);
169                                 vars.setVariable(vs, ve);
170                             }
171                         }
172
173                         // execute body
174
this.nextHandler.apply(ctx, parent);
175
176                         // increment steps
177
mi = 1;
178                         while (mi < m && itr.hasNext()) {
179                             itr.next();
180                             mi++;
181                             i++;
182                         }
183                         i++;
184                         
185                         first = false;
186                     }
187                 } finally {
188                     if (v != null) {
189                         vars.setVariable(v, vO);
190                     }
191                     if (vs != null) {
192                         vars.setVariable(vs, vsO);
193                     }
194                 }
195             }
196         }
197     }
198
199     private final ValueExpression capture(String JavaDoc name, VariableMapper vars) {
200         if (name != null) {
201             return vars.setVariable(name, null);
202         }
203         return null;
204     }
205
206     private final int getBegin(FaceletContext ctx) {
207         if (this.begin != null) {
208             return this.begin.getInt(ctx);
209         }
210         return 0;
211     }
212
213     private final int getEnd(FaceletContext ctx) {
214         if (this.end != null) {
215             return this.end.getInt(ctx);
216         }
217         return Integer.MAX_VALUE;
218     }
219
220     private final int getStep(FaceletContext ctx) {
221         if (this.step != null) {
222             return this.step.getInt(ctx);
223         }
224         return 1;
225     }
226
227     private final boolean getTransient(FaceletContext ctx) {
228         if (this.tranzient != null) {
229             return this.tranzient.getBoolean(ctx);
230         }
231         return false;
232     }
233
234     private final ValueExpression getVarExpr(ValueExpression ve, Object JavaDoc src,
235             Object JavaDoc value, int i) {
236         if (src instanceof Collection JavaDoc || src.getClass().isArray()) {
237             return new IndexedValueExpression(ve, i);
238         } else if (src instanceof Map JavaDoc && value instanceof Map.Entry JavaDoc) {
239             return new MappedValueExpression(ve, (Map.Entry JavaDoc) value);
240         }
241         throw new IllegalStateException JavaDoc("Cannot create VE for: " + src);
242     }
243
244     private final String JavaDoc getVarName(FaceletContext ctx) {
245         if (this.var != null) {
246             return this.var.getValue(ctx);
247         }
248         return null;
249     }
250
251     private final String JavaDoc getVarStatusName(FaceletContext ctx) {
252         if (this.varStatus != null) {
253             return this.varStatus.getValue(ctx);
254         }
255         return null;
256     }
257
258     private final Iterator JavaDoc toIterator(Object JavaDoc src) {
259         if (src == null) {
260             return null;
261         } else if (src instanceof Collection JavaDoc) {
262             return ((Collection JavaDoc) src).iterator();
263         } else if (src instanceof Map JavaDoc) {
264             return ((Map JavaDoc) src).entrySet().iterator();
265         } else if (src.getClass().isArray()) {
266             return new ArrayIterator(src);
267         } else {
268             throw new TagAttributeException(this.tag, this.items,
269                     "Must evaluate to a Collection, Map, Array, or null.");
270         }
271     }
272
273 }
274
Popular Tags