Apache MyFaces
Project Documentation
Foundation

Properties

Components, converters and validators have properties. Usually, properties must be defined on .tld files. Also, property getter/setter and saveState/restoreState methods can be generated automatically, reducing the amount of code that should be maintained.

Properties are inherited, so if a component/converter/validator extends from a parent component/converter/validator that has some property defined, the child must have it on its .tld.

But sometimes we have the following scenarios:

  • Components, converters and validators also have properties with no getter and setters (like "binding" property), which are implemented in their tag classes or facelets tag handler.
  • Also, some properties implemented on a parent class are not implemented on some children, so we need to exclude it from its tld definition.
  • Users can implement its own setter and getter methods for properties.
  • Some properties are related only to component but should not be on tld.
  • Some properties have some specific behavior (for example they could contains objects implementing StateHolder interface).

All these cases could be handled using @JSFProperty and @JSFJspProperty annotations. Below there are some examples describing how to use it.

General case

The most common case is let the property body be generated.

  
    @JSFProperty
    public abstract String getAutocomplete();
  

Custom Implementation of getter/setters

One example is UIViewRoot "renderKitId" property:

    @JSFProperty
    public String getRenderKitId()
    {
        //... custom implementation ...
    }
    
    public void setRenderKitId(String renderKitId)
    {
        //... custom implementation ...
    } 

Properties without getter/setters

This syntax should be used only in very special cases and users should use @JSFProperty annotation/doclet instead.

@JSFComponent(type = "javax.faces.ComponentBase", family = "javax.faces.ComponentBase", desc = "base component when all components must inherit", tagClass = "javax.faces.webapp.UIComponentELTag", configExcluded = true)
@JSFJspProperty(name = "binding", 
    returnType = "javax.faces.component.UIComponent", 
    longDesc = "Identifies a backing bean property (of type UIComponent or appropriate subclass) to bind to this component instance. This value must be an EL expression.", desc = "backing bean property to bind to this component instance")
public abstract class UIComponentBase extends UIComponent
{
    // .... some code ...
}

Excluding properties from tld

One example is UIParameter "rendered" property:

    /**
     * Disable this property; although this class extends a base-class that defines a read/write rendered property, this
     * particular subclass does not support setting it. Yes, this is broken OO design: direct all complaints to the JSF
     * spec group.
     */
    @Override
    @JSFProperty(tagExcluded = true)
    public void setRendered(boolean state)
    {
        super.setRendered(state);
        // call parent method due TCK problems
        // throw new UnsupportedOperationException();
    }

Properties with different name in component and tag class

One example is UICommand "action" property. To change it on tld, use "jspName".

    @JSFProperty(stateHolder = true, returnSignature = "java.lang.Object", jspName = "action")
    public MethodExpression getActionExpression()
    {
        // .... some code ...
    }

MethodExpression/MethodBinding properties

    @JSFProperty(stateHolder = true, returnSignature = "void", methodSignature = "javax.faces.event.ActionEvent")
    public MethodBinding getActionListener()
    {
        // .... some code ...
    }
    
    @JSFProperty(stateHolder = true, returnSignature = "java.lang.Object", jspName = "action")
    public MethodExpression getActionExpression()
    {
        // .... some code ...
    }