Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Henshin/Compact API

< Henshin
Revision as of 07:49, 24 June 2020 by Unnamed Poltroon (Talk) (Created page with "The '''Henshin Compact API''' extends Henshin's default API with simplified ways to specify and execute modules, units, and rules We consider as running example the existing...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The Henshin Compact API extends Henshin's default API with simplified ways to specify and execute modules, units, and rules

We consider as running example the existing here Bank Example and here University Courses Example.

Why?

There are already three efficient ways to specify Henshin-Modules. The main reasons to use the compact API over the other ways of specification are:

  • the design for extensibility (see the example at the bottom of the page)
  • other ways of specification all have different special features or "quality-of-life"-improvements. The compact API is designed with all these features and improvements in mind and therefore combines them all.
  • it is possible to build and execute the modules dynamically when they are specified programmatically.

Specifying a simple Henshin Module

For this part of the tutorial we will use the transformation rule createAccount from the Bank Example. We will specify this transformation rule step by step using the "henshin.compact"-Package

File:Rule-create-account.png

CModule: the first thing we need to create is a CModule. A CModule represents a Henshin-Module and is the container of all transformation rules and units we will specify. To create a CModule you can call the constructor, specifying a name for the new Module.

File:SpecifyNewCModule.png

If you already got an existing Henshin Module, you can use the static method loadFromFile to create a CModule from this .henshin file. Next we only need to add our used ecore-Package(s) to the imports of our module. To do this we can either add a single package, given as EPackage-Object. Or add all ecore-Packages contained in an .ecore-File.

File:AddImportsFromFile.png

CRule: Once we got a CModule we can then specify transformation rules by use of the createRule method. Given a name for the new rule this method will return a newly created CRule.

File:CreateRule.png

Parameters: Our new created transformation rule now needs two parameters. To create this parameters, we need to call the createParameter method twice. This method takes the kind, the name and the type of parameter we want to specify. You can specify these by using their String representation.

File:CreateParameter.png

Note: The literals EInt, EDouble, EString... can not be derived from a String.

Until now we specified a transformation rule with two parameters.

File:RuleWithoutNodes.png

Nodes: Now that we have a transformation rule, we want to fill this rule with Nodes. To create a node inside a transformation rule, we call the createNode method. Again the class CRule can derive the Type of Node from its String representation.

File:CreateNode.png

The default Action when specifying a node is the <<preserve>> action. To specify another Action when creating a Node, we just add the Action to the parameters of createNode.

File:CreateNodeWithAction.png

As you can see, Actions can be parsed from a String too.

Attributes: To add an Attribute to our freshly created Nodes, we call the createAttribute method from the respective CNode. This method takes type and value of the attribute. By default an attribute inherits the Action from its container. If you want to change this, you can simply add another Action or parseable String as parameter for createAttribute.

File:CreateAttribute.png

Edges: The last part of the transformation Rules are the edges. To create the edges of our rule, we use createEdge. Again the type of the edge can be derived from its String representation.

File:Images/createEdge.png

Additional Elements

We successfully recreated the transformation rule createAccount using the "henshin.compact"-Package. To save our result into a .henshin-File, we simpyl call the save method in our CModule. This will save the Module either at the given filepath, or at the current working directory in a file that has the same name as the module itself.

After we created the transformation rule createAccount, we will now see, what other elements the other two transformation rules need and how to specify them using "henshin.compact"

AttributeConditions: The transformation rule transferMoney uses two attribute conditions. These are specified by the createAttributeCondition method in CRule.

File:CreateAttributeCondition.png

Updating Attributes: For some Attributes you want their value to change when the transformation rule is applied. To realize this you can use the operator -> inside of an attributes value String. The value to the left of the arrow will be the value before applying the rule. The value to the right of the arrow will be the value after applying the rule.

Multi-Rules: A Multi-Rule is a transformation rule nested inside another rule. The transformation specified by a Multi-Rule will be applied to all matching objects instead of just one specific match. The transformation rule deleteAllAccounts uses one Multi-Rule. To specify a Multi-Rule, you simply specify its elements, using the *-Operator at the end of the parseable Action String. </br><img src="images/MultiRule.png"></br> You can also specify a Multi-Rule path to create more complex constructs of different Multi-Rules. The Path of the rule an element is contained in is specified behind the *-operator.

File:MultiRulePath.png

NestedConditions: NestedConditions, by name NACs and PACs, are contained in the Lhs-Graph of a Rule. <<forbid>> Nodes and Edges are always part of NACs. <<require>> Nodes and Edges are always part of PACs. You can name the conditions they are contained in, by adding the #-Operator at the end of the parseable Action String. By default all conditions inside the Lhs-Graph are contained in a conjunktion. However, these conditions can be used to build bigger logical conditions. With CRule you can extract these conditions by using the methods getNAC and getPAC. Henshin provides logical operators to build up your own logical conditions.

File:AdvancedConditions.png

Specifying Units

Now that we can fully specify transformation rules, we want to put Units to use, to get the most out of our transformation rules. We will use the transformation Rules of the universitycourses example to create some of the Units used in the example.

The Class CModule provides a own method for every type of unit there is. We will now construct some Units to see how similar unit types are created.

UnaryUnit: As example for a UnaryUnit we use the LoopUnit cleanupUninterestingCoursesUnit.

File:UniversityCourses-cleanupUninterestingCoursesUnit.png

This unit is created by the createLoop method.

File:LoopUnit.png


ConditionalUnit: ConditionalUnits are a special case of unary Units. To create a ConditionalUnit you need to specify a If- and Then-Subunit. You can specify a Else-Subunit too but this is only optional. ConditionalUnits are the only unary unit type that does not derive its name by the name of its subunit. Therefore a name for the unit needs to be specified too.

File:ConditionalUnit.png


MultiUnits: Creating a multi unit uses the same method as adding subunits to this multi unit uses. The method will add the specified Unit to the subunits of the multi unit. The multi unit is given by its name. If no unit with the given name exists CModule will instead create the unit. For example, if we want to create incrementHour we can use the following code:

File:MultiUnit.png

Mapping Parameters

Some units have Parameters that need to get mapped between the unit and its subunits. To do this you call the method mapParameterToSubunit from the container CUnit. This method takes three names. The name of the parameter to be mapped, the name of the unit to be the target and finally the name of the parameter inside the target unit. For example, the mappings inside of incrementHour are created like this:

File:ParamMapping.png

Executing Units programmatically

Before we have learned how to specify transformation rules and unit using "henshin.compact". Now that we saved our specified Module into a .henshin-File, we can apply our rules. We will again use the Bank Example to show how to use the CInterpreter and CDebugger.

Before we can start applying our units, we need to load our Module and Graph. To load the resources we need a HenshinResourceSet and then load the Graph and the Module with the given methods.

File:LoadResources.png


Once we got our Resources we can then create a new CInterpreter. The CInterpreter is given a filepath. This filepath is the location, where the CInterpreter will later save the transformed graphs.

After we constructed our CInterpreter we can start executing our Units. Using the method executeUnit we only need to specify the Graph and Module instances to use. Additionally we need to specify the name of the unit we want to be applied, as well as a value for every parameter of this unit.

File:ExecuteUnit.png


Note: The list of parameter values must have the same order as the parameters inside of the unit, as well as the same typing

After applying the transformation the transformed graph gets returned. To save this graph back to a file, we simply call the saveGraph method in our CInterpreter.

File:SaveGraph.png"

CInterpreter vs CDebugger

If you only want to simply execute your transformation units, the CInterpreter will do everything you need. For more advanced operations like applying Rules on certain matches, you will need to use the CDebugger. The CDebugger class provides methods for undoing and redoing units, as well as choosing matches for your transformation rules. Once you created your desired match, you call the method executeRuleOnMatch, giving it the match to execute on.

Note: the undo and redo functions are not working correctly as for the date of March 5th, 2020

Back to the top