dev@jsftemplating.java.net

Re: possible bug ?

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Sat, 21 Oct 2006 09:48:07 -0700

Hi Anissa,

Feel free to send in bugs or other questions to the
"dev_at_jsftemplating.dev.java.net" alias. I've included this alias as well.

A "page session" attribute is stored on the "ViewRoot" of the page you
are on. If you get a new "ViewRoot" then you won't have any page
session attributes anymore.

So... in your case if you navigate (use the "navigate" handler), it
should create a new ViewRoot (and call the beforeCreate events) and
return it to you. However, there *is* an issue here... the following
code in the ViewHandler *sets* the UIViewRoot which is needed for the
"page handlers" to access the UIViewRoot during a "beforeCreate" event:

        // FIXME: I should not set the view root here! But some components
        // may require this during creation of the UIComponent tree.
        // NOTE: This must happen after return
_oldViewHandler.createView(...)
        if (context.getViewRoot() == null) {
            context.setViewRoot(viewRoot);
        }

FYI, I originally did this b/c some components (lh table component)
accessed the UIViewRoot in its constructor. This has since been
fixed... but now I rely on this for the "page session" feature...

Anyway, the reason for the "!= null" check is b/c this code can be
called w/o *changing* the UIViewRoot that is set in the FacesContext.
This is important b/c I want to be able to support accessing a different
page ahead of time (i.e. getUIViewRoot handler).

In your case, you are "navigating" to another page, which comes through
this code with the current page already set in the FacesContext. So the
current page -- not the page you are navigating to -- will get the
pageSession attribute set. When you are calling "redirect" a new
request is sent, therefor the current ViewRoot will be null and the
expected viewRoot will be passed into the beforeCreate.

There are 2 approaches that can be taken to fix this issue (that I can
think of):

1) You can "null out" the current ViewRoot before calling navigate:
facesContext.setViewRoot(null);

2) I can always set the viewRoot, and restore it to its previous value
after createView is done.

I think we should try #2... this will change the value of the ViewRoot
passed into the beforeCreate()/afterCreate()/initPage() methods. I
think this will be inline w/ people's expectations, though. What do you
think? I'll change it now... if we change our mind later I'll change it
again.

Ken


Anissa Lam wrote:
>
> Hi Ken,
>
> I see that if i navigate to a page, the page attribute i set in
> beforeCreate will disappear when it gets to beforeEncode. This only
> happens if you navigate to this page. If you come to this page using
> redirect, then everything is fine. I really think this is a bug.
> Can you take a look ?
>
> I have attached page1.jsf and page2.jsf
>
> thanks
> Anissa.
>
>
> ------------------------------------------------------------------------
>
>
> <sun:page id="page1">
> <sun:html>
> <sun:form>
> <sun:button text="Press to navigate to page 2" >
> <!command
> println("========= about to navigate to page2 ==========");
> navigate("page2.jsf");
> />
> </sun:button>
> </sun:form>
> </sun:html>
>
> </sun:page>
>
>
>
> ------------------------------------------------------------------------
>
> "value of foo = #{foo}
>