Datasources provide work of data-aware components.
Visual components themselves do not access Middleware and get entity instances from related datasources. Furthermore, one data source can work with multiple visual components if they need the same instance or set of instances.
The link between a visual component and a data source consists of the following:-
When the user changes the value in the component, the new value is set for the entity attribute in the data source
-
When the entity attribute is modified in the code, the new value is set and displayed in the visual component
-
User input can be monitored both by the datasource listener and the value listener of the component – they are fired sequentially.
-
To read or write the value of an attribute in the application code, it is recommended to use the data source, rather than the component. Below is an example of reading the attribute:
@Inject private FieldGroup fieldGroup; @Inject private Datasource<Order> orderDs; public void init(Map<String, Object> params) { Customer customer; // Get customer from component customer = (Customer) fieldGroup.getFieldValue("customer"); // Get customer from datasource customer = orderDs.getItem().getCustomer(); }
As can be seen, working entity attribute values through the component requires type casting and, in case of the FieldGroup, specifying the attribute name as a string. At the same time, if the instance is obtained from the datasource via the
getItem()
method, the values of attributes can be read and modified directly.
Typically, the visual component is bound to the attribute that directly belongs to the entity in the data source. In the example
above, the component is bound to the customer
attribute of the Order
entity.
A component can be associated with an attribute of a related entity, for example, customer.name
. In this case, the component will display the value of the name attribute, however when the user changes the value, the datasource
listeners will not be invoked and the changes will not be saved. Therefore, it makes sense to bind the component to second-order
entity attributes only if they are intended for display. For example in a Label, a Table column, or in a TextField, where editable = false
.
datasources also track changes in entities contained therein and can send modified instances back to Middleware for storing in a database.
The basic sources of interfaces are described below.
-
Datasource
is a simple data source designed to work with one entity instance. The instance is set by thesetItem()
method and is accessed viagetItem()
.DatasourceImpl
class is the standard implementation of such source, which is used, for instance, as a main data source on entity edit screens. -
CollectionDatasource
is a data source designed to work with a collection of entity instances. The collection is loaded with the invocation of therefresh()
method, instance keys are accessible through thegetItemIds()
method. ThesetItem()
method sets the “current” instance of the collection andgetItem()
returns it, i.e., for example, the one that corresponds to the currently selected table row.The way to load collections is determined by implementation. The most typical one is loading from Middleware via DataManager; in this case,
setQuery()
,setQueryFilter()
are used to form a JPQL query.CollectionDatasourceImpl
class is the standard implementation of such sources, which is used on screens with entity lists.-
GroupDatasource
is a subtype ofCollectionDatasource
, designed to work with the GroupTable component.Standard implementation is the
GroupDatasourceImpl
class. -
HierarchicalDatasource
is a subtype ofCollectionDatasource
, designed to work with the Tree and TreeTable components.Standard implementation is the
HierarchicalDatasourceImpl
class.
-
-
NestedDatasource
is a data source designed to work with instances that are loaded in an attribute of another entity. In this case, a source that contains a parent entity is accessible viagetMaster()
, and meta property that corresponds to the parent attribute containing instances of this source is accessible viagetProperty()
.For example an entity instance
Order
which contains a reference to theCustomer
instance is set in thedsOrder
source. Then, to link theCustomer
instance with visual components, it is enough to createNestedDatasource
withdsOrder as parent
and meta property to point to theOrder.customer
attribute.-
PropertyDatasource
is a subtype ofNestedDatasource
, designed to work with one instance or collection of related entities that are not embedded.Standard implementations: for working with one instance –
PropertyDatasourceImpl
, with a collection –CollectionPropertyDatasourceImpl
,GroupPropertyDatasourceImpl
,HierarchicalPropertyDatasourceImpl
. The latter also implement theCollectionDatasource
interface, however some of its irrelevant methods associated with loading likesetQuery()
throwUnsupportedOperationException
. -
EmbeddedDatasource
is a subtype ofNestedDatasource
, which contains an instance of an embedded entity.Standard implementation is the
EmbeddedDatasourceImpl class
.
-
-
RuntimePropsDatasource
is a specific source, designed to work with dynamic attributes of entities.
Typically, datasources are declared in the dsContext
section of a screen descriptor.