It is, but I am not on the same view, I am on a new view. The new view
is getting a component from the old view. So:
1) view #1 is restored,
2) the navigation handler is fired from an action result
3) a new view is created
4) *somehow* a tomahawk outputText component is getting added to the
new component tree from the old component tree from inside of a
decorated template.
I am still trying to find where *exactly* the old component is getting
added to the new view. I'll let you know when and if I find it.
-Andrew
On 4/14/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> Look at the UIViewRoot source for MyFaces and see if the
> saveState/restoreState methods actually save the unique id counter.
>
> >Jacob, the view root is not handing out the same ID. I have verified
> >this by stepping through the MyFaces SVN code. UI view root is only
> >handing out ID 81 once.
> >
> >The "DefaultFacelet.java" is rehydrating my decorated page and
> >re-using components from the previous view. One of these is an output
> >text component that got ID of 81 from the *LAST* view. When the new
> >view includes the same facelet (a ui:decorate tag), that same
> >outputText component is getting included into the new view.
> >
> >Evidence:
> >During
> >org.apache.myfaces.application.TreeStructureManager.internalRestoreTreeStructur
> >e(TreeStructureManager.java:112)
> >
> >Output text component with ID _id81 and memory location @1965de4 gets
> >restored.
> >
> >Navigation handler creates a new view root as it should (I navigated
> >to a new page). As shown here:
> >13:34:32,877 DEBUG [NavigationHandlerImpl] handleNavigation
> >fromAction=#{dimHandler.goView} outcome=goview toViewId
> >=/pages/Admin/Appsets/Dimension/dim_view.xhtml redirect=false
> >
> >The new view generates a new component tree:
> >13:34:33,346 INFO [STDOUT] --------------- NEW UNIQUE ID: 81 (this:
> >[EMAIL PROTECTED])
> >13:34:33,347 INFO [STDOUT] ---------- OutputText. this:
> >[EMAIL PROTECTED] Setting
> >Id to = _id81. View ID: [EMAIL PROTECTED]
> >
> >However, facelets is reusing the component from the old View in the new tree:
> >13:35:09,793 INFO [STDOUT] ---------- OutputText. this:
> >[EMAIL PROTECTED] Id =
> >_id81
> >13:35:09,794 INFO [STDOUT] ---------- OutputText. this:
> >[EMAIL PROTECTED] Client
> >Id = zfpForm:_id79:_id81
> >
> >As you can see, this is the exact same component (1965de4) from the
> >previous view. This component was not created by the new view.
> >
> >The stack trace points the finger at default facelet:
> >...
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.impl.DefaultFaceletContext$1.apply(DefaultFaceletContext.java:
> >253)
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletCon
> >text.java:263)
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:63)
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java
> >:47)
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:164)
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java
> >:47)
> >13:34:33,350 INFO [STDOUT] at
> >com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:119)
> >13:34:33,351 INFO [STDOUT] at
> >com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
> >...
> >
> >I'm trying to get more specific than this (trying to get the debug
> >working in my IDE), but this is what I have found so far. Sorry if I
> >am wrong on this, but it sure looks this way after looking at MyFaces
> >and Facelets code for a few hours.
> >
> >-Andrew
> >
> >
> >
> >On 4/14/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> >> The problem is that the UIViewRoot in older versions of MyFaces doesn't
> >guarantee that the Id is unique across calls-- which breaks the contract of
> >the method. Facelets doesn't need to change anything.
> >>
> >> Facelets doesn't 'cache' anything. It creates the tree and the state
> >> saving
> >method of the JSF implementation saves the component tree for processing on
> >succeeding requests (less the unique id counter on the viewroot).
> >>
> >> If the UIViewRoot is fixed, then it should NEVER hand out the same ids-- so
> >in a sense, the problem you are seeing is created by MyFaces itself.
> >>
> >> >Okay, I've been digging deep into MyFaces SVN and facelets 1.0.14
> >> >source code to try to find the issue of duplicate IDs. It looks like
> >> >it is a facelets bug after all.
> >> >
> >> >What I've been able to find out so far:
> >> >
> >> >MyFaces creates a view with a bunch of facelets tags (defines,
> >> >includes, compositions, etc.). This creates several facelets objects
> >> >that represent cached "views" for defines and etc.
> >> >
> >> >The particular problem seems to be happening with DecorateHandler.java
> >> >and the classes it is using. (I haven't pinpointed the exact problem
> >> >as I am having stability issues debugging JBoss in eclipse, so am
> >> >hunting and pecking through source in VIM).
> >> >
> >> >Facelets is caching the decorated view. So, when I hit the first page
> >> >it is fine. At that point, facelets is caching the components that
> >> >made up the view for my decorated page.
> >> >
> >> >Then, after navigation, and a new view is created, facelets seems to
> >> >be re-hydrating this cached copy of the decorated view for the new
> >> >view. This cache copy of components contains components with
> >> >auto-generated IDs.
> >> >
> >> >The MyFaces UIViewRoot knows nothing about these cached components and
> >> >therefore does not check any components in the view for existence of
> >> >auto-generated IDs. Therefore when facelets adds the cached version of
> >> >the component to the tree, it is not reserving unique IDs.
> >> >
> >> >As a result, the first component that was cached in the decorated file
> >> >with an auto-generated ID will clash with any components in the new
> >> >view given that very same auto -generated ID.
> >> >
> >> >The fix? Well this is up to you Jacob I guess, unless MyFaces wants to
> >> >help with this.
> >> >
> >> >1) In facelets, (during the mark & sweep?), when a cached component
> >> >hierarchy is being used, check all IDs in the component tree with
> >> >naming matching the regular expression "^_id\d+" and assign a new ID.
> >> >
> >> >Example:
> >> >if (regex.matcher(component.getId()).matches()))
> >> > component.setId( /* get a new ID from the view */);
> >> >
> >> >2) In UIViewRoot of MyFaces, when components are added to the tree, or
> >> >when assigning a new ID, check the existing components in the tree to
> >> >make sure the auto generated ID has not already been assigned to a
> >> >component (don't assume UIViewRoot is the only source of "_id#" style
> >> >IDs)
> >> >
> >> >3) Something else.
> >> >
> >> >What do you think?
> >> >-Andrew
> >> >
> >> >---------------------------------------------------------------------
> >> >To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> >For additional commands, e-mail: [EMAIL PROTECTED]
> >> >
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: [EMAIL PROTECTED]
> >For additional commands, e-mail: [EMAIL PROTECTED]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>