Whenever you want to store additional information to
EMF-based models and you cannot or don't want to change the respective metamodel,
EMF Profiles provide a convenient solution for extending metamodels in a non-intrusive and lightweight manner; comparable to how
UML profiles allow to extend UML. For extending a metamodel, all you have to do is to create a profile, which can then be applied to models in order to store the additional information you want to add to the original model. In the following, we show how profiles are created step by step.
Extending the library metamodel

For illustrating the process of creating a profile, we extend the well-known library example metamodel. This metamodel basically contains three classes: the class
Library,
Writer, and
Book.
Now assume, we need to add additional information to library models without having to change the metamodel and, thus, without the need to re-generate the model-, edit-, and editor code. In particular, we want to be able to store whether a book is an ebook and, if it is an ebook, in which format it is available (such as ePub or PDF). Additionally, we want to be able to annotate books with tags.
Creating a profile project
To create a new profile project, we start the dedicated wizard for profile projects by selecting File > New > Other and select EMF Profile > EMF Profile Project.
After clicking Next, we enter a name for the profile project, as well as additional information about the profile, such as its name and its namespace URI. For the name and the namespace URI, it is recommendable to apply the same naming conventions as for metamodels.
After hitting the Finish button, the wizard creates the EMF profile project and opens the created empty EMF profile diagram, which has been initialized with the information provided in the wizard already, as can be seen in the Properties view.
Modeling the profile
A profile consists of stereotypes, which extend EClasses of metamodels. In our scenario, we want to store additional information to instances of the class Book of the library metamodel. Thus, we will create stereotypes that extend the class Book. Therefore, we first have to import the class Book. To do that, we use the popup menu (right-click the canvas of the profile diagram editor). In the popup menu, we now select Import Metamodel Element... and choose the extlibrary metamodel and, in the next step, the EClass Book. As a result, we obtain a shortcut to Book in our profile diagram canvas.


Now, we can start creating stereotypes using the palette in the profile diagram editor. To store whether a book (i.e., an instance of the class
Book) is an ebook, we create the stereotype
EBook. As we want to apply this stereotype to instances of
Book, we create an
Extension relationship from the created stereotype to the imported class
Book. Extension relationships have a multiplicity (e.g.,
0..1,
0..*,
2..4, etc.). This multiplicity specifies how often a stereotype can be (and must be) applied within one profile application to an instance of the extended class (e.g.,
Book). In our scenario, the stereotype
EBook should not be mandatory, since we might have books that are not ebooks and, thus, should not be annotated with the stereotype
EBook. Thus, we use a lower-bound multiplicity of
0. Further, it wouldn't make any sense to apply the stereotype
EBook multiple times to the same book. To prohibit multiple applications, we set the upper-bound multiplicity to
1.
Stereotypes may carry additional data. One way to allow for adding additional data is to add tagged values to stereotypes. Since we want to store the format of an ebook, we add the tagged value named
format to the stereotype
EBook. Tagged values are basically attributes and can have primitive Ecore types, such as
EString, EBoolean, ect., as well as custom
EEnum types
. We want to store whether an
EBook is available in the format of
EPUB or
PDF; thus, we create a new
EEnum named
EBookFormat with two literals,
EPUB and
PDF, and set the type of the attribute
format to
EBookFormat.
Side note: Although this isn't needed in our example, stereotypes may, in general, also contain cross references to existing model elements (in the base model or in the profile application), as well as containment references (i.e., the stereotype application owns additional model elements). For creating references, just use the palette in the diagram editor and set the properties of the added reference accordingly. You can also use inheritance among stereotypes, if needed.
As mentioned above, we also want to be able to annotate books with tags. Therefore, we add another stereotype named
TaggedBook, which also extends the class
Book, and add a tagged value named
tags of type
EString to the created stereotype. To enable multiple tags for one book, we may set
tags to be multi-valued (i.e., an upper-bound of
-1 in the properties of the tagged value) and/or set the multiplicity of the stereotype to be
0..*, which specifies that the stereotype
TaggedBook may be applied arbitrarily often to one instance of a book.
Registered profiles
Having finished the profile, we may validate it and save it. If the profile is valid, it will be registered automatically to the local profile registry. You may inspect all currently registered profiles using the Registered EMF Profiles view, which can be added using Window > Show View > Other... > EMF Profiles > Registered EMF Profiles.
As can be seen in the screenshot above, the created profile has been registered correctly. Note that you can still modify your profile; it will be synchronized automatically with the local profile registry, as long as your profile is valid. If it is invalid, it will disappear from the registry until you fix the validation error.
Once your profile is available in the local registry you can apply it to models that conform to the extlibrary metamodel. This, however, will be covered in future posts... so make sure to stay tuned.