dev@jsftemplating.java.net

Re: JSFTemplating: Re: possible bug ?

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Sat, 21 Oct 2006 10:04:29 -0700

Hi Anissa,

I take back the setViewRoot(null) idea... the RI throws a NPE if you
attempt to do this. I changed the code to always set the new UIViewRoot
and to restore the "current" UIViewRoot if it was set. This should fix
your problem. I also noticed that you cannot access "pageSession"
attributes from the "initPage" event b/c the viewRoot is not yet set
(this isn't new). Anyway, let me know if this fixes your problem.

Thanks for reporting this!

Ken

Ken Paulsen wrote:
>
> 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}
>>