Metamodels
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:
Quick Sample
namespace Sample.Metamodel
{
class Project : Plan
{
string Name;
string? Description;
List<Milestone> 0..* Milestones;
}
class Milestone
{
string Name;
string? Date;
}
}
Basic primitives
The primitives of the Essential metamodeling language are described here:
Namespace
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.
Class
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;
}
Inheritance
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
Enumerations are also allowed in the metalanguage having the usual semantics. Example:
enum WeekDays
{
Sunday, Monday, Tuesday, Wendsday, Thursday, Friday, Saturday
}
Attributes
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;
}
Primitives types
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)?# |
Cardinality operators
Traditional cardinality operators are supported with their standard meaning:
| Operator | Cardinality Semantics |
|---|---|
(nothing) |
(1..1) Compulsory univaluated forsimple 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;
Composition keyword
Multivaluated properties can be marked as compositions using the reserved
keyword composition. E.g.
class House
{
composition List<Room> Rooms;
}
Partial definitions
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.
Opposite roles
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;
}


