Code Generation tutorial

Code Generation tutorial

This tutorial has been refreshed for Eclipse 2021-06; Eclipse 4.20, EMF 2.26, OCL 6.15.0.

The direct OCL to Java Code generator has matured significantly from its experimental functionality for the Juno release. It is now the recommended approach.

In this tutorial we will continue the OCLinEcore tutorial and show how to get a direct Java representation of the Ecore model avoiding the need for run-time compilation.

Load OCLinEcore Tutorial Example Project

All the material for this tutorial is available as part of the OCLinEcore Example project that you may load by selecting New then Example... using the right button context menu of the Project Explorer. This should give the New Example dialog in which you can select the OCL (OCL Constraint Language) Plugins and the OCLinEcore Tutorial.

Direct code

In Generating Java Code we saw how to create a genmodel and how to generate code from it that realizes OCL as text strings in the Java implementation files. These text strings are lazily compiled at run-time.

Whether to generate OCL as text strings for interpretation or to convert directly to Java is determined by the Code Generation Mode. This may be configured using the project property or workspace preference as described in Code Generation Mode. So use Window->Preferences->OCL to change the Realisation of OCL embedded in Ecore models setting to Generate Java code in *Impl classes.

Now open Tutorial.genmodel, select the root Tutorial resource and invoke Generate Model Code to (re)generate the Java code. This will take somewhat longer as additional work items show that the OCL is being compiled and that Xtend templates are generating additional Java code.

Note that you must close Tutorial.genmodel while changing the Code Generation Mode.

You may also need to delete the autogenerated *Impl files if you change from one mode of generation to another.

That is all there is to it. Your model code is now 100% Java; no OCL parsing is needed at run-time.

If you see errors related to undefined ...__DIAGNOSTICCHAIN_MAP, you need tio edit your *.genmodel to make sure that the Model->Operation Reflection option on the overall GenModel is set true.

Using a GenAnnotation

Changing the default genmodel setting is a little dangerous since the change will affect any other genmodel activities you perform. It is therefore advisable to reset the workspace preference setting to its default and use a GenAnnotation to embed the setting in the genmodel.

The easiest way to create the GenAnnotation that ensure direct code generation regardless of workspace or project preferences, is to paste the following three lines into your genmodel just above the foreignModel or genPackages element.

  <genAnnotations source="http://www.eclipse.org/OCL/GenModel">
    <details key="Use Delegates" value="false"/>
  </genAnnotations>

Of course, if you want to enforce delegation you should set the value to true.

If you don’t like cutting and pasting into XMI files, you can achieve the same effect with the GenModel editor by:

  • Enable annotation display using Generator->Show Annotations

  • Invoke Annotate from the right button context menu of the genmodel root element

  • Use the Properties View to set the GenAnnotation source to http://www.eclipse.org/OCL/GenModel

  • Invoke Add Detail from the right button context menu of the GenAnnotation

  • Use the Properties View to set the Detail key to Use Delegates

  • Use the Properties View to set the Detail value to false

A further Use Null Annotations GenAnnotation may be used to control whether @NonNull and @Nullable annotations are emitted in the generated code.

  <genAnnotations source="http://www.eclipse.org/OCL/GenModel">
    <details key="Use Delegates" value="false"/>
    <details key="Use Null Annotations" value="true"/>
  </genAnnotations>