Model transformations in Henshin are defined using matched transformation rules. There are currently two editors available for rules:
- a tree-based editor (EMF), and
- a graphical editor (GMF).
The screenshot below shows both editors.
To define a transformation in either of the editors, you need to import EMF models first. This can be done using an action in the context menu of the tree-based and the graphical editor.In the graphical editor, all classes automatically appear in the palette on the right.
Henshin transformation rules mainly consists of two Graph objects, commonly referred to as LHS and RHS (left- and right-hand side), and mappings between nodes from the LHS and the RHS. The LHS is the graph pattern matched by the rule. The RHS describes the action of the rule, e.g. whether objects or links should be deleted. The mappings from the LHS to the RHS encode which objects should be preserved by the rule.
The graphical editor offers a more intuitive way of representing rules. Essentially, elements in a rule are annotated with actions such as <<create>>, <<delete>>, <<preserve>> and <<forbid>>. A screenshot of a simple, but not very meaningful, transformation rule in both editors is shown above. Supported element actions are:
- <<create>> a node or an edge, or set an attribute
- <<delete>> a node or an edge
- <<forbid>> a node or an edge or a particular attribute value. Forbid actions can be parametrized to distinguish multiple negative application conditions (NACs). This essentially corresponds to logical AND vs. OR (more generally: first-order logic formulas over graph patterns). For instance, if there are two elements, one with the action <<forbid:1>> and the other one with <<forbid:2>>, then either of the two patterns must not be found. If both elements have the same (or no) forbid parameter, then the two elements must not be found together.
Transparent Container Objects
The graphical editor moreover supports so-called transparent container objects. In EMF, all objects should be part of a containment tree, i.e., every object should have a unique parent, except the root object. For flat graph-like structures, this would mean that you have to draw the parent object and the containment edges to all objects in a rule separately. Since this can be quite verbose, the graphical editor supports transparent parent objects. Simply parameterize the rule name with the type of the parent object and all objects in the rule will be automatically treated as children of an object of this type. This works only if the parent type defines canonical containment edges for all elements that are used in the rule.
The example below shows two the basic and the compact notation for the same rule AddEdge. Note that in the compact version the rule name is specified as AddEdge:Graph which indicates that all nodes are contained in a Graph object.
The example rule above is called ReplaceBook and is defined in the context of a Library object. This means that all matched elements must be contained in a Library instance and newly created objects are automatically added to it. The rule matches two objects (plus a Library instance), one of type Writer and one of type Book. The book is being deleted by this rule and a new instance of BookOnTape is created with the same title and author as the book. The name attribute of the Writer instance is converted to upper case. Moreover the rule cannot be applied if there exists a Borrower for the book or the category of the book is Mystery. If all application conditions (positive and negative ones) are fulfilled, the rule can be applied. The changes are performed in a transaction and are therefore atomic.
If you look at the tree-based editor, you see that the graphical notation is quite different from the underlying model. The Henshin transformation model allows you to define very complex in-place transformations. The graphical editor currently does not support all of the powerful language concepts, yet.