Intermediate Domain Model Specification
This page specifies the structure and semantics of the intermediate metamodel for LEMMA domain models. All obtained intermediate LEMMA domain models must conform to this metamodel to ensure consistent behavior of LEMMA model processors. The following figure shows the metamodel's structure:

The source code of the metamodel specification can be found at https://github.com/SeelabFhdo/lemma/blob/main/de.fhdo.lemma.data.intermediate.metamodel/model/IntermediateDataModel.xcore.
Each of the following sections describes certain concepts of the metamodel.
Note
Attributes that may contain more than one value but exhibit a *
multiplicity, i.e., they may contain an arbitrary number of values or even
none at all (*
is shorthand UML notation for 0..*
), are never null.
In case no multiplicity is stated after the object type of an attribute, the
attribute may be null. For example, an attribute defined as String name
implicitly has a multiplicity 0..1
and in the zero-case the String may be
null.
However, in case the attribute's type is a built-in primitive Java type,
e.g. int
, the attribute will never be null but exhibits the type's default
value in case it did not receive an explicit value.
Model Root
Class IntermediateDataModel
Root of an intermediate domain model.
String[1]
sourceModelUri
file://
URI pointing to the source domain model file from which this intermediate domain model was derived.
Note
Model processors must not depend on this URI being absolute or relative. Both cases may occur in practice and are up to the modeler.
IntermediateImport[*]
imports
References to the intermediate representations of imported domain models.
IntermediateVersion[*]
versions
Versions being defined in the source domain model.
IntermediateContext[*]
contexts
IntermediateComplexType[*]
complexTypes
IntermediateDataStructure
, IntermediateCollectionType
, and IntermediateEnumeration
, instances being defined in the source domain model. If a domain model has versions
or contexts
, it may not have complexTypes
under the model root. They are, instead, encapsulated within the versions
or contexts
attributes
Imports
LEMMA models and their elements may refer to each other. For instance, a service model may refer to domain-specific types defined in a domain model. This interlinkage of the different LEMMA model kinds and their elements is realized on the basis of an import mechanism. That is, a service model may import a domain model to enable the modeler to refer to modeled domain-specific types. However, certain model kinds also allow for importing instances of the same type. A domain model, for example, may import other domain models to use their data structures as types for the fields of its own structures.
Class IntermediateImport
Concept to represent the import of a domain model into the source domain model.
String[1]
name
Alias of the import. Unique within the same domain model.
String[1]
importUri
Unique file://
URI that points to the location of the intermediate representation of the imported domain model.
Note
Model processors must not depend on this URI being absolute or relative. Both cases may occur in practice and are up to the modeler.
String[1]
importTypeName
Name of the import type. For domain models, the value of this attribute is always "DATATYPES".
IntermediateDataModel[1]
dataModel
Link to the containing IntermediateDataModel
instance.
String[1]
getImportTypeNameForDatatypes
(
)
Helper that returns the name of the import type for domain-specific types. This method will always return the value "DATATYPES", which corresponds to the only possible value of the importTypeName
attribute.
Namespace Concepts
Namespace concepts allow for organizing a domain model. Conceptually, they correspond to Java's package mechanism.
Class IntermediateVersion
A namespace concept to organize evolved contents of a domain model in different versions.
String[1]
name
Name of the version. Unique within the same domain model.
IntermediateComplexType[*]
complexTypes
Complex types defined directly within the version.
IntermediateContext[*]
contexts
Contexts encapsulated by the version.
Note
For the same IntermediateVersion
, either the complexTypes
or the contexts
attribute will contain values but neither both.
IntermediateDataModel[1]
dataModel
Link to the containing IntermediateDataModel
instance.
Class IntermediateContext
A namespace concept to organize domain-specific types of a domain model in semantic domains that may correspond to Bounded Contexts.
String[1]
name
Name of the context. Unique within the same domain model or version.
String[1]
qualifiedName
Qualified name of the context. The qualified name of the context consists of the name of the version
, if any, and the name of the context separated by a dot. In case the context is not part of a version
, the qualifiedName
equals the context's name
.
Hint
The IntermedateVersion
class does not comprise a qualifiedName
attribute, because versions may not be contained within an instance of another model concept's class except for the nameless model root
.
IntermediateComplexType[1..*]
complexTypes
Complex types being defined within the context.
IntermediateDataModel
dataModel
Link to the containing IntermediateDataModel
instance.
IntermediateVersion
version
Link to the containing IntermediateVersion
instance.
Note
Only one of the attributes dataModel
or version
has a value, depending on whether the context is defined directly under the model root
or within a version
.
Note
Contexts may not be nested.
Built-in Type System
This subsection describes concepts that are part of LEMMA's built-in type system provided by the Domain Data Modeling Language. The type system is aligned to Java and contains all built-in Java primitive types as well as the native types date
, string
, and unspecified
.
Besides the unspecified
type, the type conversions observe Java's widening primitive conversions for primitively typed fields
. The unspecified
type, however, is not compatible with any other type. More precisely, two distinct fields with the unspecified
type are not considered to be compatible. That is, the unspecified
type communicates the intended current absence of a type, e.g., to determine that a typing decision has not been taken, yet.
Two data structures
are compatible, if their fields are compatible, independent of their type ordering. Two distinct enumerations
are compatible, if the value-receiving enumeration comprises all initialization values of the value-providing enumeration.
Enum IntermediateTypeKind
Enumeration to specify the kind of an IntermediateType
instance being referenced in some place.
COLLECTION
Referenced type is an IntermediateCollectionType
.
ENUMERATION
Referenced type is an IntermediateEnumeration
.
PRIMITIVE
Referenced type is an IntermediatePrimitiveType
.
STRUCTURE
Referenced type is an IntermediateDataStructure
.
Enum IntermediateTypeOrigin
Enumeration to specify the origin of an IntermediateType
instance being referenced in some place.
DATA_MODEL
Type is an IntermediateComplexType
defined in a domain model.
BUILTIN
Type is a built-in type.
TECHNOLOGY
Type is technology-specific. Technology-specific types may be used to map built-in primitive types to technology-specific types, e.g., float
to float32
in the Go programming language. Moreover, they may be used to declare technology-specific structure or collection types. Code generators need to be able to interpret technology-specific types that were defined in a LEMMA technology model.
Hint
Currently, the following combinations of IntermediateTypeKind
and IntermediateTypeOrigin
values are possible:
Kind | Origin |
---|---|
COLLECTION |
DATA_MODEL ,
TECHNOLOGY
|
ENUMERATION |
DATA_MODEL |
PRIMITIVE |
BUILTIN ,
TECHNOLOGY
|
STRUCTURE |
DATA_MODEL ,
TECHNOLOGY
|
Abstract Class IntermediateType
Abstract super class for all types.
String[1]
name
Name of the type.
IntermediateTypeOrigin[1]
origin
Origin of the type.
IntermediateTypeKind[1]
kind
Kind of the type.
IntermediateDataField[1]
dataField
Data field that is typed by this type's instance.
Class IntermediatePrimitiveType
: IntermediateType
Representation of a primitive type being used within the domain model.
Integer
size
Size of the primitive type in bits. The built-in primitive types have the following sizes:
Type | Size (in bits) |
---|---|
boolean |
1 |
byte |
8 |
char |
16 |
date |
null (object type) |
double |
64 |
float |
32 |
int |
32 |
long |
64 |
short |
16 |
string |
null (object type) |
unspecified |
null (communicates type absence) |
IntermediateDataField
initializedDataField
Link to the IntermediateDataField
, whose initialization value is compatible with this primitive type.
IntermediateEnumerationField
initializedEnumerationField
Link to the IntermediateEnumerationField
, whose initialization value is compatible with this primitive type.
Custom, Domain-Specific Types
Class IntermediateComplexType
: IntermediateType
Super class of complex types like IntermediateDataStructure
, IntermediateCollectionType
, and IntermediateEnumeration
.
String[1]
qualifiedName
IntermediateImportedAspect[*]
aspects
The aspects that were assigned to the complex type.
IntermediateDataModel
dataModel
Link to the containing IntermediateDataModel
instance.
IntermediateVersion
version
Link to the containing IntermediateVersion
instance.
IntermediateContext
context
Class IntermediateImportedComplexType
: IntermediateComplexType
This class represents an IntermediateComplexType
that has been imported from another domain model.
IntermediateImport
import
The import from which the complex type originates.
Class IntermediateDataStructure
: IntermediateComplexType
A domain-specific data structure that usually comprises a variety of typed fields.
String[*]
featureNames
This attribute contains the names of all features specified for the data structure. The following values are possible:
Feature Name | Description |
---|---|
"AGGREGATE" | Data structure is an Aggregate in the sense of Domain-driven Design (DDD). |
"APPLICATION_SERVICE" | Data structure is a Service with application focus in the sense of DDD. |
"DOMAIN_EVENT" | Data structure is a Domain Event in the sense of DDD. |
"DOMAIN_SERVICE" | Data structure is a Service with domain focus in the sense of DDD. |
"ENTITY" | Data structure is an Entity in the sense of DDD. |
"FACTORY" | Data structure is a Factory in the sense of DDD. |
"INFRASTRUCTURE_SERVICE" | Data structure is a Service with infrastructure focus in the sense of DDD. |
"REPOSITORY" | Data structure is a Repository in the sense of DDD. |
"SERVICE" | Data structure is a Service in the sense of DDD. |
"SPECIFICATION" | Data structure is a Specification in the sense of DDD. |
"VALUE_OBJECT" | Data structure is a Value Object in the sense of DDD. |
Note
DDD-related features should follow the constraints described here. LEMMA's Domain Data Modeling Language currently only issues warnings in case constraints are violated. Model processors are however free to deny functioning and yield errors in case they detect constraint violations.
IntermediateDataStructure
super
The super data structure from which this data structure inherits.
Note
LEMMA's Domain Data Modeling Language supports single inheritance only. Furthermore, the super data structure must be defined within the same domain model. It cannot be imported from another domain model.
IntermediateDataField[*]
dataFields
Data fields of the structure.
Hint
In case the data structure inherits from a super structure, the attribute also contains inherited, non-hidden fields. Inherited fields of a structure can be distinguished from "local" fields by means of the IntermediateDataField
concept's inherited
attribute.
IntermediateDataOperation[*]
operations
Operations of the structure.
Hint
In case the data structure inherits from a super structure, the attribute also contains inherited, non-hidden operations. Inherited operations of a structure can be distinguished from "local" operations by means of the IntermediateOperation
concept's inherited
attribute.
Class IntermediateDataOperation
An operation within an IntermediateDataStructure
.
String[1]
name
Name of the operation. Unique within the same structure.
String[1]
qualifiedName
Qualified name of the operation. Corresponds to the name of the operation prefixed by the qualified name of the defining IntermediateDataStructure
. The name fragments are separated by dots.
boolean
hidden
Flag to indicate if the operation is hidden. Semantically, this flag corresponds to Java's private
accessibility modifier. However, the flag differs in that an inherited operation may also be set to hidden. That is, operations' visibility may be overridden. A hidden operation is not visible in any of the following levels of the inheritance hierarchy.
boolean
inherited
Flag to indicate if the operation was inherited from a super structure.
String[*]
featureNames
This attribute contains the names of all features specified for the operation. The following values are possible:
Feature Name | Description |
---|---|
"CLOSURE" | Operation is a Closure in the sense of DDD. |
"IDENTIFIER" |
Operation acts as identifier for an Entity
in the sense of DDD (see also the
featureNames attribute of the IntermediateDataStructure concept).
|
"SIDE_EFFECT_FREE" | Operation is side-effect-free in the sense of DDD. |
"VALIDATOR" |
Operation acts as validator for a
Specification in the sense of DDD (see also
the
featureNames attribute of the IntermediateDataStructure concept).
|
Note
DDD-related features should follow the constraints described here. LEMMA's Domain Data Modeling Language currently only issues warnings in case constraints are violated. Model processors are however free to deny functioning and yield errors in case they detect constraint violations.
IntermediateDataOperationReturnType
returnType
The return type of the operation. This attribute is empty when no return type was specified.
IntermediateDataOperationParameter[*]
parameters
The parameters of the operation.
IntermediateImportedAspect[*]
aspects
The aspects that were assigned to the operation.
Class IntermediateDataOperationReturnType
The return type of an IntermediateDataOperation
.
IntermediateType[1]
type
The return type.
Hint
The attribute always holds a unique IntermediateType
instance , i.e., instances of the same types are not reused.
Hint
Model processors must use this type as the operation's return type and not the originalType
.
IntermediateType[1]
originalType
The original return type of the operation.
Hint
The attribute always holds a value. In case the value differs from that of the type
attribute, the return type got altered in a mapping model and the type
attribute attribute holds an instance of the IntermediateImportedTechnologySpecificType
concept that identifies the technology-specific type to which the original return type was mapped.
IntermediateImportedAspect[*]
aspects
The aspects that were assigned to the return type within a mapping model.
Class IntermediateDataOperationParameter
A parameter within an IntermediateDataOperation
.
String[1]
name
Name of the parameter. Unique within the same operation.
String[1]
qualifiedName
Qualified name of the parameter. Corresponds to the name of the parameter prefixed by the qualified name of the defining IntermediateDataOperation
. The name fragments are separated by dots.
IntermediateType[1]
type
The type of the parameter.
Hint
The attribute always holds a unique IntermediateType
instance , i.e., instances of the same types are not reused.
Hint
Model processors must use this type as the operation's return type and not the originalType
.
IntermediateType[1]
originalType
The original type of the parameter.
Hint
The attribute always holds a value. In case the value differs from that of the type
attribute, the type got altered in a mapping model and the type
attribute attribute holds an instance of the IntermediateImportedTechnologySpecificType
concept that identifies the technology-specific type to which the parameter's original type was mapped.
IntermediateImportedAspect[*]
aspects
The aspects that were assigned to the return type within a mapping model.
Class IntermediateDataField
A field within an IntermediateDataStructure
.
String[1]
name
Name of the field. Unique within the same structure or collection type.
String[1]
qualifiedName
Qualified name of the field. Corresponds to the name of the field prefixed by the qualified name of the defining IntermediateDataStructure
. The name fragments are separated by dots.
boolean
hidden
Flag to indicate if the field is hidden. Semantically, this flag corresponds to Java's private
accessibility modifier. However, the flag differs in that an inherited field may also be set to hidden. That is, fields' visibility may be overridden. A hidden field is not visible in any of the following levels of the inheritance hierarchy.
boolean
immutable
Flag to indicate whether the field is immutable or not. In Java, for example, an immutable field could correspond to a field that has no public setter.
boolean
inherited
Flag to indicate if the field was inherited from a super structure.
String[*]
featureNames
This attribute contains the names of all features specified for the field. The following values are possible:
Feature Name | Description |
---|---|
"IDENTIFIER" |
Field acts as identifier for an Entity in
the sense of DDD (see also the
featureNames attribute of the IntermediateDataStructure concept).
|
"NEVER_EMPTY" | Field should never be empty. |
"PART" |
Field is a part of a DDD Aggregate (see
also the
featureNames attribute of the IntermediateDataStructure concept).
|
Note
DDD-related features should follow the constraints described here. LEMMA's Domain Data Modeling Language currently only issues warnings in case constraints are violated. Model processors are however free to deny functioning and yield errors in case they detect constraint violations.
String
initializationValue
If the field has an initialization value, it is encoded in this attribute. It is guaranteed that the initialization value is compatible to all primitive types in the initializationValueCompatibleTypes
attribute.
Note
Only fields defined in data structures can receive an initialization value.
Note
A field with the built-in primitive type unspecified
cannot receive an initialization value.
IntermediatePrimitiveType[*]
initializationValueCompatibleTypes
If the field exhibits an initialization value, this attribute comprises all primitive types to which the initialization value is compatible.
Note
There is no determined order in which the primitive types appear in the attribute.
IntermediateType[1]
type
The type of the field.
Hint
The attribute always holds a unique IntermediateType
instance , i.e., instances of the same types are not reused.
Hint
Model processors must use this type as the field's type and not the originalType
.
IntermediateType[1]
originalType
The original type of the field.
Hint
The attribute always holds a value. In case the value differs from that of the type
attribute, the type got altered in a mapping model and the type
attribute attribute holds an instance of the IntermediateImportedTechnologySpecificType
concept that identifies the technology-specific type to which the field's original type was mapped.
IntermediateImportedAspect[*]
aspects
The aspects that were assigned to the field within a mapping model.
IntermediateDataStructure
dataStructure
Link to the defining IntermediateDataStructure
instance.
Class IntermediateCollectionType
: IntermediateComplexType
A domain-specific collection type.
boolean
primitiveCollection
Flag to indicate if this is a collection that contains a sequence of primitive values.
boolean
structuredCollection
Flag to indicate if this collection consists of one or more data fields.
Note
Exactly one of the flags primitiveCollection
or structuredCollection
will always be true
.
IntermediatePrimitiveType
primitiveType
In case the collection is a primitive collection, this attribute contains the IntermediatePrimitiveType
instance that identifies the primitive type of the collection's values.
IntermediateDataField[*]
dataFields
In case the collection is a structured collection, this attribute contains the IntermediateDataStructure
instances that prescribe the structure of the collection's values.
Class IntermediateEnumeration
: IntermediateComplexType
A domain-specific enumeration.
String[*]
featureNames
This attribute contains the names of all features specified for the enumeration. The following values are possible:
Feature Name | Description |
---|---|
"DOMAIN_EVENT" | Enumeration is a Domain Event in the sense of DDD. |
"VALUE_OBJECT" | Enumeration is a Value Object in the sense of DDD. |
Note
DDD-related features should follow the constraints described here. LEMMA's Domain Data Modeling Language currently only issues warnings in case constraints are violated. Model processors are however free to deny functioning and yield errors in case they detect constraint violations.
IntermediateEnumerationField[1..*]
fields
The fields of the enumeration.
Class IntermediateEnumerationField
A field of an IntermediateEnumeration
.
String[1]
name
Name of the field. Unique within the same enumeration.
String[1]
qualifiedName
Qualified name of the field. Corresponds to the name of the field prefixed by the qualified name of the defining IntermediateEnumeration
. The name fragments are separated by dots.
String
initializationValue
Initialization value of the field. It is guaranteed that the initialization value is compatible to all primitive types in the initializationValueCompatibleTypes
attribute.
IntermediatePrimitiveType[*]
initializationValueCompatibleTypes
If the field exhibits an initialization value, this attribute comprises all primitive types to which the initialization value is compatible.
Note
There is no determined order in which the primitive types appear in the attribute.
IntermediateEnumeration
enumeration
Link to the defining IntermediateEnumeration
instance.
Technologies
In the following, concepts for technology assignment, e.g., to complex types and intermediate concepts for constructs from other modeling languages such as IntermediateMicroservice
are described.
Class IntermediateImportedTechnologySpecificType
: IntermediateType
Intermediate representation of a type defined within a technology model.
String[1]
qualifiedName
Qualified name of the type. Consists of the name of the defining technology, the "_types" prefix as internal qualifier within the technology model, and the name of the type, separated by dots.
IntermediateImport[1]
import
The IntermediateImport
instance pointing to the technology model from which the type was imported.
Class IntermediateImportedAspect
Aspects allow semantic refinement of modeled complex types, operations, their parameters and return types, as well as fields. Next to domain-specific modeling concepts, aspects also target constructs from other LEMMA modeling languages and their intermediate representations, e.g., IntermediateMicroservice
and IntermediateOperationNode
.
Aspects are defined within technology models. An aspect definition might be accompanied with properties and have their applicability constrained to certain peculiarities of concept instances to which they apply. With this mechanism it is possible to create, e.g., aspects for the OR mapping of data structures or the specification of HTTP status codes returned by a microservice operation.
String[1]
name
Name of the aspect.
String[1]
qualifiedName
Qualified name of the aspect. Consists of the name of the defining technology, the "_aspects" prefix as internal qualifier within the technology model, and the name of the aspect, separated by dots.
String[*]
featureNames
This attribute contains the names of all features specified for the aspect. The following values are possible:
Feature Name | Description |
---|---|
"SINGE_VALUED" | Flag to indicate that an aspect may only be applied once at a target element. |
IntermediateImport[1]
import
The IntermediateImport
instance pointing to the technology model from which the type was imported.
IntermediateAspectProperty[*]
properties
Properties of the aspect as defined in its technology model.
IntermediateAspectPropertyValue[*]
propertyValues
Values for aspect properties as assigned in the aspect's application within the source model.
IntermediateComplexType
complexType
IntermediateComplexType
to which the aspect was applied.
IntermediateDataOperation
operation
IntermediateDataOperation
to which the aspect was applied.
IntermediateDataOperationParameter
parameter
IntermediateDataOperationParameter
to which the aspect was applied.
IntermediateDataField
dataField
IntermediateDataField
to which the aspect was applied.
Map<IntermediateAspectProperty, String>
getEffectivePropertyValues
(
)
Helper to return the effective property values for an aspect application. The effective property values consist of the default values for the aspect's properties and the property values specific to the aspect's application.
Class IntermediateAspectProperty
Specification of an aspect property.
String[1]
name
Name of the property. Unique within the same aspect.
String[1]
type
Name of the property's primitive type. The attribute can receive one of the following values:
- "boolean"
- "byte"
- "char"
- "date"
- "double"
- "float"
- "int"
- "long"
- "short"
- "string"
Note
A property cannot be of the built-in primitive type unspecified
.
String
defaultValue
This attribute encodes a possible default value of the property. It is guaranteed that this value fits the property's type.
String[*]
featureNames
This attribute contains the names of all features specified for the property. The following values are possible:
Feature Name | Description |
---|---|
"MANDATORY" | Flag to indicate that the property needs to receive a value. It is guaranteed that all mandatory properties receive a value during the application of the respective aspect. |
"SINGE_VALUED" | Flag to indicate that a property may only receive a value once. It is guaranteed that all single-valued properties receive at most one value during the application of the respective aspect. |
IntermediateImportedAspect
aspect
The aspect to which the property belongs.
Class IntermediateAspectPropertyValue
Value of an IntermediateAspectProperty
.
String[1]
value
The value encoded as a String.
IntermediateAspectProperty[1]
property
The aspect property for which the value was specified.
IntermediateImportedAspect
aspect
The aspect application to which the property value belongs.