A transformation definition describes how a model written in one language can be transformed into a model written in another language. Such a description is generic when it is independent of the actual models. It must make use of the concepts defined in both languages; in other words, it is built using the metaclasses in the metamodels of both languages. A transformation definition relates metaclasses in the source language to metaclasses in the target language. OCL is useful for defining transformations. An OCL expression is a representation of an element in the model; in this case, in the metamodel. An OCL expression can therefore precisely indicate which element or elements in the source metamodel are used in a certain transformation. The same holds for the elements in the target metamodel. For instance, when a UML class is being transformed into a Java class, not all attributes in the model need to be transformed into class members , only the ones that are owned by the UML class that is being transformed. In OCL, this can be expressed precisely. From the context of the UML class, the attributes to be transformed are exactly identified by the following expression: self.features->select( f f.isOclType( Attribute ) ) Because transformations are to be executed by automated tools, transformation definitions need to be written in a precise and unambiguous manner. Currently, no standard language for writing transformation definitions exists. In our opinion, such a language should be built on the assets of OCL. The next section uses a language that is an extension of OCL to write an example transformation definition. 5.5.1 Example Transformation DefinitionThis section describes the definition of the transformation of a public attribute to a private attribute and a get and set operation. Of course, this is only a very simple example, yet it shows how transformations can be defined using OCL expressions. The source and target languages are both UML. The transformation will be executed according to the following rules:
The preceding rules must be written in a manner that can be understood by an automated tool; therefore, we need to formalize them. To do so, we use a language that is an extension of OCL. In it, each transformation rule is named, and its source and target language are specified. In a rule, a condition may be specified under which the elements of the source language metamodel can or cannot be transformed. Likewise, a condition may be specified that must hold for the generated elements. Finally, the actual transformation is defined by stating the rule to be used to transform a metamodel element of the source language into a metamodel element of the target language. Because there may be conditions in the applied rule, we use the keyword try to indicate that the rule will be applied only when the source and target conditions hold. The <~> symbol represents the transformation relation: Transformation ClassToClass (UML, UML) { source c1: UML::Class; target c2: UML::Class; source condition -- none target condition -- none mapping try PublicToPrivateAttribute on c1.features <~> c2.features; -- everything else remains the same } Transformation PublicToPrivateAttribute (UML, UML) { source sourceAttribute : UML::Attribute; target targetAttribute : UML::Attribute; getter : UML::Operation; setter : UML::Operation; source condition sourceAttribute.visibility = VisibilityKind::public; target condition targetAttribute.visibility = VisibilityKind::private and -- define the set operation setter.name = 'set'.concat(targetAttribute.name) and setter.parameters->exists( p p.name = 'new'.concat(targetAttribute.name) and p.type = targetAttribute.type ) and setter.type = OclVoid and -- define the get operation getter.name = 'get'.concat(targetAttribute.name) and getter.parameters->isEmpty() and getter.returntype = targetAttribute.type; mapping try StringToString on sourceAttribute.name <~> targetAttribute.name; try ClassifierToClassifier on sourceAttribute.type <~> targetAttribute.type; } -- somewhere the rules StringToString and ClassifierToClassifier -- need to be defined Naturally, all details of transformations, and transformation definitions cannot be explained in such a small section. The complete language used to define transformations, an example transformation of a platform-independent model (PIM) to an EJB platform-specific model (PSM), a database PSM, a JSP PSM simultaneously , and much more information on MDA can be found in MDA Explained, The Model Driven Architecture: Practice and Promise [Kleppe03]. |