1 14 15 package com.sun.facelets.tag.jstl.core; 16 17 import java.io.IOException ; 18 import java.lang.reflect.Array ; 19 import java.util.Collection ; 20 import java.util.Iterator ; 21 import java.util.Map ; 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 41 public final class ForEachHandler extends TagHandler { 42 43 private static class ArrayIterator implements Iterator { 44 45 protected final Object array; 46 47 protected int i; 48 49 protected final int len; 50 51 public ArrayIterator(Object 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 next() { 62 return Array.get(this.array, this.i++); 63 } 64 65 public void remove() { 66 throw new UnsupportedOperationException (); 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 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 , FacesException, FaceletException, ELException { 107 108 int s = this.getBegin(ctx); 109 int e = this.getEnd(ctx); 110 int m = this.getStep(ctx); 111 Integer sO = this.begin != null ? new Integer (s) : null; 112 Integer eO = this.end != null ? new Integer (e) : null; 113 Integer mO = this.step != null ? new Integer (m) : null; 114 115 boolean t = this.getTransient(ctx); 116 Object src = null; 117 ValueExpression srcVE = null; 118 if (this.items != null) { 119 srcVE = this.items.getValueExpression(ctx, Object .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 itr = this.toIterator(src); 130 if (itr != null) { 131 int i = 0; 132 133 while (i < s && itr.hasNext()) { 135 itr.next(); 136 i++; 137 } 138 139 String v = this.getVarName(ctx); 140 String 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 value = null; 147 try { 148 boolean first = true; 149 while (i <= e && itr.hasNext()) { 150 value = itr.next(); 151 152 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 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 this.nextHandler.apply(ctx, parent); 175 176 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 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 src, 235 Object value, int i) { 236 if (src instanceof Collection || src.getClass().isArray()) { 237 return new IndexedValueExpression(ve, i); 238 } else if (src instanceof Map && value instanceof Map.Entry ) { 239 return new MappedValueExpression(ve, (Map.Entry ) value); 240 } 241 throw new IllegalStateException ("Cannot create VE for: " + src); 242 } 243 244 private final String getVarName(FaceletContext ctx) { 245 if (this.var != null) { 246 return this.var.getValue(ctx); 247 } 248 return null; 249 } 250 251 private final String getVarStatusName(FaceletContext ctx) { 252 if (this.varStatus != null) { 253 return this.varStatus.getValue(ctx); 254 } 255 return null; 256 } 257 258 private final Iterator toIterator(Object src) { 259 if (src == null) { 260 return null; 261 } else if (src instanceof Collection ) { 262 return ((Collection ) src).iterator(); 263 } else if (src instanceof Map ) { 264 return ((Map ) 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 |