Skip to content

4. Wrapper Generation

Timur Sağlam edited this page Mar 10, 2020 · 2 revisions

Generating the Wrapper Classes

To connect the Ecore model code and the legacy code, wrapper classes that implement the Ecore interfaces and delegate to their implementations have to be generated. This is the task of the WrapperGenerator class. Its method buildWrappers() takes an GeneratedEcoreMetamodel and an IProject as parameters. The method then traverses the EPackage tree of the metamodel and builds a wrapper package structure in the IProject. The wrapper structure contains one wrapper class for every correlating EClass in the EPackage tree. The folder tree of the wrapper structure resembles the EPackage tree.

The wrapper classes are Xtend classes, that implement the interface of their correlating EClasses and delegate all field access and methods declared in EObject to the implementing class of their correlating EClasses. A simplified depiction of this pattern is visualized in the following diagram:

The Ecorificaton Base Pattern

Retaining Specialization Relations

As described before, the Ecorification process interferes with the specialization relations of the origin code to allow the integration of the Ecore functionality. More specifically, the classes of the adapted origin code extend the wrapper classes from the integration code. Therefore, all existing specialization relations of the origin code are overwritten. To retain the original specialization relations, the wrapper classes of the integration code need to extend the superclasses of their correlating classes in the origin code.

Retaining Specialization Relations

Retaining Realization Relations

Existing realization relations are not changed by the Ecorification process. But the generated Ecore interface that correlates to the existing interfaces needs to be included into the realization hierarchy. That means every type that extends or implements an interface needs to have an equal relation to the Ecore counterpart of the interface.

Retaining Realization Relations

Two Kinds of Delegation

Because the wrapper classes should only delegate some methods, we must distinguish two kinds of delegation. Methods whose signatures are implicitly declared by the Ecore interfaces of the Ecore code through inheriting them from their super interfaces are not part of the correlating class of the origin code. The correlating classes of the origin code inherit them through their specialization relations. The wrapper classes must not delegate these methods to the Ecore implementations because they are implemented in the original superclasses. That means the wrapper classes inherit the implementation of these methods from their super classes, which were originally the superclasses of the origin code.

  1. We use the Xtend Active Annotation @Delegate for top level classes in the inheritance hierarchy. That means all methods declared in super interfaces of the wrapper are delegated. This includes the methods declared in EObject.

  2. We use our own Active Annotation @DelegateDeclared from the XAnnotations project for all other classes in the inheritance hierarchy. That means only the methods are delegated, whose signatures are directly declared in an interface of the wrapper class. This prevents the delegation of the inherited methods.

Xtend Dependencies

Because the wrapper classes are written in the language Xtend, the ecorified project needs all the necessary Xtend dependencies. These dependencies are classpath entries, build properties and manifest entries. The class XtendLibraryHelper adds those dependencies to the project with the call of the method addXtendLibs(), which takes an IProject as a parameter.