GenModel GenAnnotations

GenModel GenAnnotations

The automated generation of models that form part of the OCL tooling exploits a number of GenAnnotations to influence the auto-generated code.

http://www.eclipse.org/OCL/GenModel GenAnnotation Source

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

This GenAnnotation is also used by regular OCL code generation

Use Delegates

If the Use Delegates key is present and has a true value genModel will generate code for OCL expressions that delegates to the run-time interpreter, rather than generating Java code.

Use Null Annotations

If the Use Null Annotations key is present and has a true value the generated code will have @NonNull and @NonNull annotations.

http://www.eclipse.org/OCL/GenModel/ToString

<genAnnotations source="http://www.eclipse.org/OCL/GenModel/ToString">
  <details key="org.eclipse.ocl.examples.codegen.cgmodel.CGElement"
    value="return &lt;%org.eclipse.ocl.examples.codegen.analyzer.CG2StringVisitor%>.toString(this);"/>
</genAnnotations>

By default EMF generates a toString() method that identifies all attribute values. This cannot be suppressed, only circumvented.

If the http://www.eclipse.org/OCL/GenModel/ToString GenAnnotation is present the default is changed to use an inherited implementation, which must be specified somewhere.

Specific implementations of toString may be provided as the values of detail entries whose key is the qualified name of the interface class. Imports may be encoded with the implementation by enclosing the fully qualified name in <%...%>.

http://www.eclipse.org/OCL/GenModel/Visitor

<genAnnotations source="http://www.eclipse.org/OCL/GenModel/Visitor">
  <details key="Root Visitor Class" value="org.eclipse.ocl.pivot.util.Visitor"/>
  <details key="Derived Visitor Class" value="org.eclipse.ocl.pivot.util.Visitor"/>
  <details key="Visitable Interface" value="org.eclipse.ocl.pivot.util.Visitable"/>
  <details key="Visitable Classes" value="org.eclipse.ocl.pivot.Element"/>
</genAnnotations>

The accept method for an hierarchical visitor pattern may be woven into the code using the http://www.eclipse.org/OCL/GenModel/Visitor genAnnotation.

The implementation for class XXXX in the root package is

@Nullable R accept(@NonNull RootVisitorClass<R> visitor) {
return visitor.visitXXXX(this);

The implementation for class XXXX in the derived package is

@Nullable R accept(@NonNull RootVisitorClass<R> visitor) {
return (R) (DerivedVisitorClass<?>)visitor).visitXXXX(this);

The direct cast to the derived type assumes that the caller has ensured that the visitor in use supports the visitor interfaces for all objects in use.

The null annotations or omitted unless null annotations have been enabled.

Root Visitor Class

The fully qualified name of the visitor class must be specified as the value of the Root Visitor Class detail. This class defines the argument type of the accept method.

Derived Visitor Class

The fully qualified name of the derived visitor class must be specified as the value of the Derived Visitor Class detail. This detail may be omitted for the root package.

Visitable Interface

The fully qualified name of the visitable interface must be specified as the value of the Visitable Interface detail. It’s mandatory for the root package.

Visitable Classes

An @Override annotation is generated for all implementations. This leads to an error where the implementation is not an override. The space-separated fully qualified names of all classes for which the accpe is not an override must be specified as the value of the Visitable Classes detail.

Implementation Details

The support for accept is in templates/model/Class/insert.javajetinc where the appropriate code is generated into the implementation file with help from OCLBuildGenModelUtil.

http://www.eclipse.org/OCL/GenModel/CopyAndPaste

<genAnnotations source="http://www.eclipse.org/OCL/GenModel/CopyAndPaste">
  <details key="org.eclipse.ocl.xtext.markup.FigureElement" 
   value="model/FigureElement.javacopy"/>
</genAnnotations>

EMF allows custom code to be added to classes using an @Generated NOT comment annotation or no annotation at all. These additions are preserved during regeneration, but may be lost if the file is deleted and regenerated.

As an alternative, custom contributions may be pasted into class implementation files by specifying a detail entry whose key is the qualified interface name of the class to be customised and whose value is the project-relative name of a file providing text to be copied and pasted.

The copied text should be tab indented so that it matches the tab indentation of the auto-generated code.

The copied text may reference types that may need importing by encoding the fully qualified name in <%...%>.

The customization files are conventionally given a *.copyjava file name and are placed in the model folder alongside the *.genmodel.

Implementation Details

The support for copy and paste is in templates/model/Class/insert.javajetinc where the referenced text is copied into the implementation file with help from OCLBuildGenModelUtil.

Implementation Details

org.eclipse.ocl.examples.build

The org.eclipse.ocl.examples.build plugin hosts the build-time functionality that does not need to bloat the distribution.

Modified JET templates are in the templates folder which .jetproperties prefixes to the template path. The .project has an org.eclipse.emf.codegen.jet.IJETNature nature and builder so that the custom JET templates are automatically built to the jet-gen source folder. The .project similarly has has an org.eclipse.xtext.ui.shared.xtextNature nature and builder so that the Xtend templates are automatically built to the xtend-gen source folder. Both these generated source folders are excluded from source control, since they are 100% auto-generated and they do not form part of the distribution.

Custom JET templates are declared by OCLBuildGenModelGeneratorAdapterFactory which creates a OCLBuildGenClassGeneratorAdapter that replaces the normal reference to org.eclipse.emf.codegen.ecore.templates.model.Class by org.eclipse.ocl.examples.build.templates.model.Class.

The custom build functionality is installed by the GenModelSetup workflow component,