protected void renderComponent()

in tapestry-framework/src/org/apache/tapestry/form/Form.java [334:429]


    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
    {
        String actionId = cycle.getNextActionId();
        _name = getDisplayName() + actionId;

        boolean renderForm = !cycle.isRewinding();
        boolean rewound = cycle.isRewound(this);

        _rewinding = rewound;

        _allocatedIdIndex = 0;

        _rendering = true;

        if (rewound)
        {
            String storedIdList = cycle.getRequestContext().getParameter(_name);

            reconstructAllocatedIds(storedIdList);
        }

        ILink link = getLink(cycle, actionId);

        // When rendering, use a nested writer so that an embedded Upload
        // component can force the encoding type.

        IMarkupWriter nested = writer.getNestedWriter();

        renderBody(nested, cycle);

        if (renderForm)
        {
            writeAttributes(writer, link);

            renderInformalParameters(writer, cycle);
            writer.println();
        }

        // Write the hidden's, or at least, reserve the query parameters
        // required by the Gesture.

        writeLinkParameters(writer, link, !renderForm);

        if (renderForm)
        {
            // What's this for?  It's part of checking for stale links.  
            // We record the list of allocated ids.
            // On rewind, we check that the stored list against which
            // ids were allocated.  If the persistent state of the page or
            // application changed between render (previous request cycle)
            // and rewind (current request cycle), then the list
            // of ids will change as well.

            writeHiddenField(writer, _name, buildAllocatedIdList());
            writeHiddenValues(writer);

            nested.close();

            writer.end(getTag());

            // Write out event handlers collected during the rendering.

            emitEventHandlers(writer, cycle);
        }

        if (rewound)
        {
            int expected = _allocatedIds.size();

            // The other case, _allocatedIdIndex > expected, is
            // checked for inside getElementId().  Remember that
            // _allocatedIdIndex is incremented after allocating.

            if (_allocatedIdIndex < expected)
            {
                String nextExpectedId = (String) _allocatedIds.get(_allocatedIdIndex);

                throw new StaleLinkException(
                    Tapestry.format(
                        "Form.too-few-ids",
                        getExtendedId(),
                        Integer.toString(expected - _allocatedIdIndex),
                        nextExpectedId),
                    this);
            }

            IActionListener listener = getListener();

            if (listener != null)
                listener.actionTriggered(this, cycle);

            // Abort the rewind render.

            throw new RenderRewoundException(this);
        }
    }