Running Epsilon from Java¶
While Epsilon's development tools are based on Eclipse, its runtime is not, and can be used from any (headless) Java application. For example, the back-end of the Epsilon Playground is a headless, server-less Java application that runs on Google's Cloud Platform.
Did you know that ...
Contrary to popular belief, EMF is not tightly coupled to the Eclipse IDE either, and can also be embedded in any Java application by importing a couple of dependencies from Maven Central.
Dependencies¶
Epsilon libraries are available on MavenCentral. Below is a fragment of a Maven pom.xml
file, where we declare dependencies to the execution engine of Epsilon's core expression language and on Epsilon's driver for EMF-based models. As the EMF driver has a dependency on EMF, we don't need to declare a dependency to the EMF libraries on MavenCentral; Maven will fetch these automatically for us.
<dependencies>
<dependency>
<groupId>org.eclipse.epsilon</groupId>
<artifactId>org.eclipse.epsilon.emc.emf</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.epsilon</groupId>
<artifactId>org.eclipse.epsilon.eol.engine</artifactId>
<version>2.2.0</version>
</dependency>
...
</dependencies>
Parsing and Executing Epsilon Programs¶
Having declared a dependency to the EOL engine, parsing and executing an EOL program is as simple as that.
EolModule module = new EolModule();
module.parse(new File("program.eol"));
module.execute();
Tip
By replacing EolModule
with EtlModule
, EvlModule
etc. you can parse and execute ETL transformations, EVL validation constraints etc. EGL deviates from this pattern and if you wish to execute a single template you should use the EglTemplateFactoryModuleAdapter
class.
Loading Models¶
Most of your Epsilon programs will need to run against models of some sort. To run an EOL program against a model (model.xmi
) that conforms to a file-based Ecore metamodel (metamodel.ecore
), you can extend the code above as follows.
// Loads the EMF model
EmfModel model = new EmfModel();
model.setMetamodelFile("metamodel.ecore");
model.setModelFile("model.xmi");
// Set the name by which the model will be
// referred to in the program. Useful if
// the program manages more than one models
model.setName("M");
// Read the contents of the model from disk
// when the model is loaded. Set to false
// to ignore existing model contents (e.g.
// if the model is the target of a
// model-to-text transformation)
model.setReadOnLoad(true);
// Save any changes made to the model
// when it is disposed
model.setStoredOnDisposal(true);
model.load();
// Parses and executes the EOL program
EolModule module = new EolModule();
module.parse(new File("program.eol"));
// Makes the model accessible from the program
module.getContext().getModelRepository().addModel(model);
module.execute();
// Saves any changes to the model
// and unloads it from memory
// Use model.getContext().
// getModelRepository().dispose()
// instead if multiple models are involved
model.dispose();
Adding Variables¶
You can add variables to your Epsilon program and provide their values from Java as shown below.
EolModule module = new EolModule();
module.parse("s.println();");
module.getContext().getFrameStack().put(Variable.
createReadOnlyVariable("s", "Hello World"));
module.execute();
Using Tools Contributed by Plugins¶
To use tools contributed by other plugins in a standalone Java setup within Eclipse you'll need to add the following line of code.
context.getNativeTypeDelegates().
add(new ExtensionPointToolNativeTypeDelegate());
Analysing Epsilon Programs¶
Epsilon programs do not have an Ecore-based metamodel, but you can query and analyse them through Epsilon's Java API as shown below.
// Parse an ETL transformation
EtlModule m = new EtlModule();
m.parse("rule A2B transform a : In!A to b : Out!B { b.name = a.name; }");
// Get the first rule of the transformation
TransformationRule a2b = m.getTransformationRules().get(0);
// Print its name
System.out.println(a2b.getName());
// Get the body of the A2B rule
StatementBlock body = (StatementBlock) a2b.getBody().getBody();
// Print the number of statements it contains
System.out.println(body.getStatements().size());
As of version 2.3, Epsilon programs can also be analysed using visitors. As an example, see the EolUnparser
class which recursively visits the contents of an EolModule
and pretty-prints it. To implement your own analyser, you will need to implement the IEolVisitor
interface for EOL, or the respective IE*lVisitor
interfaces for other Epsilon-based languages. Using a combination of E*lUnparser
and your custom visitor, you can easily rewrite Epsilon programs too.
EolModule module = new EolModule();
module.parse("'Hello world'.println();");
EolUnparser unparser = new EolUnparser();
// Prints "Hello world".println();
System.out.println(unparser.unparse(module));
Debugging Epsilon Programs¶
To debug Epsilon programs being executed from a Java program, read these instructions.
More Examples¶
In Epsilon's Git repository, there are two example projects that show how to run Epsilon from Java, and the ANT Epsilon tasks in a headless environment (i.e. from command line).