Configuration files (faces-config.xml, .tld, facelets taglib)

Writing your component class

Write an abstract class, and let generate all property code, including saveState/restoreState methods in a concrete child class (Example: almost all components in tomahawk core and sandbox).

Write an abstract class (generally package scope) and use template pattern. In other words, all property code is generated including saveState/restoreState methods in a concrete child class, but other code inside the abstract class is copied to the generated class.

Write a component class manually

In this mode, no code is generated, but the information is chained to other files to be generated like faces-config.xml, tlds, tag classes, etc.

Below there is an example of it:

/**
* The most important points are:
*
* 1. Define componentType, componentFamily and rendererType adding its
* constants (like below) or directly in the annotation.
*
* 2. If the component has a jsp tag, define the "name" and the "tagClass"
* If the tagClass does not exists a new file is generated if make-tags
* goal is set on pom.xml
*
*/
@JSFComponent(
name = "mycomponents:sayHello",
clazz = "org.myorganization.component.sayhello.SayHello",
tagClass = "org.myorganization.component.sayhello.SayHelloTag")
public class SayHello extends UIOutput
{
public static final String COMPONENT_TYPE = "org.myorganization.SayHello";
public static final String DEFAULT_RENDERER_TYPE = "org.myorganization.SayHelloRenderer";
public static final String COMPONENT_FAMILY = "javax.faces.Output";
/** ..... Some custom code goes here .... **/
}

Write a component class using Abstract Pattern

The objective is create a abstract component class that defines all information required to generate the concrete component class. All custom code goes in the abstract class, so it is inherited to the child component.

This pattern is preferred over template mode, because it is more simple to understand, but there are some cases where this mode cannot be applied (like in myfaces core api, where the component hierarchy cannot be changed).

Below there is an example of it:

/**
* To generate component classes using abstract pattern
*
* 1. Define the "clazz" file which it is generated
*
* 2. Define componentType, componentFamily and rendererType adding its
* constants (like below) or directly in the annotation.
*
* 3. If the component has a jsp tag, define the "name" and the "tagClass"
* If the tagClass does not exists a new file is generated if make-tags
* goal is set on pom.xml
*
*/
@JSFComponent(
name = "mycomponents:sayHello",
clazz = "org.myorganization.component.sayhello.SayHello",
tagClass = "org.myorganization.component.sayhello.SayHelloTag")
public abstract class AbstractSayHello extends UIOutput
{
public static final String COMPONENT_TYPE = "org.myorganization.SayHello";
public static final String DEFAULT_RENDERER_TYPE = "org.myorganization.SayHelloRenderer";
public static final String COMPONENT_FAMILY = "javax.faces.Output";
/**
* User's first name.
*/
@JSFProperty
public abstract String getName();
}

Write a component class using Template Pattern

The objective is create an abstract (generally package scoped) class that works as a "template".

Add tomahawk core or core12 to your dependencies, where there is an alternate tag hierarchy, so your components can work with the reference implementation. Make sure tomahawk dependency. should be before myfaces core dependency in the pom, to be sure that tomahawk model is loaded first.

If you need to write some custom code on tag class, but keep some code generated, use abstract pattern on tag class. The properties that needs to be defined on abstract tag class must have inheritedTag="true", so there are not overriden. See t:tree component for an example.

Adding a Renderer to faces-config.xml file.

The annotations/doclets @JSFRenderer and @JSFRenderKit are used include renderer configuration to generated faces-config.xml files. Just add it to your renderer like this: