Annotation Type FacesDataModel
-
@Retention(RUNTIME) @Target(TYPE) @Inherited @Qualifier public @interface FacesDataModel
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 theforClass()
attribute.The runtime must maintain a collection of these
DataModel
s such thatUIData
and other components defined by the Jakarta Faces Specification can query the runtime for a suitableDataModel
wrapper (adapter) for the type of theirvalue
. This has to be done after all wrappers for specific types such asSet
are tried, but before theScalarDataModel
is selected as the wrapper. SeeUIData.getValue()
.This query must work as follows:
For an instance of type
Z
that is being bound to aUIData
component or other component defined by the Jakarta Faces Specification that utilizesDataModel
, the query for that type must return the most specific DataModel that can wrapZ
.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 classZZ
wrapped by the DataModel (as indicated by theforClass()
attribute) it holds thatZZ.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
andY
from this collection, if an object ofX
is aninstanceof
an object ofY
,X
appears in the collection beforeY
. The collection's sorting is otherwise arbitrary. In other words, subclasses come before their superclasses.For example:
Given
class B
,class A extends B
andclass Q
, two possible orders are;{A, B, Q}
{Q, A, B}
The only requirement here is that
A
appears beforeB
, sinceA
is a subclass ofB
.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 { }
package test.faces23; @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.faces23.Child1Model"
-
-
Element Detail
-
forClass
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:
- the type that the DataModel that is annotated with this annotation is able to wrap
- Default:
- java.lang.Object.class
-
-