Skip to content

Eclipse Epsilon

Epsilon is a family of scripting languages and tools for automating common model-based software engineering tasks such as code generation, model-to-model transformation, model validation and model visualisation, that work out of the box with EMF (including Xtext and Sirius), UML (including Cameo/MagicDraw), Simulink, XML and other types of models.

Epsilon can be used as a standard Java library, and also provides Apache Ant tasks that can be embedded in Maven/Gradle build files. Editing support for Epsilon programs is available in Eclipse, VS Code, Intellij, TextMate and Sublime.

Online Playground

You can try out the examples below from your browser in the online Epsilon Playground. No installation required!

[*For every person*]
[%for (p in Person.all){%]

[*Generate a <h1> with the name of the person*]
<h1>[%=p.name%]'s Tasks</h1>

[*Generate a table for the person's tasks*]
<table>
[*For every task*]
[%for (t in p.getTasks()){%]
    [*Generate a row with the title of the task*]
    <tr>
        <td>[%=t.title%]</td>
    </tr>
[%}%]
</table>

[%}%]

[%
// Returns the tasks of a person
operation Person getTasks() {
    return Task.all.select(
        t|t.effort.exists(e|e.person = self));
}
%]
// For every task
context Task {

    // Check that the start month is positive
    constraint ValidStart {
        check: self.start > 0
        message: "The start month of a task must be positive"
    }

    // Check that the duration is positive
    constraint ValidDuration {
        check: self.duration > 0
        message: "The duration of a task must be positive"
    }

    // Check that the duration is no more than 12 months
    constraint TaskNotTooLong {
        check: self.duration <= 12
        message: "The duration of a task must not exceed 12 months"
    }

}

// For every person
context Person {

    // Check that the person is involved
    // in at least one task
    critique IsInvolvedInATask {
        check: Effort.all.
            exists(e|e.person = self)

        message: self.name + 
            " is not involved in the project"
    }

}
rule Project2Project
    transform s : Source!Project
    to t : Target!Project {

    t.title = s.title;

    // Transform the tasks of the source
    // project using the Task2Deliverable
    // rule and assign the result to
    // t.deliverables
    t.deliverables ::= s.tasks;
}

// Transform each task to a deliverable
// to be submitted at the end of the task
rule Task2Deliverable
    transform t : Source!Task
    to d : Target!Deliverable {

    d.title = t.title + " Report";
    d.due = t.start + t.duration;

    // The lead of the deliverable
    // is the person with the highest
    // effort in the task
    d.lead ::= t.effort.sortBy(e|-e.percentage).
        first()?.person;
}

// @lazy means that persons will be transformed 
// only upon request. As such, Charlie will not 
// appear in the target model because he leads
// no deliverables
@lazy
rule Person2Person
    transform s : Source!Person
    to t : Target!Person {

    t.name = s.name;
}
@namespace(uri="psl")
package psl;

class Project {
    attr String title;
    attr String description;
    val Task[*] tasks;
    val Person[*] people;
}

class Task {
    attr String title;
    attr int start;
    attr int duration;
    val Effort[*] effort;
}

class Person {
    attr String name;
}

class Effort {
    ref Person person;
    attr int percentage = 100;
}
<?nsuri psl?>
<project title="ACME">
    <person name="Alice"/>
    <person name="Bob"/>
    <task title="Analysis" start="1" dur="3">
        <effort person="Alice"/>
    </task>
    <task title="Design" start="4" dur="6">
        <effort person="Bob"/>
    </task>
    <task title="Implementation" start="7" dur="3">
        <effort person="Bob" perc="50"/>
        <effort person="Alice" perc="50"/>
    </task>
</project>
package org.eclipse.epsilon.examples;

import java.io.File;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.emfatic.core.EmfaticResourceFactory;
import org.eclipse.epsilon.egl.EgxModule;
import org.eclipse.epsilon.emc.emf.EmfModel;
import org.eclipse.epsilon.flexmi.FlexmiResourceFactory;

public class Example {

    public static void main(String[] args) throws Exception {

        // Register the Flexmi and Emfatic parsers with EMF
        Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("flexmi", new FlexmiResourceFactory());
        Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("emf", new EmfaticResourceFactory());

        // Parse the EGX transformation and configure it to produce
        // its output files in the root directory of the project
        EgxModule module = new EgxModule(new File(".").getAbsolutePath());
        module.parse(new File("program.egx"));

        // Load the model from model.flexmi using metamodel.emf as its metamodel
        EmfModel model = new EmfModel();
        model.setName("M");
        model.setModelFile(new File("model.flexmi").getAbsolutePath());
        model.setMetamodelFile(new File("metamodel.emf").getAbsolutePath());
        model.setReadOnLoad(true);
        model.setStoredOnDisposal(false);
        model.load();

        // Make the model available to the transformation
        module.getContext().getModelRepository().addModel(model);

        // Execute the EGX transformation
        module.execute();

        // Dispose of the model
        module.getContext().getModelRepository().dispose();
    }
}

Why Epsilon?

  • One syntax to rule them all: All languages in Epsilon build on top of a common expression language which means that you can reuse code across your model-to-model transformations, code generators, validation constraints etc.
  • Integrated development tools: All languages in Epsilon are supported by editors providing syntax and error highlighting, code templates, and graphical tools for configuring, running, debugging and profiling Epsilon programs.
  • Documentation, Documentation, Documentation: More than 80 articles, 15 screencasts and 40 examples are available to help you get from novice to expert.
  • Strong support for EMF: Epsilon supports all flavours of EMF, including reflective, generated and non-XMI (textual) models such as these specified using Xtext-based DSLs.
  • No EMF? No problem: While Epsilon provides strong support for EMF, it is not bound to EMF at all. In fact, support for EMF is implemented as a driver for the model connectivity layer of Epsilon. Other drivers provide support for XML, CSV, Excel, Simulink and you can even roll out your own driver!
  • No Eclipse? No problem: While Epsilon provides strong support for Eclipse, we also provide standalone JARs through Maven Central that you can use to embed Epsilon in your plain Java or Android application.
  • Mix and match: Epsilon poses no constraints on the number/type of models you can use in the same program. For example, you can write a transformation that transforms an XML-based and an EMF-based model into a Simulink model and also modifies the source EMF model.
  • Plumbing included: You can use the ANT Epsilon tasks to compose Epsilon programs into complex workflows. Programs executed in the same workflow can share models and even pass parameters to each other.
  • Extensible: Almost every aspect of Epsilon is extensible. You can add support for your own type of models, extend the Eclipse-based development tools, add a new method to the String type, or even implement your own model management language on top of EOL.
  • Java is your friend: You can call methods of Java classes from all Epsilon programs to reuse code you have already written or to perform tasks that Epsilon languages do not support natively.
  • Parallel execution: Since 2.0, Epsilon is multi-threaded, which includes first-order operations and some of the rule-based languages, making it faster than other interpreted tools.
  • All questions answered: The Epsilon forum contains more than 10K posts and we're proud that no question has ever gone unanswered.
  • We're working on it: Epsilon has been an Eclipse project since 2006 and it's not going away any time soon.

License

Epsilon is licensed under the Eclipse Public License 2.0.

Trademarks

Eclipse Epsilon and the Eclipse Epsilon project logo are trademarks of the Eclipse Foundation. Eclipse and the Eclipse logo are registered trademarks of the Eclipse Foundation.

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

Acknowledgements

We would like to thank ej-technologies for providing us with free licenses of their powerful JProfiler Java profiler.