Generating code with Xtend and Xtext triggered from the Eclipse context menu
This page explains how you can generate code from Ecore-based models using the Xtend language and the Xtext generator infrastructure. The important difference to usual code generation with Xtext is that the generation is triggered from the navigator context menu of Eclipse.
Why Xtext's Generator Infrastructure?
With the interfaces for generators, generator modules, and file system access the Xtext API makes it very convenient to generate Code for a given EMF Resource. You only have to specify which content you want to generate and the URIs of the files that contain should contain it.
Why not a normal Xtext project?
If you generate code for an Ecore metamodel that was not created with Xtext, then a normal Xtext project brings a lot of code an functionality that you do not need. If you do not want to trigger your generator each time a file of an Xtext-based DSL is saved but only when a specific command is used, then you do not need all the code of an Xtext project but only the part that eases the handling of input resources and output files.
Why sdq.commons.ecore2txt?
With this very small plug-in project we tried to give you only the code that is needed every time you want to generate any text files from Ecore-based models triggered by a context menu entry. And nothing more.
How to use it?
- Check out and import the commons.ecore2txt plug-in project from svn (user:anonymous, password:anonymous).
- Create a new plug-in project for your generator.
- Create a generator that extends the
IGenerator
interface. - Create a generator module that extends
AbstractEcore2TxtGeneratorModule
and provides thegetLanguageName
andgetFileExtensions
methods. - Create a handler that extends
AbstractEcore2TxtHandler
and provides theexecuteEcore2TxtGenerator
method.- You can easily implement this method by calling
Ecore2TxtUtil.generateFromSelectedFilesInFolder(files,new YourOwnGeneratorModule(),new YourOwnGenerator(),"yourGenerationTargetFolderName")
- You can easily implement this method by calling
- Let your generator plug-in provide the following extensions
<extension
point="org.eclipse.ui.commands">
<command
defaultHandler="tld.domain.yourhandler"
id="tld.domain.yourcodegencommand"
name="Create Your Code">
</command>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="popup:org.eclipse.ui.popup.any?after=additions">
<menu
id="yourmenu"
label="Your Submenu label">
<command
commandId="tld.domain.yourcodegencommand"
label="Create Your Code"
style="push"
tooltip="Create Code that ...">
</command>
<visibleWhen
checkEnabled="false">
<with
variable="activeMenuSelection">
<iterate>
<adapt type="org.eclipse.core.resources.IResource">
<or>
<test
property="org.eclipse.core.resources.name"
value="*.yourFileExt1">
</test>
<test
property="org.eclipse.core.resources.name"
value="*.yourFileExt2">
</test>
</or>
</adapt>
</iterate>
</with>
</visibleWhen>
</menu>
</menuContribution>
</extension>
A more detailed but also more complex tutorial that was used to build the ecore2txt plug-in was written by Christian Dietrich
What to copy and adapt?
YourGenerator:
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.generator.IGenerator
class YourGenerator implements IGenerator {
override doGenerate(Resource input, IFileSystemAccess fsa) {
val fileURI = ...
val contents = yourContentGeneration(input)
fsa.generateFile(fileURI, contents)
}
}
YourGeneratorModule:
import edu.kit.ipd.sdq.commons.ecore2txt.generator.AbstractEcore2TxtGeneratorModule
class YourGeneratorModule extends AbstractEcore2TxtGeneratorModule {
override protected String getLanguageName() {
...
}
override protected String getFileExtensions() {
...
}
}
YourGeneratorHandler:
import org.eclipse.core.resources.IFile;
import edu.kit.ipd.sdq.commons.ecore2txt.handler.AbstractEcore2TxtHandler;
import edu.kit.ipd.sdq.commons.ecore2txt.util.Ecore2TxtUtil;
import YourGenerator;
import YourModule;
public class YourGeneratorHandler extends AbstractEcore2TxtHandler {
@Override
public void executeEcore2TxtGenerator(Iterable<IFile> files) {
Ecore2TxtUtil.generateFromSelectedFilesInFolder(files,new YourGeneratorModule(),new YourGenerator(),"src-gen");
}
}