Difference between revisions of "DTO DSL"

From OS.bee documentation
Jump to: navigation, search
(DTO)
(DTO)
 
(37 intermediate revisions by 2 users not shown)
Line 1: Line 1:
==Copyright Notice==
 
  
{{Copyright Notice}}
 
  
 
==Purpose==
 
==Purpose==
  
The '''DTO DSL''' facilitates the creation and handling of data transfer objects (DTOs) in order to carry data between processes. Communication between processes is usually done by calls to remote interfaces and services where each call is a computationally expensive and time-consuming operation. The use of DTOs that aggregate the data that would have been transferred separately reduces the number of calls that are necessary, thus speeding up the operation. Furthermore, DTOs are decoupled from the JPA, thus eliminating burdensome dependencies.
+
The DTO DSL facilitates the creation and handling of data transfer objects (DTOs) in order to transfer data between processes. Communication between processes is usually done by calls to remote interfaces and services, where each call is a computationally expensive and time-consuming operation. The use of DTOs that aggregate data that would have been transferred separately reduces the number of calls that are necessary, thus speeding up the data-transfer operation. Furthermore, DTOs are decoupled from the JPA, thus eliminating burdensome dependencies.
  
Using the '''DTO DSL''', it is easy to create DTOs and the mapper classes that link them to the respective persistence entities. Property change support is automatically included in order to have current data without direct dependencies on the persistence layer.
+
Using the DTO DSL, it is easy to create DTOs and the mapper classes that link them to the respective persistence entities. Property-change support is automatically included, in order to have current data without direct dependencies on the persistence layer.
  
 
==Overview==
 
==Overview==
  
 
The main semantic elements of the DTO DSL are the following:
 
The main semantic elements of the DTO DSL are the following:
* '''Package''' - the root element that contains all the other elements. A model can contain multiple packages.
+
* '''package''' - The root element that contains all the other elements. A model can contain multiple packages.
* '''Import''' declarations - used to import other DTO models or the entity model files that are covered by the DTOs.
+
* '''import''' declarations - Used to import other DTO models or the entity model files that are covered by the DTOs.
* '''Datatype''' declarations - a way to define datatypes that can be used (only within the package - private scope).
+
* '''datatype''' declarations - A way to define datatypes that can be used (only within the package - private scope).
* '''DTO''' - the model of a DTO that wraps an entity. It contains further elements such as properties and references. Appropriate mapper methods can be specified.
+
* '''DTO''' - The model of a DTO that wraps an entity. It contains further elements such as properties and references. Appropriate mapper methods can be specified.
* '''Property''' - a reference to an enum, a Java class or a “simple datatype" (as defined in the datatype declaration). Can be inherited from the wrapped entity and offers multiplicity.
+
* '''property''' - A reference to an enum, a Java class or a “simple datatype" (as defined in the datatype declaration). Can be inherited from the wrapped entity and offers multiplicity.
* '''Reference''' - a reference to another DTO. Can be inherited from the wrapped entity and offers multiplicity.
+
* '''reference''' - A reference to another DTO. Can be inherited from the wrapped entity and offers multiplicity.
* '''Operations''' - similar to Java methods. The Xbase expression language can be used to write high-level code.
+
* '''operation''' - Similar to Java methods. The Xbase expression language can be used to write high-level code.
* '''Comments''' can be added to all elements.
+
* '''comment''' - Can be added to all elements.
  
'''Caveat:''' In order to make use of the DTO DSL, one has to make sure that the OSBP builder is executed after the Xtext builder.
+
Note: In order to make use of the DTO DSL, one has to make sure that the OSBP builder is executed after the Xtext builder.
  
 
==DTO model files==
 
==DTO model files==
Line 31: Line 29:
 
===package===
 
===package===
 
<blockquote>
 
<blockquote>
Packages are the root element of the DTO DSL grammar. Everything is contained in a '''package''': Imports, datatypes, DTOs and enums have to be defined inside the package definition. One document can contain multiple packages with unique names.
+
Packages are the root element of the DTO DSL grammar. Everything is contained in a <code>package</code>;  imports, datatypes, DTOs and enums have to be defined within the package. One document can contain multiple packages with unique names.
  
The elements a package can contain are DTOs and enums. Additionally, a package allows import statements and the declaration of datatypes.
+
The elements a package can contain are DTOs and enums. Additionally, a package allows <code>import</code> statements and the declaration of datatypes.
 
[[File:Dto-01.png|right|frame|''Figure 1 - DTO model file - a package is the topmost element and contains other items.'']]
 
