[
https://issues.apache.org/jira/browse/MYFACES-2638?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12874404#action_12874404
]
Leonardo Uribe commented on MYFACES-2638:
-----------------------------------------
I committed a solution for this one. The idea is use a different SAX handler to
compile composite component metadata. This solution also includes a new
FaceletHandler that include cc:interface and cc:implementation tags for cache
BeanInfo generated instance in a better way.
In the next days I'll continue checking and enhancing the new algorithm for
composite components.
> Fix PostAddToViewEvent and PreRemoveFromViewEvent publishing conditions
> -----------------------------------------------------------------------
>
> Key: MYFACES-2638
> URL: https://issues.apache.org/jira/browse/MYFACES-2638
> Project: MyFaces Core
> Issue Type: Bug
> Components: JSR-314
> Affects Versions: 2.0.0-beta-3
> Reporter: Leonardo Uribe
> Assignee: Leonardo Uribe
> Attachments: MYFACES-2638-3.patch, MYFACES-2638-4.patch,
> MYFACES-2638-6.patch, MYFACES-2638-6_1.patch, MYFACES-2638-6_5.patch,
> MYFACES-2638-6_8.patch, MYFACES-2638-6_9_fix_facets.patch,
> MYFACES-2638-test-webapp.zip
>
>
> From a discussion of jsr-314-open mailing list:
> Actually the event publishing conditions of
> PostAddToViewEvent/PreRemoveFromViewEvent are not very clear. These
> conditions depends if partial state saving is used or not and if facelets
> updates the view or not. The problem is this fact is not very intuitive, so
> for write code correctly the user needs to be aware of that, in other words
> this should be documented somewhere. Also, there are some technical questions
> that could be of interest on this mailing list and myfaces dev list too.
> In theory, PostAddToViewEvent is used in this cases:
> - h:outputScript and h:outputStylesheet renderers uses it to relocate
> component resources to UIViewRoot facet "head" or "body" target
> (h:outputStylesheet by default to "head"). Note "head" and "body" facets are
> transient.
> - cc:insertChildren and cc:insertFacet, to relocate components to some place
> inside cc:implementation. The reason why we do that through a listener
> attached to PostAddToViewEvent is we need to take into account the case of
> nested composite components using cc:insertFacet/cc:insertChildren. Note when
> the component tree is built the first time, PostAddToViewEvent is propagated
> from root to nodes.
> - When Partial State Saving is enabled, it is necessary to attach a listener
> to PostAddToViewEvent/PreRemoveFromViewEvent, so if some user add/remove a
> component, we can keep track of those changes and save/restore the component
> tree properly, in other words, support component addition or removal
> programatically.
> Now, the instants of time where PostAddToViewEvent is published are:
> - With Partial State Saving enabled
> * When the view is build at first time.
> * In a postback when the view is build but before the state of the
> component is restored.
> - With Partial State Saving disabled
> * When the view is build at first time.
> * In a postback when the view is "refreshed", because all component nodes
> are detached and attached to the tree. In other words, on render response
> phase, vdl.buildView is called and in this case facelets algorithm add all
> transient components (usually all html markup not saved), and to do that, it
> detach and attach all components to be in right order. This also has some
> other implications, like c:if tag depends on this to work correctly.
> A developer that is not aware of this fact could think that
> PostAddToViewEvent is called when the view is build.
> This is true with PSS is enabled, but is not true when PSS is disabled. On
> this topic:
> [jsr-314-open] add component resources depending on the owner component state
> It was described why PostAddToViewEvent cannot be used in that case. But
> let's change a litte bit the problem. We have a custom component that creates
> some other on PostAddToViewEvent and add it as a children. It should work but
> in fact it only works when PSS is enabled, with PSS disabled that code will
> cause a duplicate id exception. Of course, the developer can solve it with
> some effort but the point is we are not consider the element of least
> surprise.
> But this fact this is only the tip of the iceberg. In mojarra (this was
> already fixed on myfaces), components relocated by cc:insertChildren or
> cc:insertFacet does not have state when PSS is disabled, because when the
> view is "refreshed" the components are created again, but facelets algorithm
> remove all components with no bound to a facelet tag handler, and then the
> listeners attached to PostAddToViewEvent relocates the new ones, so this
> effect is not notice at first view.
> Do you remember PostAddToViewEvent propagation ordering is important by
> cc:insertChildren/cc:insertFacet? well, with PSS disabled, the ordering now
> is from nodes to root, because all nodes are detached and attached from nodes
> to root, so in myfaces we did something like this (I removed some non
> relevant code to be more clear):
> try
> {
> if (refreshTransientBuild)
> {
> context.setProcessingEvents(false);
> }
> // populate UIViewRoot
> _getFacelet(renderedViewId).apply(context, view);
> }
> finally
> {
> if (refreshTransientBuild)
> {
> context.setProcessingEvents(true);
>
> // When the facelet is applied, all components are
> removed and added from view,
> // but the difference resides in the ordering. Since the
> view is
> // being refreshed, if we don't do this manually, some
> tags like
> // cc:insertChildren or cc:insertFacet will not work
> correctly, because
> // we expect PostAddToViewEvent will be propagated from
> parent to child, and
> // facelets refreshing algorithm do the opposite.
>
> FaceletViewDeclarationLanguage._publishPreRemoveFromViewEvent(context, view);
>
> FaceletViewDeclarationLanguage._publishPostAddToViewEvent(context, view);
> }
> }
> In few words, disable event processing, and fire PostAddToViewEvent and
> PreRemoveFromViewEvent in the expected order to build the tree correctly. If
> we don't do this, h:outputScript and h:outputStylesheet will not work
> correctly (remember that UIViewRoot "head" and "body" facets are transient,
> so if these components are relocated, are in fact transient too). Also, care
> must be taken to prevent the listener of programatic component
> addition/removal register components on this time.
> The conclusion based on this reasoning, it is clear the need of new event
> that be specific for relocate components (keep it simple for christ sake!).
> This event should be propagated for all components in the tree after the view
> is build from root to nodes. It could be good to have some clearification
> about the real intention of PostAddToViewEvent/PreRemoveFromViewEvent.
> Really, better names for those events are
> PostAddToComponentTreeEvent/PreRemoveFromComponentTreeEvent.
> I'll attach a proposal to fix this one soon.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.