On 5/5/06, Don Brown <[EMAIL PROTECTED]> wrote:

These are very good points.  How does JSF handle the multiple renders?


For the implementation questions below, my answers are based on the
jsf-portlet bridge code in the RI's java.net project.  AFAICT, the
implementations inside MyFaces and the portals.apache.org bridges project
are pretty similar, but might not be identical.

The JSF lifecycle is implemented by a single portlet with the two standard
lifecycle methods.  The portlet container calls processAction() for the
portlet that processes the form post, which is mapped to a call to JSF's
Lifecycle.process() method.  This in turn triggers the Restore View through
Invoke Application phases of the standard JSF lifecycle (in "action
framework" terms, that is everything up to and including calling the action
method).  Then, the portlet container will call render() on the JSF portlet
for *every* portlet on the page, which gets mapped to a call to JSF's
Lifecycle.render() method, which does the Render Response phase of the
lifecycle (i.e. the moral equivalent of forwarding to the JSP page that you
navigated to).

The net effect is that one portlet runs through both phases of the portlet
lifecycle, while all the other portlets only run through the rendering
phase.

 Do you
have to ensure your backing bean is session scoped?  Wouldn't a request
scope
mean the data would be lost at the end of the processAction()?


Yes, you would lose request attribute data at the end of processAction() --
the container is explicitly prohibited from carrying them forward.

But, when you think about it, this actually makes sense.  A portlet *always*
needs to be prepared to rerender its current state, because it might not be
the one that receives the next GET or POST request, so it needs to save
enough state information (in session scope or cookies or ...) to make that
possible.

There's one other subtlety to sessions in portlets -- it turns out there are
two kinds.  You can have session attributes in "portlet scope" (specific to
a particular instance of a particular portlet) or in "applicaton scope" (per
user, like a servlet session).  The former is useful for the kind of state
saving referenced above, while the latter is used the same way we use
session scope in webapps.  The point here, though, is we'd need to decide
whether or not to expose both concepts in an abstraction API (JSF did not,
and I'm not sure this was the right long term choice.)

 How would you
expect a portlet lifecycle to be supported with a stateless Action-based
framework?


I would think we'd want to support some explicit notion of a "setup" phase
right before rendering, and a "cleanup" phase afterwards.  That way, you can
do things like open a Hibernate session and do a query that's needed to
populate a table, then clean up the session afterwards.  (JSF makes this
possible with "before phase" and "after phase' event listeners, while Shale
exposes these concepts directly as callbacks to the prerender() and
destroy() methods on your backing bean if it implements ViewController.)

With this structure, the Action framework would actually have two
controllers in a portlet environment ... one for the processAction() part
and one for the render() part.  In a webapp, it would all be just one,
essentially concatenating the processing steps.  We would also want some
sort of environment-independent "action context" object that was implemented
differently for the two environments, but that seems likely to be desireable
anyway.

Don


Craig

Reply via email to