[[File:Dto-01.png|right|frame|''Figure 1 - DTO model file - a package is the topmost element and contains other items.'']]
 
   
 
   
Line 50: Line 48:
 
===import===
 
===import===
 
<blockquote>
 
<blockquote>
In order to wrap entities into DTOs, the DTO DSL has to reference entities defined in entity model files. Furthermore, it is possible to reference DTOs in other packages. The <code>import</code> statement is a way to address these elements by their fully qualified name.
+
In order to wrap entities into DTOs, the DTO DSL has to reference entities defined in entity model files. Furthermore, it is possible to reference DTOs in other packages. The <code>import</code> statement is a way to address these elements without having to use their fully qualified name.
  
Import statements allow the use of the <code>*</code>-wildcard.
+
Import statements allow the use of the '*' wildcard.
 
   
 
   
 
► '''Syntax:'''
 
► '''Syntax:'''
Line 69: Line 67:
 
===datatype===
 
===datatype===
 
<blockquote>
 
<blockquote>
The DTO DSL allows the definition of datatypes. These are translated by the inferrer into their standard Java presentation. The behaviour of the generator can be controlled by the datatype definitions.
+
The DTO DSL allows the definition of datatypes. These are translated by the inferrer into their standard Java presentation. The behavior of the generator can be controlled by the datatype definitions.
 
There are three types of datatype definitions:
 
There are three types of datatype definitions:
  
;jvmTypes: Datatpye definitons that map types to jvmTypes take the basic syntax of <br> <code>datatype <name> jvmType <type> as primitive;</code><br> Specifying datatypes in this manner uses an appropriate wrapper class in the generated Java code; adding the keyword <code>as primitive</code> enforces the use of primitive datatypes where applicable: <br><code>datatype foo jvmType Integer</code> compiles to an <code>Integer</code> whereas <br><code>datatype foo jvmType Integer as primitive</code> results in <code>int</code>.
+
;jvmTypes: Datatype definitons that map types to jvmTypes take the basic syntax of <br> <code>datatype <name> jvmType <type> as primitive;</code><br> Specifying datatypes in this manner uses an appropriate wrapper class in the generated Java code.<br> Adding the keywords <code>as primitive</code> enforces the use of primitive datatypes where applicable: <br><code>datatype foo jvmType Integer</code> compiles to an <code>Integer</code> whereas <br><code>datatype foo jvmType Integer as primitive</code> results in <code>int</code>.
  
 
;dateTypes: The datatypes for handling temporal information can be defined by the following statement:<br><code>datatype <name> datetype date|time|timestamp;</code><br>Datatypes that have been defined in this manner can be used as property variables in DTOs.
 
;dateTypes: The datatypes for handling temporal information can be defined by the following statement:<br><code>datatype <name> datetype date|time|timestamp;</code><br>Datatypes that have been defined in this manner can be used as property variables in DTOs.
Line 78: Line 76:
 
;blobs: Binary blobs can be handled by defining a datatype with the <code>as blob</code> keyword. The Java implementation of such a blob is a byte array.<br><code>datatype <name> as blob;</code>
 
;blobs: Binary blobs can be handled by defining a datatype with the <code>as blob</code> keyword. The Java implementation of such a blob is a byte array.<br><code>datatype <name> as blob;</code>
  
After import statements and datatype definitions, the content of the .dtos file is made up of DTO definitions.
+
After <code>import</code> statements and <code>datatype</code> definitions, the content of the .dtos file is made up of DTO definitions.
 
</blockquote>
 
</blockquote>
  
 
==DTO==
 
==DTO==
  
Data Type Objects ('''DTO''') are the most complex elements in the DTO DSL. A DTO wraps an '''entity''' defined in the [[Entity DSL]] and its properties and references into a single object used for communication purposes.
+
Data Transfer Objects ('''DTOs''') are the most complex elements in the DTO DSL. A DTO wraps an '''entity''' defined in the [[Entity DSL]] together with its properties and references into a single object used for communication purposes.
  
DTO are defined by name, properties, references and wrapper methods. A DTO normally does not implement business logic.
+
DTOs are defined by name, properties, references and wrapper methods. A DTO normally does not implement business logic.
  
 
For each DTO that is defined in a package, the DTO DSL automatically generates a Java DTO class and a corresponding mapper class that handles data transfer and conversion between DTO and entity.
 
For each DTO that is defined in a package, the DTO DSL automatically generates a Java DTO class and a corresponding mapper class that handles data transfer and conversion between DTO and entity.
Line 102: Line 100:
 
===extends===
 
