Hi Ken,
Thanks for explaining the implementation details, and then fixing the
issues. I guess most user will expect his 'revised' behavior. Besides,
when coding the page, one will not know if this page will be visited
through the navigate or redirect handler. Coding to make it works for
both case was really hard if not impossible.
I was aware that i cannot access pageSession attribute during
"initPage", this is acceptable and reasonable behavior, as this is the
case no matter how the page is accessed.
thanks
Anissa.
Ken Paulsen wrote:
>
> 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.
>>>