10

I am building a code generator in XTend where I already have an input model and meta model. That is, I use ATL to generate the input model for my XTend code generator (as part of a transformation sequence to gradually lower the abstraction level, instead of at once; this is the reason i'm not using xtext to create the syntax).

So to be very clear, my input model for the code generator is a file in XMI format and NOT in the grammar of the xtext project (not even using that)! And i think this is causing me problems/confusion.

I created a new XText project using Existing models, right clicked on the .text file, run as , generate artefacts, and then i did the same for the mwe2 file.

What is the next step, am I doing it right? How can I start my code generator? All the examples are from the POV that you use XText to create a DSL. I have an EMF meta model, and an XMI based instance of that. How to process that further using XTend?

Any hint or pointer to a tutorial is helpful.

Solution:

The solution was as Sven suggested in my accepted answer, but also I would like to note that you need to use a genmodel to generate Java artifacts from your meta model. This link shows how: http://www.vogella.com/articles/EclipseEMF/article.html , see section 4. This may appear all too logical, but i think it's worth noting anyway.

Marten Sytema
  • 1,906
  • 3
  • 21
  • 29

1 Answers1

19

If you have an XMI and just want to generate code from it, you don't need Xtext at all. Just start with a Java project (I'd use a plug-in project, to reuse the dependency management) and start coding:

import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.resource.Resource$Factory$Registry
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl

class MyCodeGenerator {

  def static void main(String[] args) {
    new MyCodeGenerator().generate("mymodel.xmi")
  }

  def generate(String file) {
    doEMFSetup
    val resourceSet = new ResourceSetImpl
    val resource = resourceSet.getResource(URI.createURI(file), true)
    for (content : resource.contents) {
      generateCode(content)
    }
  }

  def dispatch generateCode(MySpecialType it) '''
    public class «name» {
      «FOR member : members»
      «ENDFOR»
    }
  '''

  def dispatch generateCode(MyMember it) '''
    private «type» «name»;
    ...
  '''

  def doEMFSetup() {
//    EPackage$Registry.INSTANCE.put(MyPackage.eINSTANCE.nsURI, MyPackage.eINSTANCE)
    Resource$Factory.Registry.INSTANCE.extensionToFactoryMap.put("xmi", new XMIResourceFactoryImpl);
  }

}

The dependencies you need to add to your Manifest :

Require-Bundle: org.eclipse.xtend.lib,
 com.google.guava,
 org.eclipse.xtext.xbase.lib,
 org.eclipse.emf.common,
 org.eclipse.emf.ecore,
 org.eclipse.emf.ecore.xmi
Sven Efftinge
  • 3,065
  • 17
  • 17
  • Thanks a whole lot! The XMI is instance of a certain meta model, does your code consider this (ie. load this meta model?). Or is the XMI format descriptive enough and pointing to the metamodel somehow? – Marten Sytema Sep 18 '12 at 11:06
  • So I probably need the genmodel stuff right, and add that project as a dependency to this newly created plugin project? – Marten Sytema Sep 18 '12 at 11:25
  • 1
    Great, it works! Hah. Do you think it might be useful to put this example on the XTend site? To me it sounds like a common purpose of XTend (ie. use it as replacement of XPand) – Marten Sytema Sep 18 '12 at 12:13
  • Wow, a simple, minimalistic solution which covers my use case also! I also think it should be promoted more! – thSoft Jun 19 '13 at 19:51