===extends===
 
<blockquote>
 
<blockquote>
'''extends''' marks a DTO that is derived from another DTO. That means that the properties and references of the parent DTO are inherited.
+
<code>extends</code> marks a DTO that is derived from another DTO. That means that the properties and references of the parent DTO are inherited.
  
 
[[File:dto-04.png|center|frame|''Figure 4 - The <code>extends</code> keyword causes a Java subclass to be created for the DTO.'']]
 
[[File:dto-04.png|center|frame|''Figure 4 - The <code>extends</code> keyword causes a Java subclass to be created for the DTO.'']]
Line 110: Line 108:
 
===wraps===
 
===wraps===
 
<blockquote>
 
<blockquote>
'''wraps''' indicates the entity that is handled by the DTO. The entity has to be imported from the entity model file into the DTO package (for importing several entities, the use of the _*_-wildcard may be advisable).  
+
<code>wraps</code> indicates the entity that is handled by the DTO. The entity has to be imported from the entity model file into the DTO package (for importing several entities, the use of the '*' wildcard may be advisable).  
  
[[File:dto-05.png|center|frame|''Figure 4 - The <code>wraps</code> keyword links the DTO to its respective entity. Thus, properties and references of the entity are made available in the DTO (and can there be accessed via content assist).'']]
+
[[File:dto-05.png|center|frame|''Figure 4 - The <code>wraps</code> keyword links the DTO to its respective entity. Thus, properties and references of the entity are made available in the DTO (and can be accessed there via content assist).'']]
 
</blockquote>
 
</blockquote>
  
 
==Enums==
 
==Enums==
  
Enums are an abstraction above the Java enum. They compile to enum classes and can be used as properties in DTOs.
+
Enums are an abstraction of the Java enum. They compile to <code>enum</code> classes and can be used as properties in DTOs.
  
 
[[File:dto-06.png|center|frame|''Figure 6 - Defining enums allows using them as variables in DTOs.'']]
 
[[File:dto-06.png|center|frame|''Figure 6 - Defining enums allows using them as variables in DTOs.'']]
 
  
 
==Properties==
 
==Properties==
Line 132: Line 129:
 
The basic property. Defines a variable that can be used within the DTO. Appropriate getters and setters are created.
 
The basic property. Defines a variable that can be used within the DTO. Appropriate getters and setters are created.
  
[[File:dto-07.png|center|frame|''Figure 7 - Variables can be defined using the var keyword.'']]
+
[[File:dto-07.png|center|frame|''Figure 7 - Variables can be defined using the <code>var</code> keyword.'']]
 
</blockquote>
 
</blockquote>
  
Line 139: Line 136:
 
{{deprecated}}
 
{{deprecated}}
  
defines a field in the DTO for mapping an <code>id</code> property (used as primary key in the persistence layer). This keyword is deprecated. If no id is given, a warning is shown. Caution: ID autogeneration causes problems since the value is not set before the entity is persisted in the database, which can cause problems.  
+
Defines a field in the DTO for mapping an <code>id</code> property (used as a primary key in the persistence layer). This keyword is deprecated. If no <code>id</code> is given, a warning is shown. Caution: ID autogeneration causes problems, since the value is not set before the entity is persisted to the database, which can cause problems.  
  
 
'''It is advised to use the <code>uuid</code> keyword instead.'''
 
'''It is advised to use the <code>uuid</code> keyword instead.'''
  
[[File:dto-08.png|center|frame|''Figure 8 - Variables can be defined using the var keyword.'']]
+
[[File:dto-08.png|center|frame|''Figure 8 - Using the <code>id</code> property, "id" is defined as a unique key.'']]
 
</blockquote>
 
</blockquote>
  
 
===uuid===
 
===uuid===
 
<blockquote>
 
<blockquote>
creates a field for the mapping of Universally Unique IDs as primary keys. UUIDs have to be strings.  
+
Creates a field for the mapping of Universally Unique IDs as primary keys. UUIDs must be strings.  
  
[[File:dto-09.png|center|frame|''Figure 9 - By using the uuid keyword, eliablyunique IDs can be used as primary keys and mapped to a DTO.'']]
+
[[File:dto-09.png|center|frame|''Figure 9 - By using the <code>uuid</code> keyword, reliably unique IDs can be used as primary keys and mapped to a DTO.'']]
 
</blockquote>
 
</blockquote>
  
 
===version===
 
===version===
 
<blockquote>
 
<blockquote>
defines a field for mapping a version property used by the JPA-Compiler.  
+
Defines a field for mapping a version property used by the JPA Compiler.  
  
