Example: Construct a workflow to orchestrate several Epsilon programs with Ant

<project default="showPath">
  
  <!-- Prepare our flowchart model for processing with Epsilon --> 
  <target name="loadFlowchartModel">
    <epsilon.emf.register file="../org.eclipse.epsilon.examples.metamodels/Flowchart.ecore" />
    <epsilon.emf.loadModel
      name="Flowchart"
      read="true"
      store="false"
      metamodeluri="flowchart"
      modelfile="models/wakeup.model"
    />
  </target>
  
  <!-- First check that our flowchart is well-formed -->
  <target name="validate" depends="loadFlowchartModel">
    <!-- Note that this task will fail if the model is not valid due to the failonerrors=true
         attribute. To see how an invalid model causes a failure, try changing 
         modelfile="models/wakeup.model" to modelfile="models/invalid.model" on line 11
      -->
    <epsilon.evl src="programs/validate_flowchart.evl" failonerrors="true">
      <model ref="Flowchart" />
    </epsilon.evl>
  </target>
  
  <!-- Next prepare a new and empty path model for use in the EOL and EGL scripts -->
  <target name="loadPathModel">
    <epsilon.emf.register file="metamodel/path.ecore" />
    <epsilon.emf.loadModel
      name="FlowchartPath"
      read="false"
      store="false"
      metamodeluri="path"
      modelfile="models/path.model"
    />
  </target>
  
  <!-- Invoke EOL to select a path through the flowchart, and then
       invoke EGL to transform the chosen path to HTML -->
  <target name="showPath" depends="validate,loadPathModel">
    <epsilon.eol src="programs/choose_path.eol">
      <model ref="Flowchart" />
      <model ref="FlowchartPath" />
    </epsilon.eol>
    
    <!-- Save the generated HTML in path.html -->
    <epsilon.egl src="programs/path_to_html.egl" target="path.html">
      <model ref="FlowchartPath" />
    </epsilon.egl>
    
    <!-- Force Eclipse to refresh our project so we can see the newly generated path.html file -->
    <eclipse.refreshLocal resource="org.eclipse.epsilon.examples.workflow.flowchart" depth="-1" />
  </target>
</project>
context Flowchart {
  constraint MustHaveOneStart {
    check  {
      var numberOfStartNodes = self.nodes.select(n|n.isStart()).size(); 
      return numberOfStartNodes == 1;
    }
    message : "There must be precisely 1 starting node, but there are " + numberOfStartNodes
  }
  
  constraint MustHaveAtLeastOneFinal {
    check  {
      var numberOfFinalNodes = self.nodes.select(n|n.isFinal()).size(); 
      return numberOfFinalNodes >= 1;
    }
    message : "There must be at least 1 final node, but there are " + numberOfFinalNodes
  }
}

operation Flowchart!Node isStart() : Boolean {
  return self.incoming.isEmpty(); 
}

operation Flowchart!Node isFinal() : Boolean {
  return self.outgoing.isEmpty();
}
// Create an empty path
var path = new FlowchartPath!Path;

// Find the start node
var start : Flowchart!Node = Flowchart!Node.all.selectOne(n|n.isStart());
var current : Flowchart!Node = start;

// Walk through the flowchart until we reach a final state
while (not current.isFinal()) {
  // Create a stop on the path for this node
  var stop = new FlowchartPath!Stop;
  stop.label = current.type.name + " " + current.name;
  path.stops.add(stop);
  
  // Select an outgoing transition at random
  var chosenTransition = current.outgoing.random();

  // Continue with the node from the chosen outgoing transition
  current = chosenTransition.target;
}

operation Flowchart!Node isStart() : Boolean {
  return self.incoming.isEmpty(); 
}

operation Flowchart!Node isFinal() : Boolean {
  return self.outgoing.isEmpty();
}
[% var path : FlowchartPath!Path = FlowchartPath!Path.all.first; %]
<html>
<body>
  <h1>The chosen path was:</h1>
  <ol>
    [% for (stop in path.stops) { %]
    <li>[%=stop.label%]</li>
    [% } %]
  </ol>
</body>
</html>

Check out the code from the SVN:

  • go to the SVN repository
  • navigate to trunk/examples
  • check out the org.eclipse.epsilon.examples.workflow.flowchart project

Once you have checked out/imported the code, to run the example you need to go through the following steps:

  1. register any .ecore metamodels in the org.eclipse.epsilon.examples.workflow.flowchart project
  2. right click the .launch file in the org.eclipse.epsilon.examples.workflow.flowchart project
  3. select Run as... and click the first item in the menu that pops up

What's this?

In this example we demonstrate how to use the built-in Epsilon Ant tasks to define a workflow by combining several Epsilon programs. Here, we validate, transform and generate HTML from a flowchart model.

What are .emf files?

.emf files are Ecore metamodels expressed using the Emfatic textual syntax.

More examples...

Epsilon Object Language
Epsilon Transformation Language
Epsilon Generation Language
Epsilon Validation Language
Epsilon Merging Language
Epsilon Flock
Combining the Epsilon Languages
EuGENia
EUnit

Even more examples...

More examples are available in the examples folder of the SVN repository.