Type System TypeData type TypeParameterized type

Type System

The abstraction layer on API basis is called a type system. It provides access to built-in types and different registered metamodel implementations. These registered metamodel implementations offer access to the types they provide. The first part of this documentation describes the type system. The expression sub-language is described afterwards in the second part of this documentation. This differentiation is necessary because the type system and the expression language are two different things. The type system is a kind of reflection layer, that can be extended with metamodel implementations. The expression language defines a concrete syntax for executable expressions, using the type system.

The Java API described here is located in the org.eclipse.xpand.type package and is a part of the subproject core.expressions.

Every object (e.g. model elements, values, etc.) has a type. A type contains properties and operations. In addition it might inherit from other types (multiple inheritance is also possible, depending on the underlying meta-meta-model).

As mentioned before, the expressions framework has several built-in types that define operations and properties. In the following, we will give a rough overview of the types and their features. We will not document all of the operations here, because the built-in types will evolve over time and we want to derive the documentation from the implementation (model-driven, of course). For a complete reference, consult the generated API documentation.

By default, the type system only knows the built-in types. In order to register your own metatypes (e.g. Entity or State), you need to register a respective metamodel implementation with the type system. Within a metamodel implementation the Xpand type system elements (Type, Property, Operation) are mapped to an arbitrary other type system (e.g. Java reflections, Ecore or XML Schema).

You need to configure your Xpand language components with the respective metamodel implementations.

A possible configuration of the Xpand2 generator component looks like this:

<component class="org.eclipse.xpand2.Generator">
   <metaModel class="org.eclipse.type.emf.EmfMetaModel">
      <metaModelPackage value="my.generated.MetaModel1Package"/>
   </metaModel>
   <metaModel class="org.eclipse.type.emf.EmfMetaModel">
      <metaModelFile value="my/java/package/metamodel2.ecore"/>
   </metaModel>
   ...
</component>

In this example the EmfMetaModel implementation is configured two times. This means that we want to use two metamodels at the same time, both based on EMF. The metaModelPackage property is a property that is specific to the EmfMetaModel (located in the org.eclipse.xtend.typesystem.emf plugin). It points to the generated EPackages interface. The second meta model is configured using the Ecore file. You do no need to have a generated Ecore model for Xpand in order to work. The EmfMetaModel works with dynamic EMF models just as it works with generated EMF models.

Note that is recommended to prefer the EmfRegistryMetaModel instead of the EmfMetaModel, although EmfMetaModel is derived from the EmfRegistryMetaModel. Further it is recommended to use platform URIs (see API Doc URI) to refer to EMF resources.

The use of platform URIs in the workflow requires setting up EMF for standalone execution with the StandaloneSetup class from the org.eclipse.emf.mwe.utils plugin. Further, StandaloneSetup is used to register known EMF packages. An equivalent workflow configuration for the sample above would look like this:

<bean class="org.eclipse.emf.mwe.utils.StandaloneSetup">
  <platformUri value=".."/>
  <registerGeneratedEPackage value="my.generated.MetaModel1Package"/>
  <registerEcoreFile value="platform:/resource/my/java/package/metamodel2.ecore"/>
</bean>
...
<component class="org.eclipse.xpand2.Generator">
   <metaModel class="org.eclipse.type.emf.EmfRegistryMetaModel"/>
   ...
</component>

The StandaloneSetup is given the path to the platform. This is the path to which platform resource URIs are resolved relative to. It usually points to the workspace or check out location of the plugin project, which is usually one directory above the working directory in which a workflow is executed.

Metamodel instances are often shared between different components that make use of expressions (most notably the Xpand Generator, XtendComponent and CheckComponent). Normally you don't want that a Metamodel instance configured and instantiated for each workflow component. MWE lets you instantiate a class using the <bean> tag and by giving the bean an id value, this same instance can be referred to using the idRef attribute. This would lead to this workflow:

<bean class="org.eclipse.emf.mwe.utils.StandaloneSetup">
  <platformUri value=".."/>
  <registerGeneratedEPackage value="my.generated.MetaModel1Package"/>
  <registerEcoreFile value="platform:/resource/my/java/package/metamodel2.ecore"/>
</bean>
<bean id="mm_emf" class="org.eclipse.type.emf.EmfRegistryMetaModel"/>
...
<component class="org.eclipse.xpand2.Generator">
   <metaModel idRef="mm_emf"/>
   ...
</component>

With Xpand you can work on different kinds of Model representations at the same time in a transparent manner. One can work with EMF models, XML DOM models, and simple JavaBeans in the same Xpand template. You just need to configure the respective MetaModel implementations.

If you want to do so you need to know how the type lookup works. Let us assume that we have an EMF metamodel and a model based on some Java classes. Then the following would be a possible configuration:

<component class="org.eclipse.xpand2.Generator">
   <metaModel class="org.eclipse.internal.xtend.type.impl.java.JavaMetaModel"/>
   <metaModel class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel">
      <metaModelFile value="my/java/package/metamodel.ecore"/>
   </metaModel>

   ...
</component>

When the runtime needs to access a property of a given object, it asks the metamodels in the configured order. Let us assume that our model element is an instance of the Java type org.eclipse.emf.ecore.EObject and it is a dynamic instance of an EMF EClass MyType.

We have three Metamodels:

The first one will return the type Object (not java.lang.Object but Object of Xpand !). At this point the type Object best fits the request, so it will act as the desired type.

The second metamodel returns a type called org::eclipse::emf::ecore::EObject The type system will check if the returned type is a specialization of the current 'best-fit' type (Object). It is, because it extends Object (Every metatype has to extend Object). At this time the type system assumes org::eclipse::emf::ecore::EObject to be the desired type.

The third metamodel will return metamodel::MyType which is the desired type. But unfortunately it doesn't extend org::eclipse::emf::ecore::EObject as it has nothing to do with those Java types. Instead it extends emf::EObject which extends Object.

We need to swap the configuration of the two metamodels to get the desired type.

<component class="org.eclipse.xpand2.Generator">
   <metaModel class="org.eclipse.xtend.typesystem.emf.EmfMetaModel">
      <metaModelFile value="my/java/package/metamodel.ecore"/>
   </metaModel>
   <metaModel class="org.eclipse.internal.xtend.type.impl.java.JavaMetaModel"/>

   ...
</component>

The order of the metamodels is important for the work within the Xpand-editors. The metamodels to work with can be configured inside the Xtend/Xpand -properties dialog. The Activated metamodel contributors table is a ordered list. The more specific metamodels have to be placed at the top of the list.

In the following, each of the built-in metamodels that come with Xpand will be documented. Furthermore, there will be some guidelines on how to implement your own metamodel.

This section will describe the metamodels that can be used for EMF models. Please note that you have to execute one of the setup utility classes, Setup or StandaloneSetup, in your workflow before you can use one of the EMF metamodels.

Xpand also provides several metamodels that allow to use UML models in conjunction with this model-to-text generation framework. Please note that you have to execute the setup utility class Setup in your workflow before you can use one of the UML metamodels