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
}
}
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
]
]
}