First, you'll get a brief overview of MTF (what is it, what are the important use-cases, and so on). Then you'll be introduced to the basic concepts used throughout this article (mapping, relation, and the syntax of the mapping language).
The core approach of this article is a step-by-step tutorial that illustrates how to write rules for a concrete example: a UML (Unified Modeling Language) to Relational model transformation. Each step presents a new mapping rule and explains the related concepts; where meaningful, a class diagram illustrates the rule.
The tutorial ends with a presentation of the MTF launcher, which allows you to run the example. Finally, the conclusion wraps up the essential concepts presented in this article and recommends further resources.
Using modeling in software development
The use of modeling is a growing trend in the software industry, as illustrated by the rise of Model-Driven Engineering and the Object Management Group's (OMG) latest initiative: Model-Driven Architecture (MDA)--for more information, see the Resources section later in this article. Model transformation plays a key role in this context, as it enables you to:
- Map models to other models
- Establish correspondence and traceability between different models
However, these technologies need to be supported by relevant tools and runtime environments in order to be fully effective. EMF provides the foundation for a modeling platform for Eclipse, allowing you to define model repositories and related editors around a common meta-model.
In 2002, as part of the Meta Object Facility (MOF) 2.0 standardization, OMG requested proposals for standards allowing users to query, establish and maintain views of, and transform MOF models. This piece of the MOF 2.0 standard is referred to as MOF 2.0 Queries/Views/Transformations (QVT, for short). As of November 2004, a number of submitters (including IBM) are working together to define the QVT standard. The specification at that time was still under significant revision. To learn more about these OMG initiatives, see the Resources section at the end of this article.
What is the Model Transformation Framework?
As part of its involvement in the QVT standardization, IBM has developed a prototype model transformation toolkit, MTF, which is now available from alphaWorks (see Resources). MTF implements some of the QVT concepts and is based on the EMF. It provides a simple declarative language for defining mappings between models, along with a transformation engine that can interpret mapping definitions in order to perform transformations.
The aim of MTF is to simplify your ability to develop transformation tools by supporting incremental update, round-tripping, reconciliation, and traceability. The most common related use-cases include:
- Model, code and document generation
- Model compare and merge
- Design pattern expansion
- Model consistency
MTF comes as a set of plug-ins that you can deploy in either Eclipse or the IBM Software Development Platform products. It provides a transformation engine for EMF models and a set of tools that helps you write, run, and debug mapping rules. The rule editor provides basic editing features (such as syntax checking and highlighting). The debugger allows you to trace the execution of the rules step-by-step. The mapping view enables you to inspect the result of a transformation when it is completed.
It is interesting to note that the transformation engine is not intended to run only inside an Eclipse environment. It relies only on EMF runtime libraries, so it can be used in any Java application as well as in Eclipse plug-ins.
Concepts of model transformation
The general idea behind the term model transformation is to produce models from other models given as input, according to predefined relationships between elements. It assumes that these models are described by compatible meta-models, in order to express these correspondences in a consistent way. In the scope of QVT, model transformation relates to MOF models. MTF applies these concepts to EMF models.
An MTF transformation results in a set of mappings that relate objects among different models; an object unbound to any mapping is considered out of the scope of the transformation. Specifying mappings between models provides a declarative way to define the result of a transformation. For example, if a mapping requires the existence of an object in a target model, the transformation engine will try to create it to satisfy the mapping.
Mappings that relate individual instances may not be the most concise and convenient way to specify a transformation. You probably prefer to define the correspondences at a class-level rather than for each of the instances. In order to do this, you can specify the mappings that relate objects with the same types into something called a relation. A relation in MTF (also referred to as a mapping rule) defines a type of mapping that will apply to instances of given model classes. In a sense, the semantics of a relation are quite similar to those of a constraint.
An example of this, shown below in Figure 1, illustrates a mapping between two models (shown in red and blue, respectively), composed of two relations (A2C and A2D) applied to relevant instances to produce three mappings (m1, m2 and m3, shown in an off-white color).
Figure 1. Example of mappings between two models
Transformations in MTF are defined in a declarative way: you specify a set of relations between model classes, and then let the MTF engine perform the transformation actions using these relations as input. The transformation engine proceeds in two stages called mapping and reconciliation. During the mapping stage, it evaluates the relations and generates mappings by iterating through the relevant model instances. At the end of this stage, some mappings may be inconsistent with respect to the relation. In other words, not all the imposed constraints of the relation are satisfied.
Reconciliation tries to satisfy the relations by creating missing elements, modifying existing elements, or deleting elements. In some cases, reconciliation may not be needed (when the models are already consistent, or if you only want to check the consistency of models without changing them). Furthermore, it is also not always possible (if no value can be inferred from the mapping). These concepts may appear a bit abstract for the moment, but they will be explained in detail in the following sections. The main idea to keep in mind is this process:
Relations > mapping > Mappings > reconciliation > Models changed
The relations are organized in a way that tends to follow the structure of the models. You will usually find at least one relation per model class, starting from a relation that relates the top-level model classes. Similar to a rule-based system, it is possible to invoke one relation from another, and propagate the execution of the mapping to related model classes. This mechanism is called correspondence and allows MTF to traverse a whole model by applying all the correspondences reachable (directly or transitively) from the top-level relation.
MTF supports a flexible transformation model that can accept multiple models, relate multiple elements, and update multiple models. The relations do not impose any direction of evaluation and can be executed in multiple directions, which can be useful when you're dealing with round-tripping issues. The direction of the transformation (source and target) is actually defined when you invoke the transformation engine.
As you may have already guessed, the relations that drive the transformations play an important role in MTF. They are expressed in a language called the Relation Definition Language (RDL), which is parsed and evaluated by the transformation engine. RDL allows the definition and application of relations between classes, based on correspondences between structural features. A typical relation, for instance, would associate two classes with a matching identifier attribute. The syntax of the language is simple, and is composed of only a few keywords and the standard Boolean operators.
The relate keyword allows the definition of relations using the form presented in Listing 1. The name and the formal parameters are defined in the signature of the relation. You can constrain these parameters with conditions to filter the matching values. The body of the relation usually contains the correspondences that need to be applied to the properties of the matched values, in order to propagate the execution of the transformation. These properties are looked-up by querying the matched values, based on the EMF structural features of a class. The equals keyword refers to a built-in correspondence, which allows one to test the equality of strings and other primitive types.
Listing 1. Defining relations
relate MyRelation(s:S source, t:T target)
{
equals(source.name, target.name),
MyOtherRelation(source.value, target.value)
}
|
Although it is concise, the RDL language allows you to express a number of essential concepts used in model transformation (for example, correspondences, expressions, and conditions). As a relation defines only correspondence relationships between elements, the context in which it is executed (in other words, the actual parameters that are input) is very important. Different executions may produce different results. The transformation presented in the following section helps explain these concepts in details.
Example: a UML to Relational model transformation
This section discusses how MTF can be used in a concrete case: a UML to Relational database (RDB) model transformation. Much has been written on this topic and several transformation algorithms are available. We implement in this article a partial mapping based on the principles introduced by J. Rumbaugh et al.(see Resources). The main rules of this mapping are presented below:
Mapping classes to tables
- Each UML class maps to a table.
- Each simple property of a class maps to a column of a table.
Mapping associations to tables
- Each many-to-many association maps to a distinct table.
- Each one-to-one association is buried as a foreign key in the table of either class.
- Each one-to-many association is buried as a foreign key in the table of the many class.
- Aggregation follows the same rules as association.
For simplicity's sake, this example makes a couple of simplifying assumptions here. It does not:
- Support non-navigable associations (where each association end is owned by a class)
- Provide mapping for other UML concepts, such as packages, generalization links, and so on
You'll make use of an EMF implementation of the UML 2.0 meta-model from the Eclipse.org UML2 project (see Resources). The UML modeling tools in the IBM® Rational® Software Modeler and IBM® Rational® Software Architect products are based on this EMF meta-model.
Since there is no standard meta-model of a relational schema, and again for the sake of simplicity, we have decided to define our own meta-model based on EMF, which we'll call SimpleRDB--see Figure 2. This formalism defines a schema as composed of a set of tables, which can be related with simple key constraints (details follow).
Another solution is to leverage the RDBSchema meta-model, used to implement part of the IBM® Rational® Application Developer (IRAD) SQL tools. In this case, the schema generated from the UML models can be directly consumed by the IRAD tools -- for instance, in order to generate SQL code. This is a good example of tool integration based on MTF.
Figure 2. The SimpleRDB meta-model
MTF runs on Eclipse 3.0 or higher, with the associated EMF level. It can be also installed in IRAD, Rational Software Modeler, and other IBM Software Development Platform tools. It is packaged as a set of plug-ins you simply have to place in your plug-in directory (see the MTF programmer's guide for more details regarding the installation--see Resources). To run this transformation example, you will also need to have these installed:
- UML2 1.0: available at www.eclipse.org: click the downloads link and look under the Eclipse Tools Project section
- SimpleRDB 1.0: included with this article
This example explains the basics of the RDL language, which should help you get started with MTF. Many of the relations explained here are illustrated with UML class diagrams. As there is no standard graphical notation to describe the concepts used by MTF (relation, correspondence, condition), we'll use a variation of the standard UML class diagram, to which we added our own stereotype and constraint notation.
Create a project in your workspace, then create a new file called simplerdb.rdl. Open it with the MTF mapping rule editor (.rdl is the default extension bound to the editor). Now, you are all set to write your first relations, as shown in Listing 2.
Step 1: Define the import statements
An RDL file begins with a series of import statements, used to declare the EMF packages that will be involved in the transformation. An import typically binds a package URI to a logical name that is used to prefix the classes specified in the relations, as shown in Listing 2.
Listing 2. Import Statements
import uml "http://www.eclipse.org/uml2/1.0.0/UML" import rdb "http:///com/ibm/mtf/simplerdb.ecore" import ecore "http:///com/ibm/mtf/model/emf.ecore" import ws "http:///com/ibm/mtf/model/workspace.ecore" import util "http:///com/ibm/mtf/util.ecore" |
These logical names provide a unique identifying mechanism similar to the namespaces used in XML. If you don't know the exact URI of the packages you want to import, the mapping rule editor provides a content assist feature, which lists the packages registered in the workbench.
In your example, you import the uml and rdb packages as you relate UML models to relational schemas. You also need to import the ecore, ws, and util utility packages, used to load the models (as explained in the next step) and import special constructs.
Step 2: Mapping a UML2 resource to a SimpleRDB resource
The transformation starts from the top-level relation presented in Listing 3. It provides a convenient mechanism for loading the model objects and running the transformation in the workbench (see the Run it! section). If you have already programmed Eclipse plug-ins, you may be familiar with the IFile class name, used as the parameter type of the relation. Here, you are not dealing with the org.eclipse.core.resources.IFile class itself, but rather with an EMF wrapper around it.
Listing 3. Mapping resources
relate Uml2SimpleRdb(
ws:IFile source,
ws:IFile target)
{
UmlModel2Schema
(over source.resource.contents,
over target.resource.contents)
}
|
MTF is designed to perform transformations on EMF models, but it also provides a way to adapt non-EMF classes. A mechanism called extension lets you adapt any Java class and manipulate it in the transformation engine, with user-defined semantics. The ecore and ws packages are some of the extensions shipped with MTF that provide default support for files and EMF resources. It is not mandatory to use them but they do give you significant help while defining the transformation.
You can write separate code that loads the relevant EMF resources and invokes the mapping engine on the model objects, but in this example everything is done for you in a transparent way. Don't worry if you're not familiar with the syntax of RDL yet, we will explain it in detail in the next step of the example.
There is as yet no defined case or naming convention for relations in RDL. This example tries to follow the Java naming convention and organize the relations (mappings, expressions, and conditions) in a top-down approach.
Step 3: Mapping a model to a schema
The relation shown in Listing 4 maps any given UML model to a schema with the same name. The formal parameters uml:Model and rdb:Schema are used as matching criteria; consequently, the mappings will be created only if the values applied to the relation are instances of the Model or Schema classes.
Listing 4. Mapping a model
relate UmlModel2Schema(
uml:Model model,
rdb:Schema schema)
{
equals (model.name, schema.name)
UmlClass2Table
(over model.ownedMember, match over schema.tables),
ManyToManyUmlAssociation2Table
(over model.ownedMember, match over schema.tables)
}
|
If you take a closer look at the previous relation, you can see how it invokes this relation in order to propagate the transformation from the EMF resources to their content. An EMF resource defines a collection of EObjects available in a model and accessible through a contents property. The UmlModel2Schema relation will be instantiated with the content of the left-side resource (the UML model), and the content of the right-side resource (the SimpleRDB model). In fact, you always have the ability to apply a relation on any object (or set of objects). If the object doesn't match the type criteria, then nothing will happen. If it does match, a mapping will be instantiated for each matching combination of values, and the transformation will be propagated to child elements.
The signature of the relation focuses on the mappings between UML models and relational schemas without really expressing how their content should be mapped. It is in the body of the relation that you will find the correspondences used to relate the model elements. When the relation is applied, the transformation engine will search for correspondences -- between classes and associations defined in the UML model, and tables defined in the relational schema -- and generate the relevant mappings for them.
We make sure that the name of the schema is identical to the name of the model using the equals built-in correspondence; both Model and Schema classes having an equal name attribute. Take note of the dot-based syntax used to query a property of an EMF object. The names of the properties used in RDL are based on the structural features exposed in the EMF classes.
In the meta-model of UML 2.0, classes and associations are subclasses of PackageableElement, and are accessible from the Model class through a navigable property called ownedMember. You use this property in your transformation to relate both classes and associations to tables of a relational schema. As the ownedMember and tables properties refer to a collection, the over keyword is used to indicate that the correspondence will be applied to all the elements of the collection, and not on the collection itself, as an object.
In this particular case, the execution of the relation will produce a cross product between all the tables and all the owned members that match the criteria explained in the later rule. Note that the match keyword indicates that some elements of the domain, such as schema.tables in Listing 4, are allowed to be left unmatched. In case there is no prefixed match keyword (for instance, model.ownedMember in Listing 4), then every type-conforming element of the collection must be mapped by the relation UmlClass2Table.
Figure 3. The UmlModel2Schema relation and its correspondences
The relation presented in this step of the example illustrates only part of a typical UML to RDB mapping, as it deals only with binary associations. A complete mapping would take into account n-ary associations, as well as generalization relationships between classes.
Step 4: Mapping a class to a table
Your next step is to define how UML classes relate to tables in the relational schema, as shown in Listing 5. The mapping is quite similar to the previous relation; you will find a table corresponding to each class with an identical name. The identity condition between the class and table names is ensured here thanks to the when keyword. The execution of the relation will propagate the transformation to the properties of each class, and map them to the relevant columns. One-to-one and one-to-many associations are handled by this relation as well.
Listing 5. Mapping a class
relate UmlClass2Table(
uml:Class class,
rdb:Table table)
when equals(class.name, table.name)
{
TablePrimaryKeyColumn [1] (match over table.columns,
over table.constraints),
UmlAttribute2Column(over class.ownedAttribute,
match over table.columns),
ClassOwnedEnd2ForeignKeyColumn(over class.ownedAttribute,
match over table.columns, over table.constraints)
}
|
As this example deals with navigable associations only, it assumes that association ends are always owned by the classes. Consequently, each property that implements an association end will relate to a foreign key in the relational schema. Many-to-many relations require a special mapping and are handled individually in another relation.
Applied as a correspondence, the TablePrimaryKeyColumn relation adds a primary key to each table related to a UML class. A primary key defines a column or a set of columns used as a unique identifier for a table. It is a first class entity in the meta-model of SimpleRDB, but it has no equivalent in UML 2.0. That is why the signature of the relation has no formal parameter that relates a UML element. It also explains why we use a specific multiplicity in the correspondence.
The concept of multiplicity in RDL has not been introduced before; it makes it possible to constrain the number of mappings -- to be instantiated from a relation -- by specifying a lower or upper bound. In this particular case, a multiplicity that corresponds to "exactly one" has been defined for the TablePrimaryKeyColumn relation (you can see the bracketed symbol introduced in the correspondence in Listing 5). If not specified, the default multiplicity is 0..n, which means as many mappings as are possible, and which is not relevant here, since a primary key is meant to be unique.
The UmlAttribute2Column relation maps simple-typed attributes of a class to columns of a table. The match keyword is used here because not every column relates to a UML attribute; as presented earlier, primary and foreign keys are added in order to map UML associations as well. In the case of the ClassOwnedEnd2ForeignKeyColumn relation, we map association ends, represented as class-typed properties, to foreign keys composed of a column and a foreign key constraint.
Figure 4. The UmlClass2Table relation and its correspondences
The class diagrams presented throughout this example are another possible representation of the concepts beyond the syntax of RDL. In these diagrams, the relations are defined as classes tagged with a specific stereotype, and their properties represent the formal parameters specified in input. A relation involves several model classes, which have properties that represent the values that will be applied to these parameters. Constraints defined on the properties of the relation show the conditions used to narrow the scope of the candidate values. As you can see in Figure 4, the property and column roles are the formal parameters of the UmlAttribute2Column relation, whereas ownedAttributes and columns represent the actual values involved in the correspondence.
The notion of correspondence is illustrated by an association between two relations, tagged with a dedicated stereotype. This example has so far focused on correspondences between classes associated with a containment relationship (a property is contained in a class, a table is contained in a schema, and so on), and has used the symbol of aggregation in the class diagrams to illustrate them. However, you will see in the next steps that some correspondences can also be applied between classes linked with simple associations. In this case, the notation will be different, without the aggregation symbol.
Step 5: Adding a primary key to a table
Listing 6 defines the relation between a column and a primary key, also represented by Figure 5 following. The relation ensures that:
- The name of the column conforms to that of a primary key -- in this case with the name ID
- The key is in fact the primary key of the table that to which it refers
- The key refers to the column
- The column type is INTEGER
Listing 6. Adding a primary key
relate TablePrimaryKeyColumn(
rdb:Column column,
rdb:PrimaryKey key)
when equals (column.name, "ID")
{
equals (key.table.primary, key),
equals (column, over key.column),
equals (column.type, "INTEGER")
}
|
The built-in correspondence that specifies the column type illustrates the declarative aspects of RDL. In your transformation, the relational schema is the target model, for which the reconciliation will produce values. Applying a correspondence on the target model is a kind of declarative specification of what the target values should be. In this specific case, this means that each type of column used as a primary key will be INTEGER. This is the first time that this example is using a relation as a declarative statement to define an expression (in other words, a value assignment) instead of using it for model-to-model mapping.
Figure 5. The TablePrimaryKeyColumn and its correspondences
Step 6: Mapping an attribute to a column
The relation in Listing 7 maps a UML attribute to a column with the same name. In the UML 2.0 meta-model, attributes and navigable association ends are both expressed as properties of a class.
Listing 7. Mapping an attribute
relate UmlAttribute2Column(
uml:Property property
when util:InstanceOf "uml:DataType" (property.type),
rdb:Column column)
when equals(property.name, column.name)
{
equals(column.type, "VARCHAR")
}
|
The when keyword has multiple applications and can be used in different contexts. Although all these usages express a notion of condition, their respective meanings are slightly different. Nested in a parameter declaration (for example, the property parameter in the relation above), a when clause defines a way to filter the candidate values applied in a correspondence. It relates properties in the scope of the parameter only, and is called a filter condition.
On the other hand, when it is used at the end of the signature of a relation, the same clause defines a join criterion between different sets of candidate values (for example, the property and column names), based on specific relationships between the related parameters. This is called an identity condition.
In the above relation, you want to map the simple type attributes only, and thus you make use of the InstanceOf constraint in a filter condition applied to the property parameter, which ensures that the type of the property is a Datatype. This custom constraint extends the RDL language, and is part of the util extension shipped with MTF.
In the body of the relation, you apply a correspondence to specify the type of each column related to a matched property. For the sake of simplicity, consider VARCHAR as the default type for every column that is not a primary or a foreign key.
Figure 6. The UmlAttribute2Column relation
Step 7: Mapping an association end to a foreign key
The relation in Listing 8 defines a mapping between an association end and a foreign key. In the principles introduced earlier, Rumbaugh et al. consider different cases for the mapping of associations regarding their multiplicity:
- A one-to-one association is mapped to a foreign key buried in one of the tables (no matter which)
- A one-to-many association is specifically mapped to a foreign key in the "many" table
- A many-to-many association is mapped to a distinct table
Listing 8. Mapping an association end
relate ClassOwnedEnd2ForeignKeyColumn(
uml:Property property when CheckOne(property)
& util:InstanceOf "uml:Class" (property.type),
rdb:Column column, rdb:ForeignKey fkey)
when equals (property.name, column.name)
& equals (column, over fkey.column)
{
equals(column.type, "INTEGER"),
ref UmlClass2Table(property.type, fkey.refTable)
}
|
Here, you'll focus on one-to-one and one-to-many multiplicities, which you'll handle as a single case. Many-to-many associations (handled by another relation) are outside the scope of this article. For this example, consider the creation of a foreign key for every association end to occur with a multiplicity of "one". As a consequence, two things may occur:
- In the case of one-to-many relations, your transformation creates a foreign key in every "many" table
- In the case of a one-to-one relation, your transformation creates a foreign key in each table
You're pursuing a slight variation of the strategy proposed by Rumbaugh et al.
You will notice that the structure of the UML meta-model implies different strategies for the mapping of associations, whether their ends are navigable (owned by one of a related class) or non-navigable (owned by the association itself). To access the association ends, you need to walk the classes owned by the model, or walk the associations, or both (if both navigable and non-navigable ends are handled).
For the sake of simplicity, this example supports only two-way navigable associations This allows you easy access to the association ends, by walking the classes only, and then mapping the relevant properties to foreign keys.
One of the particular aspects of the relation presented in Listing 8 is that it makes use of another relation (for instance, CheckOne) as a condition for filtering values. Nested in predicates, correspondences can be applied to build powerful filters based on the multiplicity of the relations. Here, it allows you to define more expressive notions than strict equality (testing the presence of an element in a set, for instance).
The CheckOne relation is applied here to make sure that many-to-many associations will not be taken into account in the execution of the relation. Other predicates are defined to make sure that the property provided as a parameter is an association end (again, using the InstanceOf constraint). They also check that relevant matches between property and column names are satisfied.
When we are able to relate without ambiguity any association end to a foreign key, we can apply the correspondence to specify to which primary key the foreign key refers. In SimpleRDB, primary and foreign keys are defined as a column associated to a key constraint that refers this column, with a table owning both columns and constraints. In addition, foreign keys own a refTable attribute, which points to a primary key defined in another table. In this correspondence, you need to express the link between the primary and foreign keys, and specify a value for this attribute.
Applied with the property.type and fkey.refTable attributes, the UMLClassToTable relation can be used to specify this link between primary and foreign key. The relation has been used previously in a correspondence to map each class owned by a model to a table owned by a relational schema. In both cases, the goal is to relate UML classes (instances of uml:Class) to relational tables (instances of rdb:Table).
What you are doing here is a bit different, though, as you map simple references to already related elements (in other words, the UML classes). This is instead of mapping aggregation relationships, which imply the creation of new elements. From a mapping perspective, it means that you need to refer to existing mappings (instance of UmlClassToTable and relating a given a class and table) instead of instantiating new ones.
That is why this example uses the ref keyword in the correspondence, to express that a mapping should already exist for the referenced element and there is no need to create another one.
Figure 7. The ClassOwnedEndToForeignKeyColumn relation and its correspondences
The relation defined in Listing 9 is another example of the multiple uses of relations in MTF. Your main interest here is creating the relevant mappings from a relation, and then enumerating them as part of a condition. The mappings instantiated from this relation will not be taken into account during reconciliation.
Listing 9. Creating mappings from a relation
relate CheckOne( uml:Property property when equals(property.upper, "1") |
The purpose of this relation is to filter the many-to-many associations, which are handled by another relation. You are looking for association ends which have a multiplicity of one, symbolized by 1in UML2 (see Figure 8 following).
Figure 8. The CheckOne relation
The relations presented in this article implement a transformation of UML classes to tables -- and UML one-to-one and one-to-many associations to key constraints -- based on simplifying assumptions. It allowed you to understand the main concepts of the RDL language, even if a UML to Relational mapping is not entirely specified at this point. The case of the many-to-many associations is not discussed here, as its implementation is quite similar to the relations we presented before. The overall principle is to create a third table for each related association, and then to define the relevant key constraints. Additional relations that are not detailed here are shipped as part of the source code of the example.
Advanced concepts like abstract relations, or relation inheritance, are also part of the RDL language, but they will not be covered in this article. More details about these topics are available in the MTF programmer's guide--see Resources.
Once the relations have been defined, you can execute the transformation on actual models. This article uses the Primer Purchase Order model, a classic example described in the EMF book (see Resources) and illustrated in figure 9. The UML2 tutorial (see Resources) uses a variation called Extended Purchase Order. We defined the Primer Purchase Order model using UML2, specifying two-way navigable associations between the PurchaseOrder, USAddress, and Item classes, and made it available in this article. You will need to copy the file in your workspace, ideally in the project you have created for this example. Using this model as input, you will be able to run an MTF task and generate the related relational schema.
Figure 9. Adapted Primer Purchase Order model
MTF provides a high-level launching interface, which allows you to trigger a transformation from the Eclipse workbench. You just need to create a new Run configuration and enter the required parameters:
- Top-level rule
- Source and target files
- Direction of the transformation
The launcher will accept arguments only if the top-level rule has parameters that can create the values from a string. That is another reason why you used the ws extension in the Uml2SimpleRdb relation, so that you can instantiate the IFile class specifying the name of a file as a string.
The configuration screen for the MTF task is presented in Figure 10. You need to enter the path of the simplerdb.rdl file, and define Uml2SimpleRdb as the entry rule. Then you will specify the values for the source and target arguments; the source argument will be the path of the Primer Purchase Order file (and will not be modifiable), whereas the target argument will refer to the path of the relational schema to be created (and has to be modifiable). This combination, including a modifiable parameter, allows you to define the direction of the transformation. Reconciliation may not produce the relevant result if this aspect is not properly configured.
Figure 10. Running the Uml2SimpleRdb transformation as a task
The rules should execute without a problem, and a new file corresponding to the relational schema should appear in your workbench.
MTF contributes to the Eclipse workbench by providing a mapping view that allows you to inspect the mappings generated by the transformation engine. This feature really helps you trace and understand the execution of the transformation. When the task is completed, you can click on the button
that should have appeared at the bottom of the property sheet. You will see a result similar to that presented in Figure 11.
Figure 11. Inspection of the mappings generated by MTF
MTF offers a declarative approach to model transformation. In this article, we briefly described the MTF language and demonstrated its use on a UML Model to Relational schema mapping. MTF offers many possibilities for automating model transformation and synchronization activities:
- UML to UML
- Pattern expansion
- Platform-Independent Model (PIM) to Platform-Specific Model (PSM) transformation based on profiles (EJB, CORBA, and so on)
From a tooling perspective, MTF offers a low-cost approach for smoothly integrating tools based on EMF models.
| Name | Size | Download method |
|---|---|---|
| sebas_attachments.zip | 60KB | HTTP |
Information about download methods
- To download MTF, visit the alphaWorks site. There is also a MTF programmer's guide that ships with MTF.
- Find more resources about Model Driven Architecture at the Object Management Group site.
- Find more resources about CWM and MOF
at the Object Management Group Resource Page.
- The document, MOF 2.0 query/views/transformations RFP, is also available from OMG's site.
- J. Rumbaugh, M. Blaha, W. Premerlani, F. Eddy, W. Lorensen, Object-Oriented Modeling and Design, Prentice Hall (1991).
- F. Budinksy, D. Steinberg, E. Merks, R. Ellersick, T. Grose, EMF, Addison-Wesley (2003).
- The article Getting started with UML2
provides a good introduction to UML 2.0.
- For technical resources about Rational's products, visit the developerWorks Rational content area. You'll find technical documentation, how-to articles, education, downloads, product information, and more.
Sebastien Demathieu is software engineer and works in the field of Model Driven Development. At the time he wrote this article, Sebastien was working at the IBM Watson Research Center and was involved in several tooling projects related to pervasive application development.




