Eclipse provides a nice feature to create ECore metamodels based on an XML Schema. While it is fairly simple to create a metamodel and subsequently generate Java code from the metamodel with a genmodel, there are some obstacles when using this Java implementation on code level. One prominent problem are features of a class which are realized with a FeatureMap. In this article I explain how to add instances to a FeatureMap.
Usually, an XSD attribute is mapped to class
EAttribute and XSD content is mapped to an
EReference. However, it is possible in an XSD to allow multiple different types as content of an
xsd:element. In those cases EMF realizes this mixed typed reference with a
There is a lot of documentation available on how to read from such
FeatureMap. For example:
- EMF Eclipse Modeling – Second Edition, chapter 8 and 9
- XML Schema to Ecore Mapping
- Binding XML to Java
However, these sources do not describe how to insert values into the map programmatically. Therefore, I investigated the issue and found one hint in a forum post. However, it is hard to understand when you do not understand a lot about feature maps. In an effort to document my solution, I decided to also post it on my blog, hoping some can benefit from it (and I certainly will, as I can now look it up for any place on this lovely planet).
Lets assume you have an XSD with an element data.
<xsd:element name="data" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType>
Based on this XSD you generated a metamodel, created a genmodel for this model, and generated the Java classes for the metamodel. In this case the there will by a Java class
DataType with an attribute
any of type <
a href="http://download.eclipse.org/modeling/emf/emf/javadoc/2.5.0/org/eclipse/emf/ecore/util/FeatureMap.html">FeatureMap. Apart from the
EClasses realizing the different element declarations, the generated Java code also contains a class
YourPackageName is (usually) the name of the root package of the metamodel plus some package prefix you defined.
Now you can implement code to create model elements. First, lets create a data element:
DataType data = YourPackageNameFactory.eINSTANCE.createDataType; data.name = "Some name"; // This is only an example, you might use another option from the enumeration. data.handleUnknown = HandleUnknownType.IMPLEMENTATION;
Second, lets create some content for the data element:
SomeOtherType other = YourPackageNameFactory.eINSTANCE.createSomeOtherType // Here set all attributes of 'other'
And third, assign the other element to the data element:
YourPackageNamePackage provides accessors for classes, features, operations, enumerations, and data types. The signature of the
add method of the
FeatureMap any requires as first parameter a structural feature. They are named
Hope that helps. Any comments welcome.