Frage

I'm working on xtext project and I'm generating objects through .xtext file. I want to add new attribute to one of the generated object. I saw in http://christiandietrich.wordpress.com/2011/07/22/customizing-xtext-metamodel-inference-using-xtend2/ the following code is generating a temp variable in ObjectValue but i want temp to be of type MyObject.

How to do so? where can i read about it?

import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage
import org.eclipse.emf.common.util.BasicEMap$Entry
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.EcoreFactory
import org.eclipse.emf.ecore.EcorePackage
import org.eclipse.xtext.GeneratedMetamodel
import org.eclipse.xtext.xtext.ecoreInference.IXtext2EcorePostProcessor

class CodeGeneratorClass implements IXtext2EcorePostProcessor {

    override process(GeneratedMetamodel metamodel) {
        metamodel.EPackage.process
    }

    def process(EPackage p) {
        for (c : p.EClassifiers.filter(typeof(EClass))) {
            if (c.name == "ObjectValue") {
                c.handle
            }
        }
    }

    def handle (EClass c) {
    val attr = EcoreFactory::eINSTANCE.createEAttribute
    attr.name = "temp"
    attr.EType = EcorePackage::eINSTANCE.EString
    c.EStructuralFeatures += attr
}
}
War es hilfreich?

Lösung

First: MyObject must be described either by an EClass or an EDataType. A plain Java Object won't do it.

If MyObject is an EDataType then you must add an EAttribute in the handle method. Your handle method is almost right, only the EType must be adjusted:

attr.EType = MyPackage::eINSTANCE.MyObject

Otherwise: If MyObject is an EClass then you must add an EReference instead of an EAttribute. The handle method for this case looks like this:

def handleReference(EClass c){
    val ref = EcoreFactory::eINSTANCE.createEReference
    ref.name = "temp"
    ref.EType = MyPackage::eINSTANCE.MyObject
    c.EStructuralFeatures += ref
}

EDIT

In order to define a new, minimal EDataType and hook it up into the model the following snippet should work:

def void process(GeneratedMetamodel it){
     // create new dynamic EDataType
     val dataType = EcoreFactory::eINSTANCE.createEDataType => [
        name = 'MyObject'
        instanceTypeName = 'java.package.with.MyObject' 
    ]

    // register new EDataType in own model package
    EPackage.EClassifiers += dataType

    // attach as EAttribute to appropriate EClasses
    EPackage.EClassifiers.filter(typeof(EClass)).filter[name == 'ObjectValue'].forEach[
        EStructuralFeatures += EcoreFactory::eINSTANCE.createEAttribute => [
            name = "temp"
            EType = dataType
        ]
    ]
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top