javaserverfaces
  1. javaserverfaces
  2. JAVASERVERFACES-2089

Bound attribute values resolve to NULL during PreRenderViewEvent for nested composite components

    Details

      Description

      NOTE: This test is performed using a custom build of JSF 2.2.x that was supplied as a fix for the following issue:

      http://java.net/jira/browse/JAVASERVERFACES-1826?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=309816#action_309816

      I am required to use this version as the current 2.0.3 RI does not save state correctly for components dynamically created while processing the PreRenderViewEvent (although, for this particular issue the same problem probably exists in 2.0.3).

      Overview:

      Page

      • Component1
      • Component2

      When processing the PreRenderViewEvent, for custom composite components nested within another custom composite component any data-bound attributes are resolved as NULL. This has impact when attempting to dynamically create new components based on some bound-data that is accessed via the component attributes using this.getAttributes().get(<attr_name>).

      The resulting dynamic sub-components DO render correctly and any data bound values are present as expected (values are set via ValueExpressions while creating the dynamic sub-components).

      The supplied code is an eclipse project (latest version), please let me know if I need to export the project into an alternate format.

      I plan to test against MyFaces implementation later, and have spent some time investigating the issue via JSF source code but have found nothing yet.

      Regards,

      Matt Sweeney

      1. 20111021-i_mojarra_2089_test.patch
        22 kB
        Ed Burns
      2. 20111024-JAVASERVERFACES-2089-initial-render.tiff
        35 kB
        Ed Burns
      3. 20111025-i_mojarra_2089-1532-snapshot.patch
        164 kB
        Ed Burns

        Issue Links

          Activity

          Hide
          kennardconsulting added a comment -

          Okay I have done some further experiments. Using PreRenderComponentEvent in the Acid Test (JAVASERVERFACES-1826) does not work well. Nothing gets persisted into the ViewState. I believe PreRenderComponentEvent is triggered too late in the cycle to do dynamic component tree manipulation?

          Therefore I believe 2 (above) is correct:

          "Components that use PreRenderViewEvent can never access EL like #

          {internal}"

          And by implication:

          "Components that use dynamic component tree manipulation can never access EL like #{internal}

          "

          If this is 'works as designed' then I think we need to revisit the design.

          Show
          kennardconsulting added a comment - Okay I have done some further experiments. Using PreRenderComponentEvent in the Acid Test ( JAVASERVERFACES-1826 ) does not work well. Nothing gets persisted into the ViewState. I believe PreRenderComponentEvent is triggered too late in the cycle to do dynamic component tree manipulation? Therefore I believe 2 (above) is correct: "Components that use PreRenderViewEvent can never access EL like # {internal}" And by implication: "Components that use dynamic component tree manipulation can never access EL like #{internal} " If this is 'works as designed' then I think we need to revisit the design.
          Hide
          Manfred Riem added a comment -

          Closing resolved issue out

          Show
          Manfred Riem added a comment - Closing resolved issue out
          Hide
          kennardconsulting added a comment -

          Hi guys,

          I just hit this bug again while working on a client's code, and noticed Manfred had closed it as 'resolved'?

          Why was this considered 'resolved'? It's a real problem for me, stopping me doing things like...

          <h:dataTable value="#

          {companyImport.importFiles}

          " var="_importFile">
          <h:column>
          <h:outputText value="#{_importFile.name}:"/>
          </h:column>
          <h:column>
          <m:metawidget value="#{_importFile.import}"/>
          </h:column>
          </h:dataTable>

          ...because the m:metawidget cannot 'see' the #{_importFile} var.

          Can we please reopen, or at least explain why it is resolved?

          Show
          kennardconsulting added a comment - Hi guys, I just hit this bug again while working on a client's code, and noticed Manfred had closed it as 'resolved'? Why was this considered 'resolved'? It's a real problem for me, stopping me doing things like... <h:dataTable value="# {companyImport.importFiles} " var="_importFile"> <h:column> <h:outputText value="#{_importFile.name}:"/> </h:column> <h:column> <m:metawidget value="#{_importFile.import}"/> </h:column> </h:dataTable> ...because the m:metawidget cannot 'see' the #{_importFile} var. Can we please reopen, or at least explain why it is resolved?
          Hide
          temaleva added a comment -

          Hi.
          I am absolutely agree with Kennrad.
          I could not even vote on this issue while it closed.

          I use metawidget and other dynamic stuff in my project and also starving from this problem.

          Just explain a little bit.

          There is also a trivial example which demonstrate this problem.
          This code won't work because f: tags are specific to the component, not to the iterated item. At view build time the #

          {column} isn't available. It's only available during render time.
          <p:columns id="#{table_id}_column" value="#{fields}" var="column" columnIndexVar="colIndex" sortBy="#{column}

          ">
          <h:outputText value="#

          {data_request[column.value][0]}">
          <f:converter converterId="#{column.converterID}" />
          </h:outputText>
          </p:columns>

          This could only overcome if you have converter list on a build time and this will work:
          <p:columns id="#{table_id}_column" value="#{fields}" var="column" columnIndexVar="colIndex" sortBy="#{column}">
          <h:outputText value="#{data_request[column.value][0]}

          " converter="#

          {converters[column.converterID]}

          "/>
          </p:columns>

          So the only solution one could use for metawidget is almost the same: to create a Mapped collection of Items in Bean (simplest case).
          So the code should looks like:

          <h:dataTable value="#

          {companyImport.importFileIds}

          " var="_importFileId">
          <h:column>
          <m:metawidget value="#

          {companyImport.importFile[_importFileId][import]}

          "/>
          </h:column>
          </h:dataTable>

          So An iterator variable accessible only for facelet page itself during render time.
          And the question is: How could we use facelet page at all (for dynamic processing) if it's rendered content is not available?

          Show
          temaleva added a comment - Hi. I am absolutely agree with Kennrad. I could not even vote on this issue while it closed. I use metawidget and other dynamic stuff in my project and also starving from this problem. Just explain a little bit. There is also a trivial example which demonstrate this problem. This code won't work because f: tags are specific to the component, not to the iterated item. At view build time the # {column} isn't available. It's only available during render time. <p:columns id="#{table_id}_column" value="#{fields}" var="column" columnIndexVar="colIndex" sortBy="#{column} "> <h:outputText value="# {data_request[column.value][0]}"> <f:converter converterId="#{column.converterID}" /> </h:outputText> </p:columns> This could only overcome if you have converter list on a build time and this will work: <p:columns id="#{table_id}_column" value="#{fields}" var="column" columnIndexVar="colIndex" sortBy="#{column}"> <h:outputText value="#{data_request[column.value][0]} " converter="# {converters[column.converterID]} "/> </p:columns> So the only solution one could use for metawidget is almost the same: to create a Mapped collection of Items in Bean (simplest case). So the code should looks like: <h:dataTable value="# {companyImport.importFileIds} " var="_importFileId"> <h:column> <m:metawidget value="# {companyImport.importFile[_importFileId][import]} "/> </h:column> </h:dataTable> So An iterator variable accessible only for facelet page itself during render time. And the question is: How could we use facelet page at all (for dynamic processing) if it's rendered content is not available?
          Hide
          temaleva added a comment -

          Sorry, I mean binding of course not value. So this way <m:metawidget binding="#

          {companyImport.importFile[_importFileId][import]}

          "/>

          Show
          temaleva added a comment - Sorry, I mean binding of course not value. So this way <m:metawidget binding="# {companyImport.importFile[_importFileId][import]} "/>

            People

            • Assignee:
              Ed Burns
              Reporter:
              Rinner23
            • Votes:
              2 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: