Difference between revisions of "Henshin Interpreter"

From Eclipsepedia

Jump to: navigation, search
Line 17: Line 17:
 
== Interpreter API ==
 
== Interpreter API ==
  
The interpreter can be also invoked programatically. To do this, you need to set up an Eclipse Plug-In including a dependency to the Henshin run-time.
+
The interpreter can be also invoked programatically, either as an IApplication in Eclipse or as a simple stand-alone Java app.
  
=== Setting up the Plug-In Project ===
+
Make sure you have all dependencies fulfilled to the Henshin runtime and to EMF. Then you can invoke the interpreter as shown below. The shown example is a benchmark for the [http://www.eclipse.org/modeling/emft/henshin/examples.php?example=BankAccounts Sierpinski example] as available in the examples plug-in.
 
+
If you want to create a new plug-in from scratch, go to ''New...→Other...→Plug-in Development→Plug-in Project'' and follow the wizard.
+
 
+
If you have an existing project which is not a plug-in project (e.g. just a Java project), right-click on the project in the Package Explorer and select ''Configure→Convert to Plug-in projects...''.
+
 
+
Now you need to make sure that the dependency to the Henshin interpreter plug-in is set. For this, open either the ''plugin.xml'' or the ''META-INF/MANIFEST.MF'' file in your project and click on the ''Dependencies'' tab. If it is not yet listed there, add the following plug-in dependencies
+
* ''org.eclipse.core.runtime''
+
* ''org.eclipse.core.resources''
+
* ''org.eclipse.emf.ecore''
+
* ''org.eclipse.emf.ecore.xmi''
+
* ''org.eclipse.emf.henshin.interpreter''
+
When you are done, save and close the file.
+
 
+
=== Invoking the Interpreter ===
+
 
+
In your Java class, e.g. an IApplication (see [http://www.eclipsezone.com/eclipse/forums/t99762.html here] for a hello world example) you can now invoke the interpreter as follows.
+
  
 
<source lang="java">
 
<source lang="java">
import org.eclipse.equinox.app.IApplication;
+
import java.util.List;
import org.eclipse.equinox.app.IApplicationContext;
+
  
 
import org.eclipse.emf.ecore.EObject;
 
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
 
 
import org.eclipse.emf.henshin.interpreter.EmfEngine;
 
import org.eclipse.emf.henshin.interpreter.EmfEngine;
 
import org.eclipse.emf.henshin.interpreter.RuleApplication;
 
import org.eclipse.emf.henshin.interpreter.RuleApplication;
 
import org.eclipse.emf.henshin.interpreter.util.Match;
 
import org.eclipse.emf.henshin.interpreter.util.Match;
import org.eclipse.emf.henshin.interpreter.util.ModelHelper;
 
 
import org.eclipse.emf.henshin.matching.EmfGraph;
 
import org.eclipse.emf.henshin.matching.EmfGraph;
 
import org.eclipse.emf.henshin.model.Rule;
 
import org.eclipse.emf.henshin.model.Rule;
 
import org.eclipse.emf.henshin.model.TransformationSystem;
 
import org.eclipse.emf.henshin.model.TransformationSystem;
import org.eclipse.emf.henshin.model.impl.HenshinPackageImpl;
+
import org.eclipse.emf.henshin.model.resource.HenshinResourceSet;
  
public class MyTransformation implements IApplication {
+
/**
 +
* A benchmark constructing multiple levels of a Sierpinski triangle.
 +
*
 +
* @see <a href="http://en.wikipedia.org/wiki/Sierpinski_triangle">Sierpinski Triangle</a>
 +
*/
 +
public class SierpinskiBenchmark {
  
   public Object start(IApplicationContext context) throws Exception {
+
   public static void main(String[] args) {
  
     // Register file extensions:
+
     // Create a resource set:
     ModelHelper.registerFileExtension("henshin");  
+
     HenshinResourceSet resourceSet = new HenshinResourceSet();
    // You may need to register the extensions of your model files here too
+
 
+
     // Register the dynamic package:
     // Register packages:
+
     resourceSet.registerEPackages("src/org/eclipse/emf/henshin/examples/sierpinski/model/sierpinski.ecore");
     HenshinPackageImpl.init();
+
    // Add your generated packages here...
+
  
 
     // Load the transformation system:
 
     // Load the transformation system:
     TransformationSystem trans = (TransformationSystem) ModelHelper.loadFile("model/myTransformation.henshin");
+
     TransformationSystem trasys = resourceSet.getTransformationSystem("src/org/eclipse/emf/henshin/examples/sierpinski/model/sierpinski.henshin");
 
+
    // Load the model to be transformed:
+
    EObject root = ModelHelper.loadFile("model/myModel.xmi"); // or another registered file extension
+
  
 +
    // Load the first level of the Sierpinski triangle:
 +
    EObject container = resourceSet.getFirstRoot("src/org/eclipse/emf/henshin/examples/sierpinski/model/sierpinski-start.xmi");
 +
 
     // Initialize the Henshin interpreter:
 
     // Initialize the Henshin interpreter:
     EmfGraph graph = new EmfGraph();
+
     EmfGraph graph = new EmfGraph(container);
     graph.addRoot(root);
+
     graph.removeEObject(container);
   
+
 
     EmfEngine engine = new EmfEngine(graph);
 
     EmfEngine engine = new EmfEngine(graph);
  
     // Load a rule (or a transformation unit)
+
     // Load the rule:
     Rule myRule = trans.findRuleByName("MyRule");
+
     Rule addTriangleRule = trasys.findRuleByName("AddTriangle");
 
+
    // Create a RuleApplication (or UnitApplication)
+
    RuleApplication application = new RuleApplication(engine, myRule);
+
 
+
    // Optionally set parameters using application.setParameterValue(param, value)
+
 
+
    // Find a match:
+
    Match match = myRule.findMatch();
+
    if (match!=null) {
+
 
+
      // Apply the rule:
+
      application.setMatch(match);
+
      application.apply();
+
 
+
      // Save the transformed model to a file:
+
      ModelHelper.saveFile("model/transformed.xmi", root);
+
 
+
    } else {
+
      System.out.println("Rule " + myRule.getName() + " not applicable");
+
    }
+
  
     return IApplication.EXIT_OK;
+
     System.out.println(Runtime.getRuntime().maxMemory() / (1024 * 1024) + "MB available memory\n");
  }
+
 +
    // Iteratively compute the Sierpinski triangle:
 +
    int i = 1;
 +
    while (true) {
 +
 +
// Find all matches:
 +
long startTime = System.nanoTime();
 +
RuleApplication addTriangle = new RuleApplication(engine, addTriangleRule);
 +
List<Match> matches = addTriangle.findAllMatches();
 +
long matchingTime = (System.nanoTime() - startTime) / 1000000;
 +
 +
System.out.println("Level: " + i);
 +
System.out.println("Rule applications:" + matches.size());
 +
System.out.println("Matching: " + matchingTime + "ms");
  
  public void stop() {
+
// Apply rule with all matches:
  }
+
startTime = System.nanoTime();
 +
for (Match match : matches) {
 +
    addTriangle = new RuleApplication(engine, addTriangleRule);
 +
    addTriangle.setMatch(match);
 +
    addTriangle.apply();
 +
}
 +
long runtime = (System.nanoTime() - startTime) / 1000000;
  
 +
System.out.println("Application: " + runtime + "ms");
 +
System.out.println("Total: " + (matchingTime + runtime) + "ms");
 +
System.out.println("Nodes: " + graph.geteObjects().size());
 +
System.out.println();
 +
i++;
 +
 +
}
 +
    }
 
}
 
}
 
</source>
 
</source>
  
 
If something goes wrong, you can always use the Eclipse debugger to find out what's going on (see [http://www.vogella.de/articles/EclipseDebugging/article.html here] for a tutorial).
 
If something goes wrong, you can always use the Eclipse debugger to find out what's going on (see [http://www.vogella.de/articles/EclipseDebugging/article.html here] for a tutorial).

Revision as of 15:21, 1 April 2012

The Henshin interpreter is the default engine for executing model transformations defined in Henshin. The interpreter can be invoked either using a wizard or programmatically.

Interpreter Wizard

Henshin Interpreter Wizard

The interpreter wizard can be invoked by a right-click on a *.henshin file in the Package Explorer and selecting Henshin→Apply with Henshin.

In the first page of the wizard, you need to enter the following information:

  • Choose a transformation rule or unit to be applied.
  • Specify a model file to be transformed using the rule or unit.
  • Enter possible parameters of the rule or unit. Make sure that the type of the parameters is correctly set. Ignore means that the parameter is not set and will be matched automatically by the interpreter.

If you click Preview you should either see the modifications to the model or get a message that the rule or unit could not be applied. If you think it should be applicable but still get a message that it is not, make sure the parameters are all correctly set including their types.

If you click Transform the model will be transformed and saved, if possible.

Interpreter API

The interpreter can be also invoked programatically, either as an IApplication in Eclipse or as a simple stand-alone Java app.

Make sure you have all dependencies fulfilled to the Henshin runtime and to EMF. Then you can invoke the interpreter as shown below. The shown example is a benchmark for the Sierpinski example as available in the examples plug-in.

import java.util.List;
 
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.henshin.interpreter.EmfEngine;
import org.eclipse.emf.henshin.interpreter.RuleApplication;
import org.eclipse.emf.henshin.interpreter.util.Match;
import org.eclipse.emf.henshin.matching.EmfGraph;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.model.TransformationSystem;
import org.eclipse.emf.henshin.model.resource.HenshinResourceSet;
 
/**
 * A benchmark constructing multiple levels of a Sierpinski triangle.
 * 
 * @see <a href="http://en.wikipedia.org/wiki/Sierpinski_triangle">Sierpinski Triangle</a>
 */
public class SierpinskiBenchmark {
 
  public static void main(String[] args) {
 
    // Create a resource set:
    HenshinResourceSet resourceSet = new HenshinResourceSet();
 
    // Register the dynamic package:
    resourceSet.registerEPackages("src/org/eclipse/emf/henshin/examples/sierpinski/model/sierpinski.ecore");
 
    // Load the transformation system:
    TransformationSystem trasys = resourceSet.getTransformationSystem("src/org/eclipse/emf/henshin/examples/sierpinski/model/sierpinski.henshin");
 
    // Load the first level of the Sierpinski triangle:
    EObject container = resourceSet.getFirstRoot("src/org/eclipse/emf/henshin/examples/sierpinski/model/sierpinski-start.xmi");
 
    // Initialize the Henshin interpreter:
    EmfGraph graph = new EmfGraph(container);
    graph.removeEObject(container);
    EmfEngine engine = new EmfEngine(graph);
 
    // Load the rule:
    Rule addTriangleRule = trasys.findRuleByName("AddTriangle");
 
    System.out.println(Runtime.getRuntime().maxMemory() / (1024 * 1024) + "MB available memory\n");
 
    // Iteratively compute the Sierpinski triangle:
    int i = 1;
    while (true) {
 
	// Find all matches:
	long startTime = System.nanoTime();
	RuleApplication addTriangle = new RuleApplication(engine, addTriangleRule);
	List<Match> matches = addTriangle.findAllMatches();
	long matchingTime = (System.nanoTime() - startTime) / 1000000;
 
	System.out.println("Level: " + i);
	System.out.println("Rule applications:" + matches.size());
	System.out.println("Matching: " + matchingTime + "ms");
 
	// Apply rule with all matches:
	startTime = System.nanoTime();
	for (Match match : matches) {
	    addTriangle = new RuleApplication(engine, addTriangleRule);
	    addTriangle.setMatch(match);
	    addTriangle.apply();
	}
	long runtime = (System.nanoTime() - startTime) / 1000000;
 
	System.out.println("Application: " + runtime + "ms");
	System.out.println("Total: " + (matchingTime + runtime) + "ms");
	System.out.println("Nodes: " + graph.geteObjects().size());
	System.out.println();
	i++;
 
	}	
    }	
}

If something goes wrong, you can always use the Eclipse debugger to find out what's going on (see here for a tutorial).