UML2Ecore Reference

What is UML2Ecore?
Setting up Eclipse
UML Tool Support
Setting up your metamodel project
Invoking the Generator
The generated Model
Naming
Modularizing the metamodel file

What is UML2Ecore?

Building metamodels with the internal tools of EMF is tedious. Using the tree view based editors does not scale. Once you are at more than, say, 30 metaclasses, things become hard to work with. The same is true for the Ecore editor of GMF. Since you cannot easily factor a large metamodel into several diagrams, the diagram get cluttered and layouting becomes almost impossible.

One way to solve this problem is to use UML tools to draw the metamodel and then transform the UML model into an Ecore instance.

The oAW uml2ecore utiliy transforms a suitably structured Eclipse UML2 model (which can be created using various tools) into an Ecore file.

Note that this tool also serves as a tutorial for writing model-to-model transformations. This aspect, however, is documented elsewhere. This document only shows how to use the uml2ecore tool.

Setting up Eclipse

You need an installation of oAW 4.3 including the UML2 support. Run the UML2 example (available for download on the oAW download page http://www.openarchitectureware.org/staticpages/index.php/download) to verify that you have all the UML2 stuff installed.

The only additional thing required is that you install the UML2Ecore plugin into your Eclipse installation. The plugin is part of the oAW 4.3 distribution.

UML Tool Support

Of course, you could use the tree editors supplied by UML2 for drawing the UML2 model that should be transformed into Ecore. However, this is useless, since then you are back to square one: tree editors. So you need to use an UML tool that is able to export the model in the Eclipse UML2 2.0 format. For example, MagicDraw 11.5 (or above) can do that; this tool (MD 11.5) is also the one we tested the uml2ecore utility with.

Note that we do not use any profiles in the uml2ecore utility. Although using profiles might make the metamodel a bit more expressive, we decided not to use a specific profile, to reduce the potential for compatibility problems (with the various tools).

Setting up your metamodel project

You should first create a new Generator project (select File->New->Other->openArchitectureWare/Generator Project).

Then open your UML2 tool of choice (we will use MagicDraw here) and draw a class diagram that resembles your metamodel. Here is the one we have drawn as an example for this document:

Figure 31. UML2Ecore sample metamodel - class diagram

UML2Ecore sample metamodel - class diagram

This is the usual metamodel for entities and such. Nothing special. Also, the name of the model defines the name of the Ecore metamodel; here is the MagicDraw tree view to illustrate this:

Figure 32. UML2Ecore sample metamodel - MagicDraw containment tree

UML2Ecore sample metamodel - MagicDraw containment tree

You now have to save/export this model in Eclipse UML2 format. In MagicDraw, you do this by selecting FileExportEclipse UML2. The exported files have to be in the root of the src folder in the metamodel project created above. This is how the project looks like after this step, assuming you would have called your model entity.uml2:

Figure 33. Project layout

Project layout

Before you can actually run the generator, you have to make sure that your project has a plugin dependency to the uml2ecore plugin. Double-Click on the plugin manifest file, select the Dependencies tab and click add. Select the org.openarchitectureware.uml2ecore plugin. The result looks like this:

Figure 34. Dependencies

Dependencies

In the current version, you also need a dependency to the org.openarchitectureware.util.stdlib project. Later versions of the uml2ecore plugin will reexport that dependency, so that you will not need to add it you your projects manually.

Invoking the Generator

As usual, you have to write a workflow file. It also has to reside in your project source folder. Here is how it looks:

<?xml version="1.0"?>
<workflow>
<cartridge
	file="org/openarchitectureware/util/uml2ecore/uml2ecoreWorkflow.oaw"
		uml2ModelFile="org/openarchitectureware/uml2ecore/test/data/entity.uml2"
		outputPath="out"
		nsUriPrefix="http://www.voelter.de"
		includedPackages="Data"
		resourcePerToplevelPackage="false"
		addNameAttribute="false"/>
</workflow>

As you might expect, it simply calls a cartridge supplied by uml2ecore plugin. You have to define the following properties:

Table 31. UML2Ecore - Cartridge properties

PropertyDescription
uml2ModelFileThe is the name of your UML2 file that contains the model; as usual, the file is looked for in the classpath (that is why you had to move it into the source folder)
addNameAttributeThis determines whether automatic namespace management and naming is turned on (see the end of this document). For the simple example, please set the value to be false. true/false
nsUriPrefixThe nsUriPrefix is used to assemble the namespace URI. The name of the metamodel, as well as the nsPrefix, will be derived from the UML model name; so in our example, the nsPrefix and the name of the generated EPackage will be entitymm. The complete namespace URL also required by Ecore is created by concatenating the nsUriPrefix given here, and the name. The resulting namespace URL in the example will thus be http://www.voelter.de/entitymm.
includedPackagesThis property etermines which packages the transformer should consider when transforming the model; note that the contents of all the packages will be put into the root EPackage.
outputPathThis property etermines where the resulting files are written to.
resourcePerToplevelPackageIt set to true, the generator will write a separate Ecore file for each of the top level packages in you UML model filtered by the value of the propery includedPackages. Useful for modularizing metamodels (see the end of this chapter).
nameUnnamedNavigableAssociationEndsIf set to true, all unnamed navigable association ends will be initialized with the name of the target type.


You can now run this workflow by selecting Run As -> oAW Workflow. The name of the generated Ecore file will correspond to the name of the root Model element in the UML model.

The generated Model

Here is a screenshot of the generated model:

Figure 35. Generated Ecore model

Generated Ecore model

The generator also creates a constraints file (called entitymmConstraints.chk) which contains a number of constraints; currently these are specifically the checks for the minimum multiplicity in references (an error is reported if the minimum multiplicity is one, but the reference is null or empty, respectively). You can integrate the generated constraints file into your workflow using the usual approach.

Naming

It is often the case the basically all model elements in a model should have a name. It might not always be necessary from a domain perspective, but it is really useful for debugging. Of course, you can add a superclass called Named with a single attribute name to all you classes. However, if you set the addNameAttribute parameter to be true when calling the uml2ecore cartridge, every class which does not inherit from another class gets an additional name attribute. Also, constraints that make sure that names within a namespace (i.e. a containment reference) are unique.

uml2ecore also comes with a utility extension called org::openarchitectureware::util::stdlib::naming that can calculate the namespace() and the qualifiedName() for every model element that has a name.

Another convenience is the parameter nameUnnamedNavigableAssociationEnds. Often you specify a relationship between two metaclasses and give the target end the name of the target metaclass. Let us say you specify an association from metaclass Application to Component. It is likely that the target end will be called component. By setting the parameter to true all unnamed navigable association ends will get the name of the target class. If there is more than one unnamed association only the first one will be modified. This would lead to a failing constraint afterwards, since at least after this modification all navigable association ends must be named.

Modularizing the metamodel file

You can modularize the metamodel. If you specify the resourcePerToplevelPackage=“true“ parameter to the cartridge call, you will get a separate Ecore file for each top level package, as well as a separate constraint check file.