Implementation of the ViewHandler interface that knows how to use JSP pages
as the view templating mechanism.
This implementation works tightly together with the various JSP TagHandler classes
to implement the behaviour mandated by the ViewHandler specification.
Rendering of a view is done in two parts: first a jsp-generated servlet is invoked
to create or refresh a jsf component tree, then the component tree is walked to generate
the output to send to the user.
The invoked servlet is the one generated from the jsp file which corresponds to the
viewId of the view being rendered. As is normal for jsp, this servlet alternates between
writing literal text to the response output stream and invoking "tag handler" classes
representing the jsp tags that were present in the page. This servlet is not aware of
JSF at all.
On the first visit to a view, when each JSF taghandler is invoked, the corresponding
JSF component will not yet exist so it is created and added to the current view tree.
Each JSF taghandler also marks itself as having "buffered body content", which means that
after the start-tag is executed a temporary output stream is installed for the response.
Any output generated by the jsp-servlet therefore gets written into a memory buffer
rather than sent via the network socket to the sender of the request. When the end
of the JSF tag is encountered, the JSF tag checks whether any such body text did exist,
and if so it creates a transient f:verbatim component and inserts it into the component
tree. The final result is that after this "first pass" a component tree exists which has
all the JSF components in it, plus a bunch of auto-generated f:verbatim components that
hold all plain text, or output generated by non-jsf jsp tags. Absolutely NO output has
yet been sent to the real response stream.
On later visits to the same view, the component tree already exists (has been restored).
However the "verbatim" components holding static text are not present as they were
marked "transient" (not keeping them reduces the amount of memory required to "save state").
Note that these components are not needed for any phase prior to RENDER because they
are not "input" components. When the jsp-generated servlet is executed, JSF taghandlers
that are invoked will simply verify that a corresponding component already exists in the
view-tree rather than creating a new one. However the "body buffering" occurs again, so
that the appropriate transient verbatim components are once again created and inserted into
the tree.
Regardless of whether the view is new or restored, the rendered output can now be generated
simply by walking the component tree and invoking the encodeBegin/encodeChildren/encodeEnd
methods on each component. The static components simply output their contained text.
Notes for JSF1.1 users: the new two-phase approach that uses "output buffering" to capture
non-JSF output is rather like wrapping all non-jsf components in an invisible f:verbatim tag.
Although that doesn't sound like a big change, it allows processing to occur in two passes
rather than one. And that means that before any component is rendered the entire component
tree already exists. This solves a number of JSF1.1 problems, including output-ordering
problems between text and jsf components, and errors when using the "for" attribute of a
label to reference a component later in the page. It does introduce a performance penalty;
non-JSF-generated output now gets buffered rather than being streamed directly to the
user.