A metamodel defines the structural properties of the concepts to work with.
For this task Essential provides Essential.Meta: an object-oriented Domain Specific Language (DSL) to create metamodels.
A brief introduction to its syntax follows:
namespace Sample.Metamodel { class Project : Plan { string Name; string? Description; List<Milestone> 0..* Milestones; } class Milestone { string Name; string? Date; } }
The primitives of the Essential metamodeling language are described here:
A namespace defines a naming scope where definitions like classes and enumerations can be contained for further references. Namespaces like UML packages, helps to organize the concepts when them increase in numbers.
A class defines a concept in your modeling language for further instanciation in models. Each class contains properties and can participate in relations with others classes. Sample:
class Customer { string Name; string Surname; string? Email; List<Order> Orders; }
Allows the extension of types based in other definitions. Avoid circular inheritance, please.
class Person { string Name; string Surname; string? Email; } class Customer : Person { List<Order> Orders; }
Multiple inheritance is under consideration.
Enumerations are also allowed in the metalanguage having the usual semantics. Example:
enum WeekDays { Sunday, Monday, Tuesday, Wendsday, Thursday, Friday, Saturday }
Attributes or properties are defined inside a class scope. Properties has a type and an optional cardinalty expression. Example:
class House { string? Direction; string City; Person? Owner; List<Person> Inhabitants; List<Room> 2..* Rooms; }
The inbuilt primitive types are the following ones:
Primitive type | Semantics |
---|---|
string | Unrestricted text. |
bool | Logic value: true or false . |
int | Integer. |
long | Long integer. |
decimal | Decimal value. Useful for money and when discrete numeric precission is a must. |
char | Character. |
date | Constains a date in the W3C format (locale independent): #yyyy-MM-dd# |
time | Contains a time expression given the W3C format: #hh:mm:ss(((+|-)hh:mm)|Z)?# |
datetime | Constains a datetime value in the W3C format (locale independent): #yyyy-MM-ddThh:mm:ss(TZ)?# |
Traditional cardinality operators are supported with their standard meaning:
Operator | Cardinality Semantics |
---|---|
(nothing) | (1..1) Compulsory univaluated for
simple types and (0..*) for Lists. |
? | (0..1) Optional. Element can be present or ausent. |
+ | (1..*) Compulsory and multivaluated. |
* | (0..*) Optional and multivaluated. |
0..* | (0..*) Same as previous. |
n..m | (n..m) Multivaluated with a minimun of (n) and a maximus of (m). |
Default cardinality for simple primitives (univaluated) is 1..1
. The optional
operator ?
can be used if needed. E.g. string? Label;
Default cardinality for lists types is 0..*
. E.g. List<Milestone>
Milestones;
Multivaluated properties can be marked as compositions using the reserved
keyword composition
. E.g.
class House { composition List<Room> Rooms; }
Namespaces can be splitted and defines in multiple files.
Classes will be allowed to be defined partially. Having each part on different files. The model compiler will joint the partial definitions to create a unique definition after parsing and before the validation stage.
This feature promotes Separation of Concerns and an easy extension mechanims without rewriting core metamodels.
When defining relations between classes, it is possible to name the other's end role name and also fix the opposite cardinality. E.g.:
class House { composition List<Room> 2..10 Rooms opposite House; } class Room { string Name; }