Hi,

it can be the case, that this mail may be a bit long..., but the main
question I think is:
Is there a public getPhaseListeners() method missing on UIVIewRoot ?

Some general information since JSF 1.2... there is a public
addPhaseListener() on UIViewRoot.
So you can register a PhaseListener with the current view root (per
view) to have beforePhase and afterPhase called
on these lifecycle phases:
-ApplyReqValue
-processValidation
-UpdateModel
-Invoke App
-RenderResponse

You can add such a PL (PhaseListener) via the mentioned Java API or:
<f:phaseListener type="blah.MyPL" />
(this internally uses the Java API ....)

Fine.

now when you render a page and do a (regular) postback the
phaselistener (its methods...) is executed.
Fine.

Now the "ajax" scenario.

Some libraries (like ADF Faces Rich Client or Apache MyFaces
Tobago(not Trinidad ;-) )) offer a custom lifecycle to call the
lifecycle methods (such as processXyz()) only
on the components, that are part of the ajax postback (why doing a
decode on not effected components?).

we do it like:
uiViewRoot.invokeOnComponent(context, clientId, callback);

where the *callback* is something like:
static private class UpdateModelValuesCallback implements ContextCallback
{
  public void invokeContextCallback(FacesContext context,
                                    UIComponent target)
  {
    target.processUpdates(context);
  }
}

usually these *optimized* lifecycles offer optimization for these phases:
-ApplyReqValue
-processValidation
-UpdateModel

not on:
-Invoke App
-RenderResponse

For these, we just do a delegate back to the standard (default) behavior, like:
viewRoot.processApplication(context);

So now.... the processXyz (like processUpdates()) is only! called on
the "ajax components"!
(Tobago does that in a similar way. They *fake* invokeOnComponent,
since that lib is JSF 1.1 based)

What does that mean, when submitting an ajax postback (maybe triggered
by <inputText autoSubmit="true" />) ?
The (to uiviewRoot) attached PL is only invoked for these phases:
-Invoke App
-RenderResponse

Why?
The big problem (IMO) is, that the "PhaseListener(s) attached to the
current (per view) UIViewRoot" are *triggered* by the processXyz() of
UIViewRoot itself (and encodeEnd and encodeBegin for RenderResponse phase).
So... when only invoking them on the effected "ajax components" the
before/afterPhase is never triggered (for the optimized phase).

The optimized lifecycle could get the attached PhaseListeners, in case
there where a public getPhaseListeners() method on UIViewRoot.
I am wondering why there is none ? Simply forgotten?

Please note, that (also since JSF 1.2) you can register methodExpression like:
<f:view beforePhase="#{methodExpression}" afterPhase="#{otherMethodExpression}">

but... there is acutally a public getBeforePhaseListener() and a
getAfterPhaseListener() as well.
So a optimized lifecycle could get these MethodExpressions.

What is your take on that?

Thanks for reading,
Matthias

-- 
Matthias Wessendorf

further stuff:
blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
mail: matzew-at-apache-dot-org

Reply via email to