Based on feedback from Imre and Ken, I've modified the proposal, below.
Please read through this, as silence == consent. If there are no
further comments, I'll enter this into the spec issue database, and the
changes will probably be high on my queue for implementation in January.
This change is intended to go into the MR.
-----------------------------
Problem Description:
PartialResponseWriter has very little JavaDoc or spec associated with
it. Users are finding it difficult to use as a result. Additionally,
the implicit call to startUpdate means that writing out other XML
directives from a custom component is quite difficult.
The JavaDoc preamble says:
PartialResponseWriter decorates an existing ResponseWriter to support
the generation of a partial response suitable for Ajax operations. In
addition to the markup generation methods inherited from
javax.faces.context.ResponseWriter, this class provides methods for
constructing the standard partial response elements.
The individual method summaries say such things as:
void startUpdate(String targetId)
Write the start of an update operation.
And
void startEval()
Write the start of an eval operation.
And
void startDocument()
Write the start of a partial response.
Currently, what to do if you were to call a startXXX method while
already in a startXXX function is unspecified.
The spec (section 13.4.4.1) simply says:
Writing The Partial Response
JavaServer Faces provides javax.faces.context.PartialResponseWriter to
ensure the Ajax response that is written follows the standard format as
specified in Section 1.3 “XML Schema Definition for Partial Responses”
Implementations must take care to properly handle nested CDATA sections
when writing the response. PartialResponseWriter decorates an existing
ResponseWriter implementation by extending
javax.faces.context.ResponseWriterWrapper. Refer to the
javax.faces.context.PartialResponseWriter JavaDocs, and the JavaScript
documentation for the jsf.ajax.response function for more specifics.
Proposal:
We need to tighten up the spec in several ways:
1) Add comments to the JavaDoc that PartialResponseWriter will typically
have startDocument and startUpdate called before the component can get
hold of it. Note that this is to allow interoperability with components
that are not instrumented for Ajax.
2) Expand description in 13.4.4.1 to describe that an error will be
thrown if:
startDocument is called more than once on a response.
any method is called after endDocument.
any method is called before startDocument
3) Add a description to the spec of what methods will typically be
called before the client receives the PartialResponseWriter in
RenderResponse. Describe when this is not so (render = @none).
4) Allow for the calling of other methods besides startUpdate within a
normal component’s Render Response.
a) I propose that we treat all calls to the following methods when
within a startUpdate block as having their content placed on a queue, to
be written out after the endUpdate is called:
delete
redirect
startEval/endEval
startUpdate/endUpdate
startExtension/endExtension
startInsertBefore/endInsert
startInsertAfter/endInsert
startError/endError
updateAttributes
b) for other (non-startUpdate) paired methods, calling any other method
than the ending method is an error, and will raise an exception.
c) unlimited nesting of startUpdates is allowed (though care should be
taken, since significant memory can be consumed) - all queued writes
that are made within that update block will be written out after the
endUpdate is called, essentially writing things out depth first.
5) Update JavaDoc to indicated paired methods -
startEval/endEval
startUpdate/endUpdate
startExtension/endExtension
startInsertBefore/endInsert
startInsertAfter/endInsert
startError/endError
It will be an error, and an exception will be thrown, to call one
method without the other.
Concluding statement:
While the description of this behavior (in particular the queuing) may
be a little difficult, I believe that this behavior most closely matches
what users are expecting when they currently use the API. If this
approach is accepted by the EG, I’ll write up the formal changes.