Home > Xtext > Use of EcoreGenerator to customize EMFs generated Java Classes

Use of EcoreGenerator to customize EMFs generated Java Classes

This is a blog post on the usage of the org.eclipse.emf.mwe2.ecore.EcoreGenerator worflow component.
It is an alternative to EMFs JMerge Based approach to customize generated Java Classes from an ecore model.

So let us asume we have the following Ecore file
(/sample/model/sample.ecore)

<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="sample" nsURI="http://www.eclipse.org/xtext/ecore/sample" nsPrefix="sample">
  <eClassifiers xsi:type="ecore:EClass" name="Person">
    <eOperations name="getFullname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="firstname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lastname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
</ecore:EPackage>

with the following genmodel
(/sample/model/sample.genmodel)

<?xml version="1.0" encoding="UTF-8"?>
<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/sample/src-gen" modelPluginID="sample" modelName="Sample"
    importerID="org.eclipse.emf.importer.ecore" complianceLevel="6.0" copyrightFields="false">
  <foreignModel>sample.ecore</foreignModel>
  <genPackages prefix="Sample" disposableProviderFactory="true" ecorePackage="sample.ecore#/">
    <genClasses ecoreClass="sample.ecore#//Person">
      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute sample.ecore#//Person/firstname"/>
      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute sample.ecore#//Person/lastname"/>
      <genOperations ecoreOperation="sample.ecore#//Person/getFullname"/>
    </genClasses>
  </genPackages>
</genmodel:GenModel>

I have changed the modelDirectory="/sample/src-gen"

Now we want to implement the getFullname() method.
we would usually implement the code in PersonImpl and change the javadoc to @generated NOT or remove the @generated.
(and checkin the generated code as well)

But let us try another approach

so let us create following class

(/sample/src/sample/impl/PersonImplCustom.java)

package sample.impl;

import sample.impl.PersonImpl;

public class PersonImplCustom extends PersonImpl {
	
	@Override
	public String getFullname() {
		return getFirstname() + " " + getLastname();
	}

}

and workflow

(/sample/src/test.mwe2)

module test

Workflow {
	
	bean = org.eclipse.emf.mwe.utils.StandaloneSetup {
		platformUri = ".."
	}
	
	component = org.eclipse.emf.mwe.utils.DirectoryCleaner {
		directory = "src-gen"
	}
	
	component = org.eclipse.emf.mwe2.ecore.EcoreGenerator {
		generateCustomClasses = false
		genModel = "platform:/resource/sample/model/sample.genmodel"
		srcPath = "platform:/resource/sample/src"	
	}
	
}

here is the Manifest for the deps
(/sample/META-INF/MANIFEST.MF)

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: sample
Bundle-SymbolicName: sample; singleton:=true
Bundle-Version: 0.1.0
Require-Bundle: org.eclipse.emf.mwe2.lib,
 org.eclipse.emf.mwe2.launch,
 org.apache.commons.logging,
 org.apache.commons.lang,
 org.eclipse.xtext.xbase.lib,
 org.eclipse.xtext,
 org.eclipse.xtext.generator,
 org.apache.commons.logging,
 org.eclipse.ui.workbench,
 org.eclipse.core.runtime,
 org.eclipse.core.commands,
 org.eclipse.xtext.ui,
 org.eclipse.core.expressions,
 org.apache.log4j
Export-Package: sample.impl,
 sample.util

If we run the workflow emf is configured to take PersonImplCustom instead of PersonImpl so that the following will work nicely

public class Test {
	
	public static void main(String[] args) {
		Person p = SampleFactory.eINSTANCE.createPerson();
		p.setFirstname("Christian");
		p.setLastname("Dietrich");
		System.out.println(p.getFullname());
	}

}
Advertisements
Categories: Xtext
  1. Stefan K.
    September 13, 2014 at 22:36

    Thank you for this. It was very valuable help! My code basis seems to be a lot cleaner now šŸ™‚

    Unfortunately the EcoreGenerator is not configurable, so I had to subclass it and provide my own parameterised implementation. šŸ™‚

  2. Michael
    February 16, 2015 at 12:55

    Hey,

    is there a possibility to do the custom generation for the edit Code e.g the ItemProvider

    public class ItemProviderCustom extends ItemProvider {

    • February 18, 2015 at 21:34

      no thats not possible

    • GIRISH KUMAR
      July 22, 2016 at 15:00

      your Itemprovider can extends the customprovider, this can be configured using provider rootclass ExtendClass

  3. Michael
    February 23, 2015 at 12:15

    Is the effort big to adapt this feature for the edit code?

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: