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);
}
}