/**
* {@inheritDoc}
*/
@Override
public void execute(ActionExecutionContext exctx) throws ModelException, SCXMLExpressionException {
Context ctx = exctx.getContext(getParentEnterableState());
Evaluator eval = exctx.getEvaluator();
ctx.setLocal(getNamespacesKey(), getNamespaces());
try {
Object arrayObject = eval.eval(ctx,array);
if (arrayObject != null && (arrayObject instanceof Iterable || arrayObject.getClass().isArray())) {
if (arrayObject.getClass().isArray()) {
for (int currentIndex = 0, size = Array.getLength(arrayObject); currentIndex < size; currentIndex++) {
ctx.setLocal(item, Array.get(arrayObject, currentIndex));
ctx.setLocal(index, currentIndex);
// The "foreach" statement is a "container"
for (Action aa : actions) {
aa.execute(exctx);
}
}
}
else {
// Spec requires to iterate over a shallow copy of underlying array in a way that modifications to
// the collection during the execution of <foreach> must not affect the iteration behavior.
// For array objects (see above) this isn't needed, but for Iterables we don't have that guarantee
// so we make a copy first
ArrayList<Object> arrayList = new ArrayList<Object>();
for (Object value: (Iterable)arrayObject) {
arrayList.add(value);
}
int currentIndex = 0;
for (Object value : arrayList) {
ctx.setLocal(item, value);
if (index != null) {
ctx.setLocal(index, currentIndex);
}
// The "foreach" statement is a "container"
for (Action aa : actions) {
aa.execute(exctx);
}
currentIndex++;
}
}
}
// else {} TODO: place the error 'error.execution' in the internal event queue. (section "3.12.2 Errors")
}
finally {
ctx.setLocal(getNamespacesKey(), null);
}
}