Using the backend

Using the backend

Before you can start, you need to install the following features:

  • Xtend Backend
  • Xtend Backend UML2Types
  • Xtend Backend XSDTypes
  • Xpand Middleend
  • Xtend Middleend

Altenatively you may install the Xtend Backend SDK and Xpand Middleend SDK

As a quickstart you may use the Xpand Project wizard and select "Generate a sample EMF based Xpand project". After completion of the wizard you will find the workflow file "generatorWithBackend.mwe" in the "workflow"-folder. The workflow is ready to use the backend for generation.

Before you can use a language like Xpand with the backend, the responsible middleend must be registered at the backend. This is done with the org.eclipse.xtend.middleend.LanguageSetup. Middleends are being called a languageContributor here. You can register any language specific middleend. Language specific middleend implement the interface org.eclipse.xtend.middleend.plugins.LanguageSpecificMiddleEnd . To register the Xpand, Xtend and Check middleends, do the following in the workflow before invoking the middleend component of any of the respective languages:

<component
				class="org.eclipse.xtend.middleend.LanguageSetup">
				<languageContributor
				value="org.eclipse.xtend.middleend.xtend.plugin.OldXtendRegistryFactory"/>
				<languageContributor
				value="org.eclipse.xtend.middleend.xtend.plugin.OldCheckRegistryFactory"/>
				<languageContributor
				value="org.eclipse.xtend.middleend.xpand.plugin.OldXpandRegistryFactory"/>
				</component>

Now that the middleends are registered, you can use the respective middleend workflow components to use the backend in interpreted mode.

The Xpand middleend introduces a new component to be used instead of org.eclipse.xpand2.Generator to call Xpand templates from a workflow. The component has the same parameters as the Xpand Generator component. Hence, the following workflow fragment calls the template template::Template::main:

<component class="org.eclipse.xtend.middleend.xpand.XpandComponent">
	<metaModel idRef="mm_emf"/>
	<expand value="template::Template::main FOR model" />
	<outlet path="${src-gen}" >
		<postprocessor class="org.eclipse.xpand2.output.JavaBeautifier" />
	</outlet>
</component>

The component supports all properties of Generator, except collectProfileSummary and verboseProfileFilename

Just as the Xpand middleend, the Check middleend also provides a new component to execute checks on the backend. The component org.eclipse.xtend.check.CheckComponent has to be replaced with org.eclipse.xtend.middleend.xtend.CheckComponent . The new component uses the same properties as org.eclipse.xtend.check.CheckComponent. Hence calling checks using the backend would look like this:

<component class="org.eclipse.xtend.middleend.xtend.CheckComponent">
	<metaModel idRef="mm_emf"/>
	<checkFile value="metamodel::Checks" />
	<emfAllChildrenSlot value="model"/>
</component> 

To invoke Xtend extensions from the workflow, the Xtend middleend introduces the new component org.eclipse.xtend.middleend.xtend.XtendComponent . The new component provides the same configuration properties as the old one. Hence, you may invoke the extension extensions::modification::modify using the following workflow fragment:

>component class="org.eclipse.xtend.middleend.xtend.XtendComponent">
	>metaModel idRef="mm_emf"/>
	>invoke value="extensions::modification::modify(model)"/>
>/component> 

Functions may also be contributed by the Java Annotations Middleend to the M2T Backend. The middleend is implemented by org.eclipse.xtend.middleend.javaannotations.JavaFunctionClassContributor . Registration of Java classes is done by calling the method classAsResource with a class.

Functions have qualified names in the backend represented by org.eclipse.xtend.backend.common.QualifiedName consisting of a namespace and a simple name. E.g. the Xpand definition template::Template::main has the namespace template::Template and the simple name main. The String representation of the QualifiedName would be template::Template::main. When registering Java Defined Functions, normally only the simple name of a function will be defined as it's name. The simple name is method name. To set the qualified name of a function use the annotation @M2tQualifiedName. The namespace will be derived from the fully qualified class name.

Per default, all public methods will be registered as functions. To prevent the registration of a method, annotate it with @M2tNoFunction. You may also use one of the following annotations:

  • @M2tCached - use caching
  • @M2tPrivateFunction - mark the function as private
  • @M2tAroundAdvice(pointcut) - use the method as around advice. The pointcut has the parameters:
    • namePattern - a pattern for function names as in Xpand paramTypeNames - an array with patterns of parameter type names hasVarArgs - true, if the matching functions have any number of parameters after paramTypeNames the specified in the pointcut

Functions defined by methods of a Java class can be directly called on the facade org.eclipse.xtend.middleend.javaannotations.JavaAnnotationBackendFacade . Call the method invoke to invoke functions defined in Java:

invokeFunction(String className, BackendTypesystem
					ts, QualifiedName functionName, List<?> params)