Top Description Methods
javax.faces.model

public @Interface FacesDataModel

extends Annotation
Known Direct Implementers
com.sun.faces.cdi.FacesDataModelAnnotationLiteral, javax.faces.component.UIData.FacesDataModelAnnotationLiteral
Annotations
@Retention:RUNTIME
@Target:TYPE
@Inherited
@Qualifier
Static Imports
java.lang.annotation.ElementType.TYPE, .RetentionPolicy.RUNTIME

The presence of this annotation on a class automatically registers the class with the runtime as a DataModel that is capable of wrapping a type indicated by the FacesDataModel#forClass() attribute.

The runtime must maintain a collection of these DataModels such that UIData and other components defined by the JSF specification can query the runtime for a suitable DataModel wrapper (adapter) for the type of their value. This has to be done after all wrappers for specific types such as Set are tried, but before the ScalarDataModel is selected as the wrapper. See UIData#getValue().

This query must work as follows:

For an instance of type Z that is being bound to a UIData component or other component defined by the JSF specification that utilizes DataModel, the query for that type must return the most specific DataModel that can wrap Z.

This most specific DataModel is defined as the DataModel that is obtained by first sorting the collection in which the registered DataModels are stored (for details on this sorting see below) and then iterating through the sorted collection from beginning to end and stopping this iteration at the first match where for the class ZZ wrapped by the DataModel (as indicated by the FacesDataModel#forClass() attribute) it holds that ZZ.isAssignableFrom(Z). This match is then taken as the most specific DataModel.

The sorting must be done as follows:

Sort on the class wrapped by a DataModel that is stored in the above mentioned collection such that for any 2 classes X and Y from this collection, if an object of X is an instanceof an object of Y, X appears in the collection before Y. The collection's sorting is otherwise arbitrary. In other words, subclasses come before their superclasses.

For example:

Given class B, class A extends B and class Q, two possible orders are;

  1. {A, B, Q}
  2. {Q, A, B}

The only requirement here is that A appears before B, since A is a subclass of B.

The specification does not define a public method to obtain an instance of the "most specific DataModel for a given type". Such an instance can be obtained using code similar to the following.

 
   @SuppressWarnings("unchecked")
   public <T> DataModel<T> createDataModel(Class<T> forClass, Object value) {
       class LocalUIData extends UIData {
           @Override
           public DataModel<?> getDataModel() {
               return super.getDataModel();
           }
       }
       LocalUIData localUIData = new LocalUIData();
       localUIData.setValue(value);

       return (DataModel<T>) localUIData.getDataModel();
   }
 
 

For example:

 
 public class Child1 {

 }
 
 
and
 
 package test.jsf23;

 @FacesDataModel(forClass = Child1.class)
 public class Child1Model<E> extends DataModel<E> {

    @Override
    public int getRowCount() {
        return 0;
    }

    @Override
    public E getRowData() {
        return null;
    }

    @Override
    public int getRowIndex() {
        return 0;
    }

    @Override
    public Object getWrappedData() {
        return null;
    } 

    @Override
    public boolean isRowAvailable() {
        return false;
    }

    @Override
    public void setRowIndex(int arg0) {

    }

    @Override
    public void setWrappedData(Object arg0) {

    }
 }
 
 

Then the following must work:

 
 DataModel<Child1> myModel = createDataModel(Child1.class, new Child1());
 assert myModel instanceof Child1Model;
 System.out.println(myModel.getClass());
 
 

The result printed should be e.g.: "class test.jsf23.Child1Model"

Method Summary

Modifier and TypeMethod and Description
public Class<?>

Returns:

the type that the DataModel that is annotated with this annotation is able to wrap
forClass
()

The value of this annotation attribute is taken to be the type that the DataModel that is annotated with this annotation is able to wrap.

Inherited from java.lang.annotation.Annotation:
annotationTypeequalshashCodetoString

Method Detail

forClassback to summary
public Class<?> forClass()

The value of this annotation attribute is taken to be the type that the DataModel that is annotated with this annotation is able to wrap.

Returns:Class<?>

the type that the DataModel that is annotated with this annotation is able to wrap