[ 
https://issues.apache.org/jira/browse/MYFACES-985?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13069636#comment-13069636
 ] 

Leonardo Uribe commented on MYFACES-985:
----------------------------------------

Doing some performance improvements I notice this old issue. Basically, the 
code proposed is invalid, but just for reference I'll explain what's going on 
in this case.

The general problem is about when it is valid to add components in JSF inside a 
dataTable. In theory, UIData.setRowIndex do the following:

1. If the component is in row -1 (no row), take a "snapshot" of the components 
that implements 

EditableValueHolder, to restore them later when rows are traversed.
2. If the component is in a row, save the current state of EditableValueHolder 
components.
3. Move to the selected row.
4. If no state saved found, restore EditableValueHolder components from saved 
initial state.
5. If state saved found, restore EditableValueHolder components from stored 
saved state.

The algorithm ignores all transient components, because they don't have state 
(for example, t:inputCalendar uses a transient input component when popup mode 
is enabled). The problem happens when a user try to create  inside a renderer a 
component that is EditableValueHolder and is not transient. In the moment the 
"snapshot" is created, the component does not exists, so the initial state 
cannot be created and the algorithm will fail. 

I ignore the reasons why Mojarra code works, but I believe that is not 
intentional. In JSF 2.1, full row component state was added to UIData, and the 
same principle applies, but in that case the restriction applies to all 
components. Note transient component are ignored too. 

The problem is adding a non transient EditableValueHolder component inside a 
dataTable row leads to a illegal state, because the initial state is unknown.

In JSF 2.0 and upper the most standard way to add a component as "structure" of 
other component is use a custom component facelet tag handler. In t:dataTable, 
this hack is used for detailStampRow and ajaxRowRender features. Also, 
PostAddToViewEvent can be used to modify the component tree, because it occur 
before markInitialState, so UIData rowStatePreserved will work well, and PSS 
algorithm will deal with it gracefully.

I'll close this issue as invalid, because everything that can be done for solve 
this issue was already done, and the reasons why does not work are completely 
understood.

> UIData with multihierarchical children inside produces NPE
> ----------------------------------------------------------
>
>                 Key: MYFACES-985
>                 URL: https://issues.apache.org/jira/browse/MYFACES-985
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: General
>         Environment: Tomcat 5.0
> JDK 1.4
>            Reporter: Andrew Kharchenko 
>            Assignee: Mathias Broekelmann
>             Fix For: 2.0.0
>
>         Attachments: UIData NPE Sample.rar
>
>
> I've found incorrect UIData behaviour under MyFaces which produces 
> NullPointerException on runtime and which works fine under Sun implementation.
> Here it is:
> I have a custom component which is extentor from UIInput. This component has 
> UIPanel extentor component as child which is added to children list of 
> UIInput component on rendering. 
> For one's turn, UIPanel extentor has one more UIInput extentor component as 
> child which is added to children list of UIPanel component on rendering.
> This component works fine standalone, but when it is added to UIData, I have 
> NPE on runtime. Here is the part of listing:
> java.lang.NullPointerException
>  at 
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:223)
>  at 
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:235)
>  at 
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:235)
>  at 
> javax.faces.component.UIData.restoreDescendantComponentStates(UIData.java:235)
>  at javax.faces.component.UIData.setRowIndex(UIData.java:178)
> I will also attach sample component's classes, definitions and test page if 
> it will be granted after issue creation.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to