Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 2.0
    • Fix Version/s: None
    • Component/s: Components/Renderers
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      797
    • Status Whiteboard:
      Hide

      size_medium importance_small

      Show
      size_medium importance_small

      Description

      See discussion on "[jsr-314-open] Use a Renderer on a composite component"

      Below there are extracts of this one:

      Leonardo Uribe says:

      The javadoc of Application.createComponent(FacesContext context, Resource
      componentResource) says this:

      ".....Call UIComponent.setRendererType(java.lang.String) on the UIComponent
      instance, passing "javax.faces.Composite" as the argument........"

      Now suppose a custom composite component extending from UIInput, but
      implementing NamingContainer/UniqueIdVendor. The component family in this case
      is "javax.faces.Input". The result is the component will not work because the
      renderer used for composite components assumes the family
      "javax.faces.NamingContainer". This is ok, because the user just need to
      register a custom renderer for its composite component under that
      family/rendererType like the spec says.

      The problem is why it is mandatory to set "javax.faces.Composite" as renderer
      type. The javadoc should say:

      "...If the renderer type is not set (return null), Call
      UIComponent.setRendererType(java.lang.String) on the UIComponent instance,
      passing "javax.faces.Composite" as the argument...". In that case, a user can
      override the rendererType on the constructor and avoid this hack that works with
      the current spec:

      public void setRendererType(String rendererType)
      {
      //Ignore this call !
      if (!"javax.faces.Composite".equals(rendererType))

      { super.setRendererType(rendererType); }

      }

      Why override the default Renderer and use a custom one? Let's suppose the
      component proposed needs some custom code for converter, or for decode. The
      right place to put that kind of code is the Renderer class, not the component,
      but note it is possible to put that on the component class.

      Does that sounds reasonable? should I create an issue for this one?

      Ed Burns says:

      LU> The problem is why it is mandatory to set "javax.faces.Composite" as
      LU> renderer type. The javadoc should say:

      LU> "...If the renderer type is not set (return null), Call
      LU>
      UIComponent.setRendererType(java.lang.String)<file:///D:/jdk-1_5_0-doc/jsf20/mojarra-2.0.3-SNAPSHOT/docs/javadocs/javax/faces/component/UIComponent.html#setRendererType%28java.lang.String%29>on
      LU> the
      LU> UIComponent instance, passing "javax.faces.Composite" as the argument...".
      LU> In that case, a user can override the rendererType on the constructor and
      LU> avoid this hack that works with the current spec:

      I understand the problem you have uncovered. Take a look at the
      renderkit docs for javax.faces.NamingContainer/javax.faces.Composite.
      There are specific requirements in there that depend on the composite
      component metadata specification.

      I thought it would be toooooooo subtle to allow the Renderer to be
      customized beause this contract must also be followed in the custom
      renderer case.

      LU> Why override the default Renderer and use a custom one? Let's
      LU> suppose the component proposed needs some custom code for converter,
      LU> or for decode. The right place to put that kind of code is the
      LU> Renderer class, not the component, but note it is possible to put
      LU> that on the component class.

      Yes I understand that the Renderer is the right place for such things
      but the chosen programming model for customization of composite
      components is to override the top level component. Simple. If we're
      going to change that I need a more compelling reason than correctness.

      Leonardo Uribe says:

      The current behavior of javax.faces.NamingContainer/javax.faces.Composite
      renderer says that everything
      inside the facet UIComponent.COMPOSITE_FACET_NAME should be rendered. But sometimes
      the markup of the component changes according to its inner state. One simple
      example is
      h:commandLink. If this component is disabled, it should be rendered a <span>
      instead use <a>.
      Other example is tomahawk displayValueOnly property, that when is set to true,
      only the value
      needs to be rendered.

      Ok, if I have a composite component the first thought is use c:if tag, but
      remember that with
      partial state saving enabled this tag is evaluated when the view is build, not
      when it is
      rendered. Other alternative is use a component that allows to render one child
      at the time, and
      it is on myfaces commons (mc:renderOne, old sandbox s:limitRendered). The third
      alternative is
      use a custom renderer. The example I'm trying to do is this (all non relevant
      code has been removed:

      public void encodeEnd(FacesContext context, UIComponent component)
      throws IOException
      {
      UIComponent compositeFacet = (UIComponent) component
      .getFacet(UIComponent.COMPOSITE_FACET_NAME);
      CompositeInputHtml editor = (CompositeInputHtml) component;
      if( HtmlRendererUtils.isDisplayValueOnly(editor) )

      { encodeDisplayValueOnly(context, editor); }

      else if ( useFallback(editor) )

      { encodeEndFallBackMode(context, editor); }

      else
      {
      if( ! isVisible(editor) )

      { encodeHidden(context, editor); }

      else if( ! hasAnotherPropertyThatPreventsRenderThisOneCorrectly(
      context ) )

      { compositeFacet.encodeAll(context); }

      else

      { encodeEndFallBackMode(context, editor); }

      }
      }

      It is possible to think in other cases, like a composite component like this:

      <composite:implementation>
      <f:facet name="normal">
      ......some html markup......
      </f:facet>
      <f:facet name="disabled">
      ......some html markup......
      </f:facet>
      <f:facet name="special">
      ......some html markup......
      </f:facet>
      <composite:implementation>

      And use a custom renderer to control when one or other facet should be rendered.

      Note that in fact, with the hack on the component class on setRendererType, it
      is possible
      to override the Renderer without problem, so for my particular problem I can
      live with it.
      The question is if the spec should enforce the use of
      javax.faces.NamingContainer/javax.faces.Composite renderer for composite components
      or not.

        Activity

        Hide
        Ed Burns added a comment -

        Nice idea, move to 2.1.

        Show
        Ed Burns added a comment - Nice idea, move to 2.1.
        Hide
        Ed Burns added a comment -

        triage

        Show
        Ed Burns added a comment - triage
        Hide
        Ed Burns added a comment -

        rogerk

        Show
        Ed Burns added a comment - rogerk
        Hide
        rogerk added a comment -

        triage

        Show
        rogerk added a comment - triage
        Hide
        rogerk added a comment -

        triage

        Show
        rogerk added a comment - triage
        Hide
        Ed Burns added a comment -

        Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.

        Show
        Ed Burns added a comment - Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.
        Hide
        Manfred Riem added a comment -

        Set priority to Minor

        Show
        Manfred Riem added a comment - Set priority to Minor

          People

          • Assignee:
            Unassigned
            Reporter:
            lu4242
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: