1 16 17 package org.apache.commons.jelly.tags.core; 18 19 import java.util.Iterator ; 20 21 import javax.servlet.jsp.jstl.core.LoopTagStatus; 22 23 import org.apache.commons.jelly.JellyTagException; 24 import org.apache.commons.jelly.MissingAttributeException; 25 import org.apache.commons.jelly.TagSupport; 26 import org.apache.commons.jelly.XMLOutput; 27 import org.apache.commons.jelly.expression.Expression; 28 import org.apache.commons.jelly.impl.BreakException; 29 import org.apache.commons.logging.Log; 30 import org.apache.commons.logging.LogFactory; 31 32 40 public class ForEachTag extends TagSupport { 41 42 43 private static final Log log = LogFactory.getLog(ForEachTag.class); 44 45 46 private Expression items; 47 48 52 private String var; 53 54 58 private String indexVar; 59 60 61 private String statusVar; 62 63 64 private int begin; 65 66 67 private int end = Integer.MAX_VALUE; 68 69 70 private int step = 1; 71 72 73 private int index; 74 75 public ForEachTag() { 76 } 77 78 80 public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException { 82 83 if (log.isDebugEnabled()) { 84 log.debug("running with items: " + items); 85 } 86 87 try { 88 if (items != null) { 89 Iterator iter = items.evaluateAsIterator(context); 90 91 if (log.isDebugEnabled()) { 92 log.debug("Iterating through: " + iter); 93 } 94 95 for (index = 0; index < begin && iter.hasNext(); index++ ) { 97 iter.next(); 98 } 99 100 LoopStatus status = null; 102 if (statusVar != null) 103 { 104 Integer statusBegin = (begin == 0) ? null : new Integer (begin); 106 Integer statusEnd = (end == Integer.MAX_VALUE) ? null : new Integer (end); 107 Integer statusStep = (step == 1) ? null : new Integer (step); 108 status = new LoopStatus(statusBegin, statusEnd, statusStep); 109 context.setVariable(statusVar, status); 110 } 111 112 boolean firstTime = true; 113 int count = 0; 114 while (iter.hasNext() && index <= end) { 115 Object value = iter.next(); 116 if (var != null) { 117 context.setVariable(var, value); 118 } 119 if (indexVar != null) { 120 context.setVariable(indexVar, new Integer (index)); 121 } 122 if (statusVar != null) { 124 count++; 125 status.setCount(count); 126 status.setCurrent(value); 127 status.setFirst(firstTime); 128 status.setIndex(index); 129 if (firstTime) { 131 firstTime = !firstTime; 132 } 133 } 134 boolean finished = false; 137 index++; 138 for ( int i = 1; i < step && !finished; i++, index++ ) { 139 if ( ! iter.hasNext() ) { 140 finished = true; 141 } 142 else { 143 iter.next(); 144 } 145 } 146 147 if (statusVar != null) { 148 status.setLast(finished || !iter.hasNext() || index > end); 149 } 150 invokeBody(output); 151 152 } 153 } 154 else { 155 if ( end == Integer.MAX_VALUE && begin == 0 ) { 156 throw new MissingAttributeException( "items" ); 157 } 158 else { 159 String varName = var; 160 if ( varName == null ) { 161 varName = indexVar; 162 } 163 LoopStatus status = null; 165 if (statusVar != null) 166 { 167 Integer statusBegin = new Integer (begin); 169 Integer statusEnd = new Integer (end); 170 Integer statusStep = new Integer (step); 171 status = new LoopStatus(statusBegin, statusEnd, statusStep); 172 context.setVariable(statusVar, status); 173 } 174 175 int count = 0; 176 for (index = begin; index <= end; index += step ) { 177 178 Object value = new Integer (index); 179 if (varName != null) { 180 context.setVariable(varName, value); 181 } 182 if (status != null) { 184 count++; 185 status.setIndex(index); 186 status.setCount(count); 187 status.setCurrent(value); 188 status.setFirst(index == begin); 189 status.setLast(index > end - step); 190 } 191 invokeBody(output); 192 } 193 } 194 } 195 } 196 catch (BreakException e) { 197 if (log.isDebugEnabled()) { 198 log.debug("loop terminated by break: " + e, e); 199 } 200 } 201 } 202 203 206 211 public void setItems(Expression items) { 212 this.items = items; 213 } 214 215 217 public void setVar(String var) { 218 this.var = var; 219 } 220 221 223 public void setIndexVar(String indexVar) { 224 this.indexVar = indexVar; 225 } 226 227 229 public void setBegin(int begin) { 230 this.begin = begin; 231 } 232 233 235 public void setEnd(int end) { 236 this.end = end; 237 } 238 239 241 public void setStep(int step) { 242 this.step = step; 243 } 244 245 259 public void setVarStatus(String var) { 260 this.statusVar = var; 261 } 262 263 266 public static final class LoopStatus implements LoopTagStatus 267 { 268 private Integer begin; 269 private int count; 270 private Object current; 271 private Integer end; 272 private int index; 273 private Integer step; 274 private boolean first; 275 private boolean last; 276 277 public LoopStatus(Integer begin, Integer end, Integer step) { 278 this.begin = begin; 279 this.end = end; 280 this.step = step; 281 } 282 285 public Integer getBegin() { 286 return begin; 287 } 288 291 public int getCount() { 292 return count; 293 } 294 297 public Object getCurrent() { 298 return current; 299 } 300 303 public Integer getEnd() { 304 return end; 305 } 306 309 public boolean isFirst() { 310 return first; 311 } 312 315 public int getIndex() { 316 return index; 317 } 318 321 public boolean isLast() { 322 return last; 323 } 324 327 public Integer getStep() { 328 return step; 329 } 330 333 public void setCount(int count) { 334 this.count = count; 335 } 336 339 public void setCurrent(Object current) { 340 this.current = current; 341 } 342 345 public void setFirst(boolean first) { 346 this.first = first; 347 } 348 351 public void setLast(boolean last) { 352 this.last = last; 353 } 354 357 public void setIndex(int index) { 358 this.index = index; 359 } 360 } 361 } 362 | Popular Tags |