MyFaces Core
  1. MyFaces Core
  2. MYFACES-3157

Fix order of isRendered and pushComponentToEL invocations

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0.8, 2.1.2
    • Component/s: None
    • Labels:
      None
    • Environment:
      myfaces core trunk

      Description

      Current specification for lifecycles methods:
      1) processDecodes
      2) processValidators
      3) processUpdates
      4) encodeAll
      4) encodeBegin

      explicitly says that:

      1) If the rendered property of this UIComponent is false, skip further processing.
      2) call pushComponentToEL

      But in that order of invocations it is impossible to achieve rendered like this:

      <h:outputText rendered="#

      {component.id eq 'outputTextId'}

      " id="outputTextId" />

      i.e. any rendered ValueEpression based on component itself. In Myfaces we should implement in in reverse order, because specified behaviour is buggy.

      Please see this mail thread: http://www.mail-archive.com/dev@myfaces.apache.org/msg53300.html

      and

      http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1002

      for details.

      1. myfaces-api-MYFACES-3157-v1.patch
        29 kB
        Martin Kočí
      2. myfaces-api-MYFACES-3157-v2.patch
        33 kB
        Martin Kočí

        Activity

        Leonardo Uribe made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Leonardo Uribe made changes -
        Resolution Fixed [ 1 ]
        Status Open [ 1 ] Resolved [ 5 ]
        Assignee Martin Kočí [ markoc50 ]
        Fix Version/s 2.0.8 [ 12316514 ]
        Fix Version/s 2.1.2 [ 12316512 ]
        Hide
        Leonardo Uribe added a comment -

        Thanks to Martin Koci for provide this patch

        Show
        Leonardo Uribe added a comment - Thanks to Martin Koci for provide this patch
        Martin Kočí made changes -
        Attachment myfaces-api-MYFACES-3157-v2.patch [ 12486087 ]
        Hide
        Martin Kočí added a comment -

        patch adapted for current trunk + added test and fix for visitTree method

        Show
        Martin Kočí added a comment - patch adapted for current trunk + added test and fix for visitTree method
        Hide
        Martin Kočí added a comment -

        This affects methods visitTree too: specification says "UIComponent.visitTree() implementations must call UIComponent.pushComponentToEL() before performing the visit and UIComponent.popComponentFromEL() after the visit." - methos isVisitable reads "rendered" property.

        Show
        Martin Kočí added a comment - This affects methods visitTree too: specification says "UIComponent.visitTree() implementations must call UIComponent.pushComponentToEL() before performing the visit and UIComponent.popComponentFromEL() after the visit." - methos isVisitable reads "rendered" property.
        Hide
        Martin Kočí added a comment -

        classes with isRendered() in myfaces -impl and myfaces-shared-core:

        HtmlTableRendererBase
        HtmlGridRendererBase
        HtmlRendererUtils
        RendererUtils
        UIRepeat

        Show
        Martin Kočí added a comment - classes with isRendered() in myfaces -impl and myfaces-shared-core: HtmlTableRendererBase HtmlGridRendererBase HtmlRendererUtils RendererUtils UIRepeat
        Martin Kočí made changes -
        Field Original Value New Value
        Attachment myfaces-api-MYFACES-3157-v1.patch [ 12480782 ]
        Hide
        Martin Kočí added a comment -

        myfaces-api-MYFACES-3157-v1.patch suggests changes in UIData, UIInput and UIComponentBase. The result is consistent behaviour with encodeBegin.

        please review ; there are open questions, I'll discuss them at mailing list.

        Show
        Martin Kočí added a comment - myfaces-api- MYFACES-3157 -v1.patch suggests changes in UIData, UIInput and UIComponentBase. The result is consistent behaviour with encodeBegin. please review ; there are open questions, I'll discuss them at mailing list.
        Hide
        Martin Kočí added a comment -

        problem is not restricted only on rendered: for example, #

        {component}

        for immediate property does not work too:
        From UIInput:

        if (!isImmediate())
        {
        try
        {
        pushComponentToEL(context, this);

        Show
        Martin Kočí added a comment - problem is not restricted only on rendered: for example, # {component} for immediate property does not work too: From UIInput: if (!isImmediate()) { try { pushComponentToEL(context, this);
        Hide
        Martin Kočí added a comment -

        Classes from API where if (!isRendered()) is used:

        javax.faces.render.Renderer.encodeChildren(FacesContext, UIComponent)

        javax.faces.component.UIComponent.isVisitable(VisitContext)
        javax.faces.component.UIComponent.encodeAll(FacesContext)
        javax.faces.component.UIComponentBase._isPhaseExecutable(FacesContext)

        javax.faces.component.UIData.processDecodes(FacesContext)
        javax.faces.component.UIData.processValidators(FacesContext)
        javax.faces.component.UIData.processUpdates(FacesContext)
        javax.faces.component.UIData.processColumnFacets(FacesContext, int)
        javax.faces.component.UIData.processColumnChildren(FacesContext, int)

        javax.faces.component.UIInput.processDecodes(FacesContext)
        javax.faces.component.UIInput.processValidators(FacesContext)
        javax.faces.component.UIInput.processUpdates(FacesContext)

        UIData code is inconsistent already: UIData.processDecodes
        if (!isRendered())
        return;
        pushComponentToEL(context, this);

        and UIData.processUpdates:
        pushComponentToEL(context, this);
        if (!isRendered())
        return;

        Show
        Martin Kočí added a comment - Classes from API where if (!isRendered()) is used: javax.faces.render.Renderer.encodeChildren(FacesContext, UIComponent) javax.faces.component.UIComponent.isVisitable(VisitContext) javax.faces.component.UIComponent.encodeAll(FacesContext) javax.faces.component.UIComponentBase._isPhaseExecutable(FacesContext) javax.faces.component.UIData.processDecodes(FacesContext) javax.faces.component.UIData.processValidators(FacesContext) javax.faces.component.UIData.processUpdates(FacesContext) javax.faces.component.UIData.processColumnFacets(FacesContext, int) javax.faces.component.UIData.processColumnChildren(FacesContext, int) javax.faces.component.UIInput.processDecodes(FacesContext) javax.faces.component.UIInput.processValidators(FacesContext) javax.faces.component.UIInput.processUpdates(FacesContext) UIData code is inconsistent already: UIData.processDecodes if (!isRendered()) return; pushComponentToEL(context, this); and UIData.processUpdates: pushComponentToEL(context, this); if (!isRendered()) return;
        Hide
        Jakob Korherr added a comment -

        we can only do this, if it is not explicitely tested by the TCK!

        Unfortunately, TCK-compliance is more important then fixing such spec-bugs...

        Show
        Jakob Korherr added a comment - we can only do this, if it is not explicitely tested by the TCK! Unfortunately, TCK-compliance is more important then fixing such spec-bugs...
        Martin Kočí created issue -

          People

          • Assignee:
            Martin Kočí
            Reporter:
            Martin Kočí
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development