Search code examples
javamavenxtext

Building XText 2.0 and XPand 1.1 with Maven


I am looking for an example pom.xml for an project using XText 2.0, especially the code generator XPand 1.1 in a "plain" maven project.

I already spend time with google, but may I use the wrong terms, or there is no example.

I have an already working pom for xtext 0.7.2 and I want to update the project to 2.0. but I don't know where to start. What I have at the moment is this structure of 4 maven projects:

  • mydsl
  • mydsl.generator (not used)
  • mydsl.ui
  • application (containing xpand templates to generate code)

The mydsl projects are xtext 0.7.2 projects with and additional pom in (mydsl) that provides the generated classes as maven dependency.

The application has a mwe workflow and xpand template to generate source code. This project has a maven dependency to mydsl

Because I have not implemented so many gui editor functionality I would even except to throw all the xtext stuff away (except the grammer and xpand templates) and build a complete new xtext 2 project.

But I have really no glue how to build the pom for the (new) mydsl project.


Solution

  • One of the most trickiest parts is that in an XText2 grammer project there will be a file in xtend-gen folder woth name <<project>>Generator.java. That file is not created by the Generate<<project>>.mwe2 workflow, instead it seams that it is created by some eclipse magic. But this file is needed to compile the code!

    So my solution is to let eclipse generate that file, and then add it to the svn like any normal hand written class.

    Then one only need to add this pom to the project. So maven will start the Workflow too. But there is one drawback: the workflow also generate the classes for the neighbour projects, .ui and .test and therefor it needs there manifest files. To overcome the trouble of the maven release plugin, one could add a parent maven project, that contains the grammer project and the two dummies .ui and .test

    Pom of project containing the xtext grammer:

    ...
    <dependencies>
        <dependency>
            <groupId>org.eclipse.plugins</groupId>
            <artifactId>org.eclipse.xtext.generator</artifactId>
            <version>2.0.0.v201106070531</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.plugins</groupId>
            <artifactId>org.eclipse.emf.codegen.ecore</artifactId>
            <version>2.6.1.v20100914-1218</version>
        </dependency>
        <dependency>
            <groupId>org.antlr.generator</groupId>
            <artifactId>org.antlr.generator</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.plugins</groupId>
            <artifactId>org.eclipse.emf.mwe2.launch</artifactId>
            <version>2.0.0.v201106070634</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.13</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <resources>
            <resource>
                <directory>src</directory>
            </resource>
            <resource>
                <directory>src-gen</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>${basedir}/src-gen</directory>
                            <includes>
                                <include>com/</include>
                                <include>org/</include>
                            </includes>
                            <followSymlinks>false</followSymlinks>
                        </fileset>
                        <fileset>
                            <directory>${basedir}/xtend-gen</directory>
                            <includes>
                                <include>com/</include>
                                <include>org/</include>
                            </includes>
                            <excludes>
                                <exclude>**/ProdDef2Generator.java</exclude>
                            </excludes>
                            <followSymlinks>false</followSymlinks>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.fornax.toolsupport</groupId>
                <artifactId>fornax-oaw-m2-plugin</artifactId>
                <version>3.2.1</version>
    
                <configuration>
                    <!-- <checkResources> <checkResource> src/com\queomedia\bcsweb\productdefinition\ProdDef2.xtext 
                        </checkResource> </checkResources> -->
                    <outletSrcDir>src-gen</outletSrcDir>
                    <outletSrcOnceDir>src</outletSrcOnceDir>
                    <rootDir>${project.basedir}</rootDir>
                </configuration>
                <executions>
                    <execution>
                        <id>generateGrammer</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run-workflow</goal>
                        </goals>
    
    
                        <configuration>
                            <workflowDescriptor>src/org/test/test/GenerateProdDef2.mwe2</workflowDescriptor>
                            <workflowEngine>mwe2</workflowEngine>
                            <timestampFileName>generator-generateGrammer-timestamp.tmp</timestampFileName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    
    
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.3</version>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>src-gen</source>
                                <source>xtend-gen</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    
            <!-- The plugin.xml must be included, but is not on a resource path -->
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>process-resources</phase>
                        <configuration>
                            <tasks>
                                <copy todir="${basedir}/target/classes" file="${basedir}/plugin.xml" />
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    

    POM of the project that uses the grammer and a dsl for source code generation. This is nearly the same as it was for xtext 0.7.1. But with one difference. The MweReader used in the mwe file does not exit any more (since xtext 1.0.1) So one need to use the org.eclipse.xtext.mwe.Reader. This reader not longer take the model file as input, but the path to the file. And it also stores it in a so called "slot". But this slot is an LIST of elements. So one need to change: the FOR in <expand value="templates::Main::main FOR model"/> to FOREACH

    <dependencies>
    
        <dependency>
            <groupId>test.xtext</groupId>           
            <artifactId>grammerProject</artifactId>         
            <version>1.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.plugins</groupId>
            <artifactId>org.eclipse.xtext.generator</artifactId>
            <version>2.0.0.v201106070531</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.plugins</groupId>
            <artifactId>org.eclipse.emf.codegen.ecore</artifactId>
            <version>2.6.1.v20100914-1218</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.antlr.generator</groupId>
            <artifactId>org.antlr.generator</artifactId>
            <version>3.2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.plugins</groupId>
            <artifactId>org.eclipse.emf.mwe2.launch</artifactId>
            <version>2.0.0.v201106070634</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.13</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
            <!-- there is the .mwe workflow located, in a sub dir called model, the dsl and in an other sub dir called templates, the xpt files. -->
                <directory>src/main/xtext</directory>               
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.fornax.toolsupport</groupId>
                <artifactId>fornax-oaw-m2-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
    
                    <rootDir>${project.basedir}</rootDir>
    
                    <!--  run only if this file is changed -->
                    <checkResources>
                        <checkResource>
                            src/main/xtext/model/GermanDesk.proddef2
                        </checkResource>
                    </checkResources>
                    <!--  
                    <outletSrcDir>src-gen</outletSrcDir>
                    <outletSrcOnceDir>src</outletSrcOnceDir>
                    -->                 
                </configuration>
                <executions>
                    <execution>
                        <id>generateJavaClassesFromXText</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run-workflow</goal>
                        </goals>
                        <configuration>
                            <!-- Die Workflow-Description wird in einem Ressourcen-Verzeichnis gesucht. -->
                            <workflowDescriptor>ProdDef2JavaGenerator.mwe</workflowDescriptor>
                            <workflowEngine>mwe</workflowEngine>
                            <properties>
                                <projectBasedir>${project.basedir}</projectBasedir>
                            </properties>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>     
                            <sources>
                                <source>${basedir}/target/generated-sources</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    

    Mwe workflow in that project

    <workflow>  
        <property name="project.src.directory" value="${projectBasedir}/src/main"/>
        <property name="project.target.directory" value="${projectBasedir}/target"/>
    
        <property name="modelFileDir" value="${project.src.directory}/xtext/model/"/>   
        <property name="srcGenTargetDir" value="${project.target.directory}/generated-sources"/>    
        <property name="templateTargetDir" value="${project.target.directory}/generated-sources-templates"/>
    
        <bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" platformUri=".."/>
    
        <component class="org.eclipse.emf.mwe.utils.DirectoryCleaner" directory="${srcGenTargetDir}"/>
        <component class="org.eclipse.emf.mwe.utils.DirectoryCleaner" directory="${templateTargetDir}"/>
        <component class="org.eclipse.xtext.mwe.Reader" path="${modelFileDir}" >
            <register class="com.queomedia.bcsweb.productdefinition.ProdDef2StandaloneSetup"/>
            <load slot='model' type='Model'/>
        </component>
    
        <component class="org.eclipse.xpand2.Generator">
            <metaModel class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
            <fileEncoding value="UTF-8"/>
            <expand value="templates::ProductCustomClass::productCustomClasses FOREACH model"/>
            <genPath value="${templateTargetDir}"/>
    
            <beautifier class="org.eclipse.xpand2.output.JavaBeautifier"/>  
        </component>
    
        <component class="org.eclipse.xpand2.Generator">
            <metaModel class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
            <fileEncoding value="UTF-8"/>       
            <expand value="templates::Main::main FOREACH model"/>
            <genPath value="${srcGenTargetDir}"/>
    
            <beautifier class="org.eclipse.xpand2.output.JavaBeautifier"/>
        </component>
    
    </workflow>