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.