[ 
https://issues.apache.org/jira/browse/MYFACES-2259?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Leonardo Uribe reopened MYFACES-2259:
-------------------------------------


I'll reopen this issue to include this problem emailed to jsr-314-comments at 
jcp.org:

Subject: h:outputScript target="head" is rendered in body when partial state 
saving is used and there is a postback

<START MAIL>
Hi

I have notice a failure when <h:outputScript target="head" ....> is used and 
there is a postback, that requires change something in the spec.

Suppose the following scenario

<h:head>
</h:head>
<h:body>
    <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
    <!-- some other stuff -->
</h:body>

The renderer documentation of h:outputScript and h:outputStylesheet says this:

"....The implementation of this renderer must have a @ListenerFor annotation 
attached to it, at the class level, declaring PostAddToViewEvent.class as the 
value of the systemEventClass attribute. The presence of this annotation on a 
renderer implies the renderer implements ComponentSystemEventListener, which 
this renderer must do. The implementation of processEvent() must extract the 
UIComponent from the argument event and look for the presence of the key 
"target" in the component's attribute Map. If and only if such a key is 
present, the implementation of processEvent() must pass the component to 
UIViewRoot.addComponentResource()...."

Now imagine the user are submitting a form and there is a validation error. In 
that case there is a postback so the same view is rendered. The first request 
build a view like this:

<h:head>
    <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
</h:head>
<h:body>
    <!-- some other stuff -->
</h:body>

but the next one restore this if partial state saving is used:

<h:head>
</h:head>
<h:body>
    <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
    <!-- some other stuff -->
</h:body>

the reason why this happens is clear looking the documentation of 
UIComponent.getChildren():

"...After the child component has been added to the view, if the following 
condition is not met:
      FacesContext.isPostback() returns true and 
FacesContext.getCurrentPhaseId() returns PhaseId.RESTORE_VIEW..."

This is valid if we are using jsf 1.2 state saving, because we save and restore 
the whole tree, so the components created are already on the view. But when we 
use partial state saving, we do this operation:

restored view = apply delta on (fresh view from VDL.buildView() + added 
components after that - removed components after that)

The conclusion is:  All components that relies on ComponentSystemEventListener 
listening PostAddToViewEvent to be relocated in some way (h:outputScript, 
h:outputStylesheet, composite:insertChildren, composite:insertFacet (because we 
need the whole tree built before move components, otherwise nested composite 
components will not work correctly) ) are incompatible with partial state 
saving. Its more, if the affected components are moved outside/inside/between 
NamingContainer or UniqueIdVendor instances the state will not be correctly 
restored.

The solution from my point of view is relax the restriction on 
UIComponent.getChildren() (maybe adding a faces context attribute saying the 
current view is being built using partial state saving), so when partial state 
saving is used, PostAddToViewEvent will be published.

<END MAIL>

An alternative solution to this issue is create a custom event that is trigger 
when partial state saving is on, and register all relocation listeners.

> Implement Partial State Saving feature
> --------------------------------------
>
>                 Key: MYFACES-2259
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2259
>             Project: MyFaces Core
>          Issue Type: Task
>          Components: JSR-314
>    Affects Versions: 2.0.0-alpha
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>             Fix For: 2.0.0-alpha
>
>
> Implement use of getStateHelper and partial state saving on all components 
> and the required code on facelets (StateManagerStrategy and invoke of 
> markInitialState on related ComponentTagHandler).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to