in freemarker-core/src/main/java/freemarker/core/IteratorBlock.java [364:445]
private boolean executedNestedContentForHashListing(Environment env, TemplateElement[] childBuffer)
throws IOException, TemplateException {
final boolean hashNotEmpty;
if (listedValue instanceof TemplateHashModelEx) {
TemplateHashModelEx listedHash = (TemplateHashModelEx) listedValue;
if (listedHash instanceof TemplateHashModelEx2) {
KeyValuePairIterator kvpIter
= openedIterator == null ? ((TemplateHashModelEx2) listedHash).keyValuePairIterator()
: (KeyValuePairIterator) openedIterator;
hashNotEmpty = kvpIter.hasNext();
if (hashNotEmpty) {
if (loopVar1Name != null) {
listLoop: do {
KeyValuePair kvp = kvpIter.next();
loopVar1Value = kvp.getKey();
loopVar2Value = kvp.getValue();
hasNext = kvpIter.hasNext();
try {
visibleLoopVar1Name = loopVar1Name; // Makes all loop variables visible in FTL
env.visit(childBuffer);
} catch (BreakOrContinueException br) {
if (br == BreakOrContinueException.BREAK_INSTANCE) {
break listLoop;
}
} finally {
visibleLoopVar1Name = null; // Hides all loop variables in FTL
}
index++;
} while (hasNext);
openedIterator = null;
} else {
// We will reuse this at #items
openedIterator = kvpIter;
// Note: Loop variables will only become visible inside #items
env.visit(childBuffer);
}
}
} else { // not a TemplateHashModelEx2, but still a TemplateHashModelEx
TemplateModelIterator keysIter = listedHash.keys().iterator();
hashNotEmpty = keysIter.hasNext();
if (hashNotEmpty) {
if (loopVar1Name != null) {
listLoop: do {
loopVar1Value = keysIter.next();
if (!(loopVar1Value instanceof TemplateScalarModel)) {
throw _MessageUtil.newKeyValuePairListingNonStringKeyExceptionMessage(
loopVar1Value, (TemplateHashModelEx) listedValue);
}
loopVar2Value = listedHash.get(((TemplateScalarModel) loopVar1Value).getAsString());
hasNext = keysIter.hasNext();
try {
visibleLoopVar1Name = loopVar1Name; // Makes all loop variables visible in FTL
env.visit(childBuffer);
} catch (BreakOrContinueException br) {
if (br == BreakOrContinueException.BREAK_INSTANCE) {
break listLoop;
}
} finally {
visibleLoopVar1Name = null; // Hides all loop variables in FTL
}
index++;
} while (hasNext);
} else {
// Note: Loop variables will only become visible inside #items
env.visit(childBuffer);
}
}
}
} else if (listedValue instanceof TemplateCollectionModel
|| listedValue instanceof TemplateSequenceModel) {
throw new NonSequenceOrCollectionException(env,
new _ErrorDescriptionBuilder("The value you try to list is ",
new _DelayedAOrAn(new _DelayedFTLTypeDescription(listedValue)),
", thus you must specify only one loop variable after the \"as\" (there's no separate "
+ "key and value)."
));
} else {
throw new NonExtendedHashException(
listedExp, listedValue, env);
}
return hashNotEmpty;
}