This application component provides extensions for different use-cases for metadata interactions in CUBA.
metadata-extensions
is available in the CUBA marketplace- Select a version of the add-on which is compatible with the platform version used in your project:
Platform Version | Add-on Version |
---|---|
7.2.x | 0.3.x - 0.4.x |
7.1.x | 0.1.x - 0.2.x |
Add custom application component to your project:
- Artifact group:
de.diedavids.cuba.metadataextensions
- Artifact name:
metadataextensions-global
- Version: add-on version
dependencies {
appComponent("de.diedavids.cuba.metadataextensions:metadataextensions-global:*addon-version*")
}
Information on changes that happen through the different versions of the application component can be found in the CHANGELOG. The Changelog also contains information about breaking changes and tips on how to resolve them.
To see this application component in action, check out this example: cuba-example-using-metadata-extensions.
The entity Dialog is a special kind of an Input Dialog. Instead of defining directly the input parameter types manually, in the Entity Dialog a parameter references an Entity attribute. Based on the Metadata API of CUBA the correct Input Parameters will be displayed.
The Entity Dialog comes in two flavors:
- imperative definition via the
EntityDialogs
API - declarative definition via a XML Facet
The EntityDialogs
API is an extension of the Dialogs
API provided by CUBA since version 7.0.
EntityDialogs provides the ability to create a specific kind of InputDialog
that allows to enter entity attributes.
The method createMetadataInputDialog
allows to specific one or multiple entity attributes.
Based on the type that is defined in the Entity, the InputDialog
will contain the correct input fields.
Additionally the values can be bound to a particular entity instance.
The API mirrors the style of the existing Dialogs
API. An example usage of this method looks like this:
import com.haulmont.chile.core.model.MetaClass;
import com.haulmont.cuba.gui.app.core.inputdialog.InputDialog;
import de.diedavids.cuba.metadataextensions.EntityDialogs;
import static entityAttributeParameter;
public class CustomerBrowse extends StandardLookup<Customer> {
@Inject
protected EntityDialogs entityDialogs;
@Subscribe("customersTable.quickChange")
protected void onCustomersTableQuickChange(Action.ActionPerformedEvent event) {
Customer customer = customersTable.getSingleSelected();
entityDialogs.createEntityInputDialog(this, Customer.class)
.withEntity(customer)
.withCaption(messageBundle.getMessage("change"))
.withParameters(
entityAttributeParameter(Customer.class, "name")
.withAutoBinding(false),
entityAttributeParameter(Customer.class, "birthday")
.withAutoBinding(true)
)
.withCloseListener(closeEvent -> /* ... */)
.show();
}
}
The static method entityAttributeParameter
is leveraged here to easily create EntityAttributeInputParameter
instances.
The EntityAttributeInputParameter
is very similar to the InputParameter
from CUBA.
There is one attribute called autoBinding
, which can be set through the corresponding builder method: withAutoBinding
.
It means, that in case the the Dialog contains an entity reference through withEntity(customer)
,
the value defined in the customer instance is bound to the input field of the Input Dialog.
For more information about the options for the parameter see EntityAttributeInputParameter.java.
The alternative to using the EntityDialogs
API directly via source code is to use the declarative variant,
where the main part of the entity dialog is defined in the XML screen descriptor.
Add a XML namespace ddcme
to the window tag of your screen like this:
<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
xmlns:ddcme="http://schemas.diedavids.de/metadataextensions/0.1/ui-component.xsd">
Then add your entity dialog facet to the facet section of the screen:
<facets>
<ddcme:entityDialog
id="createLaptopDialog"
entityClass="de.diedavids.cuba.metadataextensions.entity.example.Product"
caption="msg://createLaptop">
<ddcme:parameters>
<ddcme:entityAttributeParameter id="name" property="name" autoBinding="true" />
</ddcme:parameters>
</ddcme:entityDialog>
</facets>
The available attributes of the tag are equivalent to using the EntityDialogs
API for the most part, except for a couple of options.
There are two ways on how to invoke the entity dialog screen. It is either possible to connect it declarative to an action / button
via references in XML or alternative the EntityDialogFacet
instance can be injected and opened programmatically.
The attributes onAction
/ onButton
are used to reference an action / button, where the input dialog is displayed.
In case the action is performed via a button e.g. the Entity Dialog is opened without any programmatic definition required.
<ddcme:entityDialog
id="createLaptopDialog"
entityClass="de.diedavids.cuba.metadataextensions.entity.example.Product"
onAction="createLaptop">
When programmatic invocation of the Entity Dialog is required, it is also possible to do that. In this case, a reference of the Facet can be injected into the screen:
public class ProductBrowse extends StandardLookup<Product> {
@Inject
protected EntityDialogFacet createLaptopDialog;
@Subscribe
protected void onAfterShow(AfterShowEvent event) {
createLaptopDialog.show();
}
}
In order to provide an entity that this entityDialog should be bound to, it is possible to define a method in the controller, that provides this instance:
public class ProductBrowse extends StandardLookup<Product> {
// ...
@Install(to = "createLaptopDialog", subject = "entityProvider")
protected Product laptopProductEntityProvider() {
newLaptopProduct = metadata.create(Product.class);
newLaptopProduct.setType(ProductType.LAPTOP);
return newLaptopProduct;
}
}
Via the @Install
annotation the reference to the createLaptopDialog
facet is created. The subject entityProvider
indicates
the extension point for defining the entity instance.
In order to receive the results of the Entity Dialog, a Close Listener has to be registered in the controller:
public class ProductBrowse extends StandardLookup<Product> {
@Subscribe("createLaptopDialog")
public void onInputDialogClose(EntityDialogFacet.CloseEvent closeEvent) {
// closeEvent.getValues() contains the entered values
// in case the reference was kept in the controller and autoBinding is set,
// newLaptopProduct already contains all bound values
}
}
The de.diedavids.cuba.metadataextensions.dataprovider.EntityDataProvider
interface provides
some convenient methods to get information about Entities and its entity attributes.
It consists of the following APIs:
entitiesLookupFieldOptions
entityAttributesLookupFieldOptions
businessEntityAttributes
Those methods allow to get Entity (attributes) in various forms.
This API is a combination of the already existing Metadata
, MetadataTools
and MessageTools
APIs of CUBA.
The metadata storage facilities for entities allow to easily reference meta classes and meta properties in an entity. A common use-case for that is configuration entities that store a particular information on a per-entity(-attribute) basis.
An example is an DefaultValueConfiguration
Entity which stores default values for entity attributes.
Those default values should be assigned to a new instance of the entity when it is created. In order to store this
default value, it also has to reference the particular entity attribute for which this default value is defined.
This application component helps creating those kinds of entities by providing the following pieces:
There are two JPA entities defined as mapped superclasses that can be extended in the application entity:
EntityAwareStandardEntity
- Base class for Entities that reference a specific entityEntityAttributeAwareStandardEntity
- Base class for Entities that reference a specific entity attribute
The entities pre populated attributes for storing a MetaClass (attribute: entity
) and a MetaProperty (attribute: entityAttribute
).
Those mapped superclasses extend CUBAs StandardEntity
. In case the StandardEntity
is not applicable in the target
application (e.g. because no soft-delete is required), the corresponding interfaces EntityAware
& EntityAttributeAware
can be leveraged.
The application components provides support for defining both CUBA metadata interfaces directly as a datatype in a JPA entity:
de.diedavids.cuba.metadataextensions.datatype.MetaClassDatatype
: allows to usecom.haulmont.chile.core.model.MetaClass
directly as a datatypede.diedavids.cuba.metadataextensions.datatype.MetaPropertyDatatype
: allows to usecom.haulmont.chile.core.model.MetaProperty
directly as a datatype
de.diedavids.cuba.metadataextensions.converter.MetaClassConverter
: allows to convert acom.haulmont.chile.core.model.MetaClass
to a column in the databasede.diedavids.cuba.metadataextensions.converter.MetaPropertyConverter
: allows to usecom.haulmont.chile.core.model.MetaProperty
to a column in the database
Sometimes it is necessary to have an Entity that represents a MetaClass. This is useful when e.g. a list of all existing
MetaClasses in the application should be rendered. For this use-case this application component contains the entity
de.diedavids.cuba.metadataextensions.entity.MetaClassEntity
that serves that purpose.