Search code examples
jsfannotationsmojarra

Which JSF version(impl) support UI custom component annotations replacing XML taglib?


For a custom JSF component Foo, need to add the following taglib.xml. Which JSF impl (mojarra) version support annotations instead of XML?

taglib.xml

<facelet-taglib ...>        

      <namespace>http://xmlns.example.com/</namespace>

    <tag>
        <description>foo</description>
        <tag-name>foo</tag-name>
        <component>
            <component-type>com.example.component.HtmlFoo</component-type>
            <renderer-type>com.example.component.Foo</renderer-type>
        </component>                         
    </tag>      
</facelet-taglib>

UPDATED

@FacesComponent(createTag=true, namespace="http://xmlns.example.com/", tagName="foo")
public class HtmlFoo extends UIComponent {

    public HtmlFoo() {
        setRendererType("com.example.component.Foo");
    }

    public String getFamily() {
        return "com.example.component.data";
    }

    // ...
}


public class HtmlFooTag extends UIComponentELTag {
  
  @Override
  public String getComponentType() {
    return "com.example.component.HtmlFoo";
  }

  @Override
  public String getRendererType() {
    return "com.example.component.Foo";
  }

  // ...
}


@FacesRenderer(
        componentFamily="com.example.component.data",
        rendererType="com.example.component.Foo")
public class HtmlFooRenderer extends Renderer {

   //...
}

use the tag:

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:g="http://xmlns.example.com/">
     // ...
     <g:foo .../>
</html>

Error:

<g:foo> Tag Library supports namespace: http://xmlns.example.com/, but no tag was defined for name: foo

There is no annotation for HtmlFooTag. How it is connected to the component HtmlFoo?


Solution

  • It's supported since JSF 2.2, regardless of the implementation (any implementation must adhere the spec nonetheless). Since JSF 2.2, the in JSF 2.0 introduced @FacesComponent annotation got a createTag attribute which you can set to true to skip the XML boilerplate, along with optional namespace and tagName attributes. You can set the default renderer in the component's constructor.

    In other words:

    @FacesComponent(createTag=true, namespace="http://xmlns.example.com/", tagName="foo")
    public class HtmlFoo extends UIComponent {
    
        public HtmlFoo() {
            setRendererType("com.example.component.Foo");
        }
    
        // ...
    }