Howto Transform?
As the source code XMI and the target code GXL are explained and the possible constructs are available now, it is time to describe the way, XIG transforms the XMI code, storing the constructed UML class diagrams, into the corresponding GXL code, which builds the equivalent UML object diagram. To get an overview of the whole transformation-work, the following picture shows a granular view of the most important steps, XIG does. The complete (and commented) stylesheet can be seen in transform/the_translator.

As it can be seen, the XSLT stylesheet is divided into three big parts. The first part is the definition of some XPath selections, which are needed in the further translation and for some version-checking. The second part is the Root Template, which is the entrypoint of the transformation, because it selects the root element and therefore is the start of every stylesheet. This part contains itself a static part and a generic part, whereby the latters is an accumulation of five template calls. These called templates, which build the third part of the stylesheet, are the main part of the transformation - their task is the translation of the different XMI constructs.
After this simple overview, it is necessary to explain the single steps of the XSLT stylesheet more detailed:
|
XSLT code |
This first fragment shows the base of the XIG translator. As in every other XML document the mandatory XML processing instruction has to be inserted. After that, the stylesheet is set and as well as the prefix xsl is associated with the XSLT namespace, the prefix xlink is associated with the XLink namespace.
1) The Definition Part
|
XSLT code |
In this part, following the instruction, the output of the stylesheet is set to XML, the character set is defined, and the produced XML code is linked with its DTD (<xsl:output ... />). After that, some information for version-checking is stored in variables (first four <xsl:variable ... />). Also included are some ID references, indeed the references of the <<graph>>, <<edge>> and <<rel>> stereotype extended elements (this is done in the next three <xsl:variable ... />). These can simply be selected by using the information of the stereotype classes in the XMI code.
Furthermore, all classes which are attribute types and used attributes are stored (last two <xsl:variable ... />). This is done in the first case, by selecting all XMI classes, which are accordingly referenced, and in the second case, by selecting all existing attribute parts in all XMI classes.
2) The Root Template
a) The Version Check
|
XSLT code |
The upper code fragment shows the template for handling the root node - it is the start of the transformation (<xsl:template match="/"> ... </xsl:template>). To prevent different problems, which can occur, if the wrong metamodel or wrong version of the properly metamodel is used, these files are not accepted here. This is done by using a XSLT choose element (<xsl:choose>), which differs four different cases (three cases <xsl:when ... > and the default case <xsl:otherwise>). In all bad cases the transformation is stopped by using a terminating message element (<xsl:message terminate="yes">).
Only in the good case a further check for the existence of more than one <<graph>> stereotyped elements is done. If the check is passed without problems, some comments (<xsl:comment>) are inserted and the transformation begins.
b) The Static Part
|
XSLT code |
The static part of the transformation includes the creation of the GXL document element and the included graph element (<xsl:element name="gxl"> and <xsl:element name="graph">). The graph element gets the same ID the XMI code contains for the corresponding Model_Management.Model (<xsl:value-of select="/XMI/XMI.content/Model_Management.Model/@xmi.id"/>). Furthermore, it is typed as MetaSchema#GraphClass (<xsl:attribute name="href">MetaSchema#GraphClass</xsl:attribute>). As the creation of the elements, their IDs and schema element references is done in the same way in every case in the following, only deviations are mentioned any more.
The second step is the creation of the GraphClass derived Node, whereby the ID and name of an corresponding <<graph>> stereotyped class are used, if this class exists. If this class is non-existent, the ID and the name are set to xmi.0.
Due to a problem with the XML processor, the namespace prefix "xlink" is left out in all type elements. It could simply be inserted in front of the reference (e.g. <xsl:attribute name="xlink:href">MetaSchema#GraphClass</xsl:attribute>). Of course, this could (and should) be done with all type elements in the same way.
c) The Template Calls
|
XSLT code |
The last part of the Root Template contains the single template calls, which do the actual transformation work. At first, all classes are selected for transformation, which are neither stereotyped <<graph>>, <<edge>>, or <<rel>>, nor attribute type classes - these are the future NodeClass derived nodes.
Second are all associations which do not link any <<graph>>, <<edge>>, or <<rel>> stereotyped class - these are future EdgeClass derived Nodes, visualized as simply associations in the corresponding UML class diagram. All EdgeClass derived Nodes, which have been built by using <<edge>> stereotyped classes with two adjacent associations are selected whereupon following.
The last but one template call collects all XMI classes, which correspond to <<rel>> stereotyped classes with adjacent associations, and builds RelationClass derived nodes. At the end, all attributes are converted.
3) The called Templates
a) The first Template - The Translation of normal Nodes:
|
XSLT code |
The first template selects all given Foundation.Core.Class elemens in the given node-set. The first step is now to create the GXL node object (<xsl:element name="node">) and give it an ID and a name, which are set as in the corresponding class. As in every other case, the ID is set as the name, if the name attribute of the XMI element is empty and a contains edge (<xsl:element name="edge">) to the graph element is created. These steps are done in the same way in the following, therefore this is not mentioned any more from now on.
b) The second Template - The Translation of Edges, visualized as Associations:
|
XSLT code |
The second template selects all given Foundation.Core.Association elements in the given node-set this time and creates EdgeClass typed GXL node objects, which has not to be shown here any more. But one new feature is the creation of the isDirected attribute of the node objects (<xsl:attribute name="name">isDirected</xsl:attribute>).
If both association ends of the selected association are navigable (this is the first case), then the association is not directed. If exactly one association end is navigable, the association is directed (this is the second case). In every other case (here only if both association ends are not navigable), the association is defined as illegal and the transformation is stopped and throws an error message (<xsl:message terminate="yes">Error: An association is neither directed, nor undirected !</xsl:message>).
In the next code fragment the creation of the from- and to-edges is shown for the directed case. Due to the similar code in the undirected case, this case is left out in the following.
|
XSLT code |
In this case, the from-edge is shown in the upper code. As it
can be seen, the edge is tested for its navigability in the beginning (<xsl:when
test="...">);
if exactly one association end is navigable, the association is directed in the
whole. Now the from- and to-edges are created and linked. Accordingly to the
direction of the association, the from-edge of the from-edge links to the
EdgeClass derived node object (<xsl:value-of
select="@xmi.id"/>)
and the to-edge of the from-edge links to the ID, the not navigable association
end references as its target. Furthermore, the multiplicity of the association
is read out and inserted (<xsl:attribute
name="name">limits</xsl:attribute>),
if it differs from "1x1". In the same way, the association end
is tested for ordering and if the end is ordered, the bool attribute isOrdered
is inserted (<xsl:attribute
name="name">isOrdered</xsl:attribute>).
c) The third Template - The Translation of Edges, visualized as classes:
|
XSLT code |
The third template creates EdgeClass derived nodes which are visualized as a node, combined with associations. Because of that, the template selects all given Foundation.Core.Class elements, which means that all used association ends have to be selected at first (<xsl:variable name="association_ends" ... >). The ID of the class has to be stored temporarly, because the original position in the data tree is left due to the association ends selection (<xsl:variable name="class_id" select="@xmi.id"/>).
|
XSLT code |
This time, an additional error check has to be inserted. Only two adjacent associations are allowed, which must be navigable in the following ways: "-->[]-->", "<--[]<--", or "---[]---". All other cases are not unique and cause the termination of the translation (<xsl:message terminate="yes">Error: ... </xsl:message>).
After this check, the EdgeClass typed node object and its isDirected attribute is created in the same way, as described in the last template.
In the next code fragment the creation of the from- and to-edges is shown for the directed case. Due to the similar code in the undirected case, this case is left out in the following.
|
XSLT code |
In this case, the from-edge is shown in the upper code. As it can be seen, the edge is tested for its navigability in the beginning (<xsl:when test="...">); due to the previous error check it has only to be found out, if exactly two of the four association ends are navigable. If this is true, the edge is directed, because all other error cases would not reach this selection.
Now the from- and to-edges are created and linked. Accordingly to the direction of the association, the from-edge of the from-edge links to the current XMI class - therefore, to the future EdgeClass derived node. The to-edge of the from-edge links to an ID, the non-navigable association end, which is not linked to the current class, references as its target.
After that, the multiplicity of the association is read out and inserted (<xsl:attribute name="name">limits</xsl:attribute>), if it differs from "1x1". In the same way, the association end is tested for ordering and if the end is ordered, the bool attribute isOrdered is inserted (<xsl:attribute name="name">isOrdered</xsl:attribute>).
d) The fourth Template - The Translation of Relations:
|
XSLT code |
As the second kind of edges, which have been translated in the last template, relations are built as XMI classes, combined with associations. And again, the template is called with the corresponding selection of Foundation.Core.Class elements, as it is shown in the beginning. Therefore, all used association ends have to be selected again (<xsl:variable name="association_ends" ... >) and the ID of the class has to be stored.
The new step here, is the transformation of the relation special structure, which is shown in the next code fragments:
|
XSLT code |
Due to the construction of the relation, the translator has to go through all adjacent associations. For every association a RelationEndClass derived node has to be created. After that, the validness of the association has to be checked (<xsl:choose>) and an translation has to be terminated, if it is not guaranteed (<xsl:message terminate="yes">Error: A tentacle is neither directed, nor undirected !</xsl:message>).
If the association is valid, the directedTo attribute has to be set. The navigability of both association ends means that the association is undirected (this is the first case). Only one navigable association end is characteristically for a directed association (this is the second case). In the last case, two possibilities have to be distinguished (this is the internal <xsl:choose>), whereby the tentacle is directed to relation, when a navigable association end at the relation is given (the first internal case). In contrast to that, a navigable association end at the referenced node means that the tentacle is directed to the target (the second internal case).
Afterwards, the bool attribute isOrderedRelation is
inserted, if the proper association end is ordered.
|
XSLT code |
The next part of the XSLT for-each element is the creation of the hasRelationEnd derived edge, which is linked to the RelationClass derived node and the RelationEndClass derived node (this is done in the first <xsl:element name="edge">).
After that, the relatesTo derived edge is created and linked to the RelationEndClass derived node and the NodeClass derived node (this is done in the second <xsl:element name="edge">), whereby the edge derived relatesTo links to the ID of the targeted node and the attribute limits is inserted, if the multiplicity of the association end differs from "1x1". Furthermore, the role attribute is inserted in every case, but the bool attribute isOrdered only, if the proper association end is ordered.
e) The fifth Template - The Translation of Attributes:
|
XSLT code |
The attribute template matches all Foundation.Core.Attribute elements, which are given by the corresponding template call. The task of the template is not only the creation of the AttributeClass derived nodes (which is not mentioned here, because is very similar again), but also the creation of the attribute type nodes and the corresponding edges.
As now every attribute has an attribute type, the ID of this used attribute type is stored in a variable in the beginning.
|
XSLT code |
Due to a different handling of the possible attribute types in the XMI, at first a node-set of all Foundation.Core.DataTypes is stored in a variable (<xsl:variable name="data_types" ... >), too. The attribute could now either be found in the variable attribute_type, or in the variable data_types. In the following, the according attribute type node is created and typed as it is defined in the GXL Attribute Model.
In this version of XIG, it is possible to transform the atomic value types and the locator value type.
|
XSLT code |
At the end the hasAttributes derived edge has still to be created and linked to the owner node and the AttributeClass derived node. In the same way, the hasDefaultValue derived edge has to be created and linked to the AttributeClass derived node and the attribute type node.