in core/src/main/java/org/apache/commons/jelly/tags/core/ForEachTag.java [190:310]
public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException {
if (log.isDebugEnabled()) {
log.debug("running with items: " + items);
}
try {
if (items != null) {
Iterator iter = items.evaluateAsIterator(context);
if (log.isDebugEnabled()) {
log.debug("Iterating through: " + iter);
}
// ignore the first items of the iterator
for (index = 0; index < begin && iter.hasNext(); index++ ) {
iter.next();
}
// set up the status
LoopStatus status = null;
if (statusVar != null)
{
// set up statii as required by JSTL
Integer statusBegin = (begin == 0) ? null : Integer.valueOf(begin);
Integer statusEnd = (end == Integer.MAX_VALUE) ? null : Integer.valueOf(end);
Integer statusStep = (step == 1) ? null : Integer.valueOf(step);
status = new LoopStatus(statusBegin, statusEnd, statusStep);
context.setVariable(statusVar, status);
}
boolean firstTime = true;
int count = 0;
while (iter.hasNext() && index <= end) {
Object value = iter.next();
if (var != null) {
context.setVariable(var, value);
}
if (indexVar != null) {
context.setVariable(indexVar, Integer.valueOf(index));
}
// set the status var up
if (statusVar != null) {
count++;
status.setCount(count);
status.setCurrent(value);
status.setFirst(firstTime);
status.setIndex(index);
// set first time up for the next iteration.
if (firstTime) {
firstTime = !firstTime;
}
}
// now we need to work out the next index for status isLast
// and also advance the iterator and index for the loop.
boolean finished = false;
index++;
for ( int i = 1; i < step && !finished; i++, index++ ) {
if ( ! iter.hasNext() ) {
finished = true;
}
else {
iter.next();
}
}
if (statusVar != null) {
status.setLast(finished || !iter.hasNext() || index > end);
}
invokeBody(output);
}
}
else {
if ( end == Integer.MAX_VALUE && begin == 0 ) {
throw new MissingAttributeException( "items" );
}
else {
String varName = var;
if ( varName == null ) {
varName = indexVar;
}
// set up the status
LoopStatus status = null;
if (statusVar != null)
{
// set up statii as required by JSTL
Integer statusBegin = Integer.valueOf(begin);
Integer statusEnd = Integer.valueOf(end);
Integer statusStep = Integer.valueOf(step);
status = new LoopStatus(statusBegin, statusEnd, statusStep);
context.setVariable(statusVar, status);
}
int count = 0;
for (index = begin; index <= end; index += step ) {
Object value = Integer.valueOf(index);
if (varName != null) {
context.setVariable(varName, value);
}
// set the status var up
if (status != null) {
count++;
status.setIndex(index);
status.setCount(count);
status.setCurrent(value);
status.setFirst(index == begin);
status.setLast(index > end - step);
}
invokeBody(output);
}
}
}
}
catch (BreakException e) {
if (log.isDebugEnabled()) {
log.debug("loop terminated by break: " + e, e);
}
}
}