Cannot call UIComponent.getCurrentComponent() from UIComponent.restoreState() 
or UIComponent.saveState()
--------------------------------------------------------------------------------------------------------

                 Key: MYFACES-2710
                 URL: https://issues.apache.org/jira/browse/MYFACES-2710
             Project: MyFaces Core
          Issue Type: Bug
          Components: JSR-314
    Affects Versions: 2.0.0
            Reporter: Leonardo Uribe
            Assignee: Leonardo Uribe


>From jsr-314-open list:

The javadoc of UIComponent.processRestoreState() says this:

"....Perform the component tree processing required by the Restore View  phase 
of the request processing lifecycle for all facets of this component, all 
children of this component, and this component itself, as follows.

    * Call the restoreState() method of this component.
    * Call pushComponentToEL(javax.faces.context.FacesContext, 
javax.faces.component.UIComponent).
    * Call the processRestoreState() method of all facets and children of this 
UIComponent in the order determined by a call to getFacetsAndChildren(). After 
returning from the processRestoreState() method on a child or facet, call 
popComponentFromEL(javax.faces.context.FacesContext)..."

The javadoc of UIComponent.processSaveState() says this:

".....Perform the component tree processing required by the state saving 
portion of the Render Response phase of the request processing lifecycle for 
all facets of this component, all children of this component, and this 
component itself, as follows.

    * consult the transient property of this component. If true, just return 
null.
    * Call pushComponentToEL(javax.faces.context.FacesContext, 
javax.faces.component.UIComponent).
    * Call the processSaveState() method of all facets and children of this 
UIComponent in the order determined by a call to getFacetsAndChildren(), 
skipping children and facets that are transient. Ensure that 
popComponentFromEL(javax.faces.context.FacesContext) is called correctly after 
each child or facet.
    * Call the saveState() method of this component.
    * Encapsulate the child state and your state into a Serializable Object and 
return it....."

The question is: Doesn't suppose that when you call 
UIComponent.getCurrentComponent() inside UIComponent.restoreState(), it returns 
the "current component"?. There is one case when we need to do this call and is 
on the wrapper used by UIComponent.subscribeToEvent(). The javadoc of this 
method says this:

"....Install the listener instance referenced by argument componentListener as 
a listener for events of type eventClass originating from this specific 
instance of UIComponent. The default implementation creates an inner 
SystemEventListener  instance that wraps argument componentListener as the 
listener  argument. This inner class must call through to the argument 
componentListener in its implementation of 
SystemEventListener.processEvent(javax.faces.event.SystemEvent)  and its 
implementation of SystemEventListener.isListenerForSource(java.lang.Object)  
must return true if the instance class of this UIComponent is assignable from 
the argument to isListenerForSource...."

Both myfaces and mojarra has the wrapper described by the javadoc, and that one 
is responsible to save/restore the system event listeners attached. To restore 
the "component" reference required, both implementations call 
UIComponent.getCurrentComponent() and both call processEvent but for the 
parent!.

It is obviously a bug (I don't see a valid reason why do the algorithm 
described), if you look other methods like processDecodes, you see the right 
pattern:

    *  If the rendered property of this UIComponent  is false, skip further 
processing.
    * Call pushComponentToEL(javax.faces.context.FacesContext, 
javax.faces.component.UIComponent).
    * Call the processDecodes() method of all facets and children of this 
UIComponent, in the order determined by a call to getFacetsAndChildren().
    * Call the decode() method of this component.
    * Call popComponentFromEL(javax.faces.context.FacesContext) from inside of 
a finally block, just before returning.
    * If a RuntimeException is thrown during decode processing, call 
FacesContext.renderResponse() and re-throw the exception.

I'll change myfaces algorithm to look like processDecodes(). But anyway, it is 
necessary to do the proper change on mojarra and on spec javadoc.

The spec issue is this:

http://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=792


-- 
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