[[File:dto-10.png|center|frame|''Figure 10 - A version property can be mapped into a DTO by the <code>version</code> keyword.'']]
+
[[File:dto-10.png|center|frame|''Figure 10 - A version property can be mapped into a DTO by using the <code>version</code> keyword.'']]
 
</blockquote>
 
</blockquote>
  
 
===transient===
 
===transient===
 
<blockquote>
 
<blockquote>
marks the property to be transient. Transient properties are not mapped from the DTO to the entity and thus not persisted. Getter and setter methods are created.
+
Marks the property as <code>transient</code>. Transient properties are not mapped from the DTO to the entity and are thus not persisted. Getter and setter methods are created.
  
 
[[File:dto-11.png|center|frame|''Figure 11 - The <code>transient</code> keyword allows properties to be excluded from the mapping.'']]
 
[[File:dto-11.png|center|frame|''Figure 11 - The <code>transient</code> keyword allows properties to be excluded from the mapping.'']]
Line 169: Line 166:
 
===derived===
 
===derived===
 
<blockquote>
 
<blockquote>
marks the property to be derived from other values. The logic used in the derivation process may be specified using Xbase. Derived properties are not persisted and only a getter is created.
+
Marks the property as being derived from other values. The logic used in the derivation process may be specified using Xbase. Derived properties are not persisted, and only a getter is created.
  
[[File:dto-12.png|center|frame|''Figure 12 - The <code>derived</code> keyword marks properties that are based on other values and computed at runtime. The calculation logic is translated to Java. Derived properties are excluded from the mapping.'']]
+
[[File:dto-12.png|center|frame|''Figure 12 - The <code>derived</code> keyword marks properties that are based on other values and are computed at runtime. The calculation logic is translated to Java. Derived properties are excluded from the mapping.'']]
 
</blockquote>
 
</blockquote>
  
 
==References==
 
==References==
  
The DTO DSL tracks relationships between DTOs by using the concept of references. Where appropriate, back references <code>opposite</code> can be added.
+
The DTO DSL tracks relationships between DTOs by using the concept of references. Where appropriate, reverse references can be created using the <code>opposite</code> property.
  
 
References are defined by the <code>ref</code> keyword, a type and a name. The exact type of reference can be specified as follows:
 
References are defined by the <code>ref</code> keyword, a type and a name. The exact type of reference can be specified as follows:
  
*'''Multiplicity and nullability''': The DTO DSL supports the specification of multiplicities in square brackets appended to the type:
+
*'''multiplicity and nullability''': The DTO DSL supports the specification of multiplicities in square brackets appended to the type:
**<code>[1]</code> defines a non-nullable one-to-one relationship.
+
**<code>[1]</code> defines a non-nullable, one-to-one relationship.
**<code>[0..1]</code> defines a nullable one-to-one relationship (Default behavior).
+
**<code>[0..1]</code> defines a nullable, one-to-one relationship (this is the default behavior).
**<code>[1..*]</code> defines a non-nullable one-to-many relationship. Needs an opposite reference.
+
**<code>[1..*]</code> defines a non-nullable, one-to-many relationship. An <code>opposite</code> reference is required.
**<code>[0..*]</code> or simply <code>[*]</code> defines a nullable one-to-many relationship. Needs an opposite reference.
+
**<code>[0..*]</code>, or simply <code>[*]</code>, defines a nullable, one-to-many relationship. An <code>opposite</code> reference is required.
*'''opposite reference''': In the [[Entity DSL]], lifecycle references between entities need the specification of an opposite reference in order to navigate back to the original object after following the reference. The DTO DSL includes a mechanism to map such references using the opposite keyword.
+
*'''opposite reference''': In the [[Entity DSL]], lifecycle references between entities need the specification of an <code>opposite</code> reference in order to navigate back to the original object after following the reference. The DTO DSL includes a mechanism to map such references using the <code>opposite</code> keyword.
*'''cascade''': The cascade specifier controls the behaviour of the database on delete operations. In the DTO DSL, these cascading references can be mapped to DTOs by the same keyword.
+
*'''cascade''': The cascade specifier controls the behavior of the database on delete operations. If <code>cascade</code> is specified, dependent records are also deleted. In the DTO DSL, these cascading references can be mapped to DTOs by the same keyword.
  
[[File:dto-13.png|center|frame|''Figure 13 - An example of two DTOs referencing each other. The second DTO aps a cascading non-nullable to-many reference.'']]
+
[[File:dto-13.png|center|frame|''Figure 13 - An example of two DTOs referencing each other. The second DTO maps a cascading, non-nullable, one-to-many reference.'']]
  
 
==Inherited Features==
 
