public boolean render()

in velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Foreach.java [221:304]


    public boolean render(InternalContextAdapter context, Writer writer, Node node)
        throws IOException
    {
        // Get the block ast tree which is always the last child ...
        Node block = node.jjtGetChild(node.jjtGetNumChildren()-1);

        // ... except if there is an #else clause
        Node elseBlock = null;
        Node previous = node.jjtGetChild(node.jjtGetNumChildren()-2);
        if (previous instanceof ASTBlock)
        {
            elseBlock = block;
            block = previous;
        }

        Node iterableNode = node.jjtGetChild(2);
        Object iterable = iterableNode.value(context);
        Iterator i = getIterator(iterable, iterableNode);
        if (i == null || !i.hasNext())
        {
            if (elseBlock != null)
            {
                renderBlock(context, writer, elseBlock);
            }
            return false;
        }

        /*
         * save the element key if there is one
         */
        Object o = context.get(elementKey);

        /*
         * roll our own scope class instead of using preRender(ctx)'s
         */
        ForeachScope foreach = null;
        if (isScopeProvided())
        {
            String name = getScopeName();
            foreach = new ForeachScope(this, context.get(name));
            context.put(name, foreach);
        }

        int count = 1;
        while (count <= maxNbrLoops && i.hasNext())
        {
            count++;

            put(context, elementKey, i.next());
            if (isScopeProvided())
            {
                // update the scope control
                foreach.index++;
                foreach.hasNext = i.hasNext();
            }

            try
            {
                renderBlock(context, writer, block);
            }
            catch (StopCommand stop)
            {
                if (stop.isFor(this))
                {
                    break;
                }
                else
                {
                    // clean up first
                    clean(context, o);
                    throw stop;
                }
            }
        }
        clean(context, o);
        /*
         * closes the iterator if it implements the Closeable interface
         */
        if (i instanceof Closeable && i != iterable) /* except if the iterable is the iterator itself */
        {
            ((Closeable)i).close();
        }
        return true;
    }