Creating Expansion Modules
The purpose of this case is to create Data Transfer Objects, encapsulating data in Value Objects so they can be transferred over the network. These can be seen as a variation of, or being similar to, the existing data projections. However, they:
- cannot contain link fields or DataRef’s, as they should be value objects
- may contain nested value fields and objects
The development consolidates work that has been done in the Haacht project. There, custom add-on expanders were created to realize this possibility. Though the essential logic exists, it remains an endeavor to integrate it into the NS Expanders / Prime Radiant.
We consider this as the creation of a functional module Transfer Projections in the NS Expanders - Prime Radiant framework. In order to master the complexity, we distinguish three steps.
- Introduce the expansion of a single default transfer projection, and let nsx-prime insert this into the expanders control model.
- introduce a realistic meta-model for the transfer projections in the Prime Radiant, and pass it through elementsio to nsx-prime.
- Enrich the control model and implementation of the transfer projections in the expanders and connect it to the meta-model in nsx-prime.
1. A single transfer projection
Extension of control model
First, we have to provide an expander control structure for a data transfer projection.
- Create a TransferProjectionDescriptor, similar to n.d.descriptor.ProjectionDescriptor.
- Embed this descriptor in a context class as well: n.d.context.TransferProjectionExpansionContext.
- Provide a method createSimpleTransferProjection in the existing n.d.de.helper.ProjectionBuilder.
- Optionally, you could already embed this in a larger method createDefaultTransferProjections.
- Provide get/setTransferProjections methods to encapsulate them in n.d.descriptor.DataDescriptor.
- Provide getTransferProjections method in n.d.model.ComponentModel to retrieve over entire component.
Now, it becomes possible for nsx-prime to insert a single default projection for every data element. In order to do this, the n.d.elements.ModelFromDataElementClient in nsx-prime needs to create the default transfer projection using the ProjectionBuilder, and to set it in the DataDescriptor. It is here in the ModelFromDataElementClient that we will introduce in a second phase additional data transfer projections as defined by the meta-model.
Implementation and activation
The actual implementation of an new expander artifact to expand this single transfer projection, requires a coherent pair of artifacts:
- A Java expander class n.d.de.common.ProjectionExpander.java
- A String template group n.d.de.common.ProjectionExpander.stg
This expander n.d.de.common.ProjectionExpander needs to be declared as part of a new group of expander classes, called transferProjectionExpanders in the config file n.d.expansion.config.default_expanders.yaml. In order to make this expander artifact, the first of a new module, available for expansion, we also need to implement:
- Expander access methods get/setTransferProjectionExpanders in n.d.expansion.config.ExpanderClassEnumeration
- An expander configuration class n.d.de.expansion.TransferProjectionExpansionConfigurator
- A total expander class n.d..de.common.TransferProjectionTotalExpander to call all expanders of the group.
Now, we are finally ready to introduce the transfer projections in the n.d.model.FullComponentExpander by:
- Retrieving all transfer projections from the component using ComponentModel.getTransferProjections
- passing every one of those transfer projections to the n.d..de.common.TransferProjectionTotalExpander
2. Extending the meta-model
As explained, the extension of the meta-model requires coherent modifications in the various repositories.
- data element ‘DataTransferProjection’ next to ‘DataProjection’
- type Full/Simple/Custom ~ details/info
- Ln01 dataElement
- Ln05 valueTransferFields
- Ln05 calculatedTransferFields
- data element ‘ValueTransferField’
- Ln01 dataElement
- Ln01 dataTransferProjection
- Ln01 field
- data element ‘CalculatedTransferField’
- Ln01 dataTransferProjection
- Ln01 valueFieldType
For every of the three new data element provide XML import/export using
These require the regeneration of the Prime Radiant / elements component first, because they depend on the ElemDetails classes.
3. Enrich expander implementation
Expander control model
If needed, enrich the classes in the expander control structure, for instance for meta-element DataTransferProjection
As mentioned before, the n.d.model.ElemModel classes are only required for top-level meta-elements.
Introduce expander classes similar to the existing DataProjection implementation.
Besides 4 view expanders, two Java code ‘Projection’ expanders exist:
- a specific interface n.d.de.common.IProjectionExpander
- an helper class n.d.de.common.ProjectionExpanderHelper to retrieve value type imports
- the above mentioned n.d.de.common.ProjectionTotalExpander to coordinate the expander set
- ProjectionExpander > TransferProjectionExpander
- IProjectionExpander > ITransferProjectionExpander
- ProjectionTotalExpander > TransferProjectionTotalExpander
- ProjectionExpanderHelper > TransferProjectionExpanderHelper
and in n.d.de.ejb3
- ProjectorExpander > TransferProjectorExpander
These expanders need to be added to the ‘default_expanders.yaml’
Provide String templates similar to those of ‘DataProjection’ and based on Haacht templates
- ProjectionExpander > TransferProjectionExpander based on DtoExtandatie
- ProjectorExpander > TransferProjectorExpander based on FetcherExtandatie