==Inherited Features==
Line 196: Line 193:
 
There are two types of inherited features: inherited properties and inherited references.
 
There are two types of inherited features: inherited properties and inherited references.
  
Inherited features are defined by the <code>inherit</code> keyword followed by the feature type and the name of the feature in the entity. After that, the DTO a referenced entity or an embedded bean is mapped to may be specified using the <code>mapto</code> keyword.
+
Inherited features are defined by the <code>inherit</code> keyword followed by the feature type and the name of the feature in the entity. After that, the DTO to which a referenced entity or an embedded bean is mapped may be specified using the <code>mapto</code> keyword.
 
Finally, custom mapper directives may be specified (see [[#Custom Mappers|Custom Mappers]]).
 
Finally, custom mapper directives may be specified (see [[#Custom Mappers|Custom Mappers]]).
 
*'''inherit var''': used for mapping entity properties to DTO properties
 
*'''inherit var''': used for mapping entity properties to DTO properties
Line 207: Line 204:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
[[File:dto-14.png|center|frame|''Figure 14 - The <code>inherit</code> var keyword is used to map entity properties to DTO properties. Content assist is available. The mapto keyword specifies which DTO an embedded bean is mapped to.'']]
+
[[File:dto-14.png|center|frame|''Figure 14 - The <code>inherit</code> var keyword is used to map entity properties to DTO properties. Content assist is available. The <code>mapto</code> keyword specifies which DTO an embedded bean is mapped to.'']]
  
 
<br>
 
<br>
  
[[File:dto-15.png|center|frame|''Figure 15 - The <code>inherit ref</code> keyword allows for mapping entity references to DTO references. Content assist is available, and multiplicities and opposite references are automatically carried over from the entity model file. The <code>mapto</code> keyword indicates the DTO that serves as the other end of the reference.'']]
+
[[File:dto-15.png|center|frame|''Figure 15 - The <code>inherit ref</code> keywords allow for mapping entity references to DTO references. Content assist is available, and multiplicities and opposite references are automatically carried over from the entity model file. The <code>mapto</code> keyword indicates the DTO that serves as the other end of the reference.'']]
  
 
==Custom Mappers==
 
==Custom Mappers==
  
The DTO DSL provides a mechanism for creating custom mappers between DTOs and entities. These can be defined after the declaration of a property or reference and control the information exchange for the respective feature.
+
The DTO DSL provides a mechanism for creating custom mappers between DTOs and entities. These can be defined after the declaration of a property or reference, and they control the information exchange for the respective feature.
  
In order to create a custom mapper, the <code>toDTO</code> and <code>fromDTO</code> keywords are used, followed by the mapper definition in curly braces. <code>toDTO</code> controls the flow of information from entity to DTO, <code>fromDTO</code> vice versa. Within the curly braces, the special words in and out may be used to reference source and destination of the mapping.
+
In order to create a custom mapper, the <code>toDTO</code> and <code>fromDTO</code> keywords are used, followed by the mapper definition in curly braces. <code>toDTO</code> controls the flow of information from entity to DTO, <code>fromDTO</code> vice versa. Within the curly braces, the special words <code>in</code> and <code>out</code> may be used to reference the source and destination of the mapping.
  
 
► Syntax:
 
► Syntax:
Line 232: Line 229:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
[[File:dto-16.png|center|frame|''Figure 16 - The <code>toDto</code> section creates a custom mapping from entity to DTO: First a local variable <code>ArrayList</code> is created, then an InfoDetail with a disclaimer is added to each entry. The <code>in</code> keyword is used to reference the entity for the iteration.'']]
+
[[File:dto-16.png|center|frame|''Figure 16 - The <code>toDto</code> section creates a custom mapping from entity to DTO: First, a local variable <code>ArrayList</code> is created, then an InfoDetail with a disclaimer is added to each entry. The <code>in</code> keyword is used to reference the entity for the iteration.'']]
  
 
==Operations==
 
==Operations==
  
The DTO DSL supports the declaration of operations that can be performed within the DTOs. These operations are based on Xbase and offer a huge set of semantic features, extending the featureset of Java. Xbase additionally offers features like closures. When using operations, bear in mind that it is no good practice to implement business logic within DTOs. Operations can be declared by the <code>def</code> keyword followed by braces containing the inlined operation.
+
The DTO DSL supports the declaration of operations that can be performed within the DTOs. These operations are based on Xbase and offer a huge set of semantic features, extending the featureset of Java. Xbase additionally offers features like closures. When using operations, bear in mind that it is not good practice to implement business logic within DTOs. Operations can be declared by the <code>def</code> keyword followed by braces containing the inline operation.
  
 
► Syntax:
 
► Syntax:
Line 246: Line 243:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
[[File:dto-17.png|center|frame|''Figure 17 - The <code>def</code> keyword allows the inlining of custom methods in the DTO DSL code. These methods are translated to the appropriate Java methods.'']]
+
[[File:dto-17.png|center|frame|''Figure 17 - The <code>def</code> keyword allows the inlining of custom methods in the DTO DSL code. These methods are translated into the appropriate Java methods.'']]
  
 
==Comments==
 
==Comments==
Line 253: Line 250:
  
  
[[File:dto-18.png|center|frame|''Figure 18 - The comments added in the DTO DSL are transformed to Java-style comments in the generated code.'']]
+
[[File:dto-18.png|center|frame|''Figure 18 - The comments added in the DTO DSL are transformed into Java-style comments in the generated code.'']]
  
 
Comments before the <code>package</code> keyword are copied over to all generated Java classes - this is the place for copyright notices.
 
Comments before the <code>package</code> keyword are copied over to all generated Java classes - this is the place for copyright notices.
  
 
[[File:dto-19.png|center|frame|''Figure 19 - A comment before the <code>package</code> keyword ends up in all generated Java classes (DTO and mapper classes).'']]
 
[[File:dto-19.png|center|frame|''Figure 19 - A comment before the <code>package</code> keyword ends up in all generated Java classes (DTO and mapper classes).'']]
 +
==Copyright Notice==
 +
 +
{{Copyright Notice}}

Latest revision as of 08:32, 5 July 2017


Purpose

The DTO DSL facilitates the creation and handling of data transfer objects (DTOs) in order to transfer data between processes. Communication between processes is usually done by calls to remote interfaces and services, where each call is a computationally expensive and time-consuming operation. The use of DTOs that aggregate data that would have been transferred separately reduces the number of calls that are necessary, thus speeding up the data-transfer operation. Furthermore, DTOs are decoupled from the JPA, thus eliminating burdensome dependencies.

Using the DTO DSL, it is easy to create DTOs and the mapper classes that link them to the respective persistence entities. Property-change support is automatically included, in order to have current data without direct dependencies on the persistence layer.

Overview

The main semantic elements of the DTO DSL are the following:

  • package - The root element that contains all the other elements. A model can contain multiple packages.
  • import declarations - Used to import other DTO models or the entity model files that are covered by the DTOs.
  • datatype declarations - A way to define datatypes that can be used (only within the package - private scope).
  • DTO - The model of a DTO that wraps an entity. It contains further elements such as properties and references. Appropriate mapper methods can be specified.
  • property - A reference to an enum, a Java class or a “simple datatype" (as defined in the datatype declaration). Can be inherited from the wrapped entity and offers multiplicity.
  • reference - A reference to another DTO. Can be inherited from the wrapped entity and offers multiplicity.
  • operation - Similar to Java methods. The Xbase expression language can be used to write high-level code.
  • comment - Can be added to all elements.

► Note: In order to make use of the DTO DSL, one has to make sure that the OSBP builder is executed after the Xtext builder.

DTO model files

DTO models are described in .dtos files. These files describe the DTO model and are the basis for the code generation. DTO models may be split over several .dtos files containing packages in the same namespace.

A .dtos file may contain several packages with DTOs.

package

Packages are the root element of the DTO DSL grammar. Everything is contained in a package; imports, datatypes, DTOs and enums have to be defined within the package. One document can contain multiple packages with unique names.

The elements a package can contain are DTOs and enums. Additionally, a package allows import statements and the declaration of datatypes.

Figure 1 - DTO model file - a package is the topmost element and contains other items.

Syntax:

 package name {
    import importStatement;
    datatype datatypeDefinition;
    DTOs
 }

import

In order to wrap entities into DTOs, the DTO DSL has to reference entities defined in entity model files. Furthermore, it is possible to reference DTOs in other packages. The import statement is a way to address these elements without having to use their fully qualified name.

Import statements allow the use of the '*' wildcard.

Syntax:

package name {
    import importStatement;
    datatype datatypeDefinition;
    DTOs
}
Figure 2 - Items contained in another package can be accessed and handled if the package is imported.

datatype

The DTO DSL allows the definition of datatypes. These are translated by the inferrer into their standard Java presentation. The behavior of the generator can be controlled by the datatype definitions. There are three types of datatype definitions:

jvmTypes
Datatype definitons that map types to jvmTypes take the basic syntax of
datatype <name> jvmType <type> as primitive;
Specifying datatypes in this manner uses an appropriate wrapper class in the generated Java code.
Adding the keywords as primitive enforces the use of primitive datatypes where applicable:
datatype foo jvmType Integer compiles to an Integer whereas
datatype foo jvmType Integer as primitive results in int.
dateTypes
The datatypes for handling temporal information can be defined by the following statement:
datatype <name> datetype date|time|timestamp;
Datatypes that have been defined in this manner can be used as property variables in DTOs.
blobs
Binary blobs can be handled by defining a datatype with the as blob keyword. The Java implementation of such a blob is a byte array.
datatype <name> as blob;

After import statements and datatype definitions, the content of the .dtos file is made up of DTO definitions.

DTO

Data Transfer Objects (DTOs) are the most complex elements in the DTO DSL. A DTO wraps an entity defined in the Entity DSL together with its properties and references into a single object used for communication purposes.

DTOs are defined by name, properties, references and wrapper methods. A DTO normally does not implement business logic.

For each DTO that is defined in a package, the DTO DSL automatically generates a Java DTO class and a corresponding mapper class that handles data transfer and conversion between DTO and entity.

Syntax:

abstract dto <name> extends <parentDto> wraps <entityName> {
    dtoFeatures
}
Figure 3 - The defined DTO is translated to a Java class and an appropriate mapper class.


extends

extends marks a DTO that is derived from another DTO. That means that the properties and references of the parent DTO are inherited.

File:Dto-04.png
Figure 4 - The extends keyword causes a Java subclass to be created for the DTO.

wraps

wraps indicates the entity that is handled by the DTO. The entity has to be imported from the entity model file into the DTO package (for importing several entities, the use of the '*' wildcard may be advisable).

Figure 4 - The wraps keyword links the DTO to its respective entity. Thus, properties and references of the entity are made available in the DTO (and can be accessed there via content assist).

Enums

Enums are an abstraction of the Java enum. They compile to enum classes and can be used as properties in DTOs.

Figure 6 - Defining enums allows using them as variables in DTOs.

Properties

Properties of DTOs are references to datatypes or enums. They can be regarded as variables and are defined by a keyword followed by a datatype (Java type or datatype defined in the datatype section) and a name.

Properties can be determined with the following keywords:

var

The basic property. Defines a variable that can be used within the DTO. Appropriate getters and setters are created.

Figure 7 - Variables can be defined using the var keyword.

id


-- deprecated -- deprecated -- deprecated -- deprecated -- deprecated -- deprecated -- deprecated -- deprecated --

Defines a field in the DTO for mapping an id property (used as a primary key in the persistence layer). This keyword is deprecated. If no id is given, a warning is shown. Caution: ID autogeneration causes problems, since the value is not set before the entity is persisted to the database, which can cause problems.

It is advised to use the uuid keyword instead.

Figure 8 - Using the id property, "id" is defined as a unique key.

uuid

Creates a field for the mapping of Universally Unique IDs as primary keys. UUIDs must be strings.

Figure 9 - By using the uuid keyword, reliably unique IDs can be used as primary keys and mapped to a DTO.

version

Defines a field for mapping a version property used by the JPA Compiler.

Figure 10 - A version property can be mapped into a DTO by using the version keyword.

transient

Marks the property as transient. Transient properties are not mapped from the DTO to the entity and are thus not persisted. Getter and setter methods are created.

Figure 11 - The transient keyword allows properties to be excluded from the mapping.

derived

Marks the property as being derived from other values. The logic used in the derivation process may be specified using Xbase. Derived properties are not persisted, and only a getter is created.

Figure 12 - The derived keyword marks properties that are based on other values and are computed at runtime. The calculation logic is translated to Java. Derived properties are excluded from the mapping.

References

The DTO DSL tracks relationships between DTOs by using the concept of references. Where appropriate, reverse references can be created using the opposite property.

References are defined by the ref keyword, a type and a name. The exact type of reference can be specified as follows:

  • multiplicity and nullability: The DTO DSL supports the specification of multiplicities in square brackets appended to the type:
    • [1] defines a non-nullable, one-to-one relationship.
    • [0..1] defines a nullable, one-to-one relationship (this is the default behavior).
    • [1..*] defines a non-nullable, one-to-many relationship. An opposite reference is required.
    • [0..*], or simply [*], defines a nullable, one-to-many relationship. An opposite reference is required.
  • opposite reference: In the Entity DSL, lifecycle references between entities need the specification of an opposite reference in order to navigate back to the original object after following the reference. The DTO DSL includes a mechanism to map such references using the opposite keyword.
  • cascade: The cascade specifier controls the behavior of the database on delete operations. If cascade is specified, dependent records are also deleted. In the DTO DSL, these cascading references can be mapped to DTOs by the same keyword.
Figure 13 - An example of two DTOs referencing each other. The second DTO maps a cascading, non-nullable, one-to-many reference.

Inherited Features

Inherited properties and references are the core of the DTO DSL. They provide the mechanism for mapping entities and their features to the respective DTOs and their features.

There are two types of inherited features: inherited properties and inherited references.

Inherited features are defined by the inherit keyword followed by the feature type and the name of the feature in the entity. After that, the DTO to which a referenced entity or an embedded bean is mapped may be specified using the mapto keyword. Finally, custom mapper directives may be specified (see Custom Mappers).

  • inherit var: used for mapping entity properties to DTO properties
  • inherit ref: used for mapping entity references to DTO references
  • mapto: defines the DTO the feature should be mapped to. In the case of inherit var, this keyword is used to point to a DTO that maps a bean from the entity model file. In the case of inherit ref, a DTO must be specified that the reference points to.

► Syntax:

inherit var|ref entityFeature mapto dtoName {customMapper} ;
Figure 14 - The inherit var keyword is used to map entity properties to DTO properties. Content assist is available. The mapto keyword specifies which DTO an embedded bean is mapped to.


Figure 15 - The inherit ref keywords allow for mapping entity references to DTO references. Content assist is available, and multiplicities and opposite references are automatically carried over from the entity model file. The mapto keyword indicates the DTO that serves as the other end of the reference.

Custom Mappers

The DTO DSL provides a mechanism for creating custom mappers between DTOs and entities. These can be defined after the declaration of a property or reference, and they control the information exchange for the respective feature.

In order to create a custom mapper, the toDTO and fromDTO keywords are used, followed by the mapper definition in curly braces. toDTO controls the flow of information from entity to DTO, fromDTO vice versa. Within the curly braces, the special words in and out may be used to reference the source and destination of the mapping.

► Syntax:

inherit var|ref <entityFeature> mapto <dtoName> {
    toDto {
        XbaseDirectives
    }
    fromDto {
        XbaseDirectives
    }
}
Figure 16 - The toDto section creates a custom mapping from entity to DTO: First, a local variable ArrayList is created, then an InfoDetail with a disclaimer is added to each entry. The in keyword is used to reference the entity for the iteration.

Operations

The DTO DSL supports the declaration of operations that can be performed within the DTOs. These operations are based on Xbase and offer a huge set of semantic features, extending the featureset of Java. Xbase additionally offers features like closures. When using operations, bear in mind that it is not good practice to implement business logic within DTOs. Operations can be declared by the def keyword followed by braces containing the inline operation.

► Syntax:

def returnType operationName() {
    XbaseDirectives
}
Figure 17 - The def keyword allows the inlining of custom methods in the DTO DSL code. These methods are translated into the appropriate Java methods.

Comments

Comments can be added anywhere in a .dtos text file and are copied over into the generated Java code. Comments are enclosed in /* ... */.


Figure 18 - The comments added in the DTO DSL are transformed into Java-style comments in the generated code.

Comments before the package keyword are copied over to all generated Java classes - this is the place for copyright notices.

Figure 19 - A comment before the package keyword ends up in all generated Java classes (DTO and mapper classes).

Copyright Notice

All rights are reserved by Compex Systemhaus GmbH. In particular, duplications, translations, microfilming, saving and processing in electronic systems are protected by copyright. Use of this manual is only authorized with the permission of Compex Systemhaus GmbH. Infringements of the law shall be punished in accordance with civil and penal laws. We have taken utmost care in putting together texts and images. Nevertheless, the possibility of errors cannot be completely ruled out. The Figures and information in this manual are only given as approximations unless expressly indicated as binding. Amendments to the manual due to amendments to the standard software remain reserved. Please note that the latest amendments to the manual can be accessed through our helpdesk at any time. The contractually agreed regulations of the licensing and maintenance of the standard software shall apply with regard to liability for any errors in the documentation. Guarantees, particularly guarantees of quality or durability can only be assumed for the manual insofar as its quality or durability are expressly stipulated as guaranteed. If you would like to make a suggestion, the Compex Team would be very pleased to hear from you.

(c) 2016-2024 Compex Systemhaus GmbH