Wiki

Clone wiki

jastemf-plugins / Approach

Overview and Application Domain

JastEMF is a tool to support the integrated use of the JastAdd system --- a rewriteable, circular, reference attribute grammar (ReCRAG) generator --- and the Eclipse Modeling Framework (EMF) --- a Java based metamodeling framework built around the Ecore metamodeling language. The objective of JastEMF is to permit the specification of an Ecore metamodel's semantics using a JastAdd ReCRAG. Given an Ecore metamodel and an appropriate JastAdd abstract syntax tree (AST) the metamodel's semantics --- i.e. the value and behavior of its derived attributes, non-containment references and operations --- can be specified using JastAdd. In essence, JastAdd can be used to define the metamodel elements that are only declared in the metamodel.

JastEMF has three main use-cases, summarized in Figure I:

  • Given a metamodel one likes to specify its semantics, i.e. implement the evaluation and resolution routines for some or all of its derived attributes, non-containment references and operations.
  • Given a metamodel one likes to build a tool that somehow reasons about model instances, e.g. to produce some model dependent output or to manipulate the model.
  • Given a JastAdd compiler one likes to integrate it into the EMF world, i.e. provide the compiler internal API for other EMF based tools by supporting a metamodel for the compiler.

https://bitbucket.org/jastemf/jastemf-plugins/wiki/figures/JastEMF_Use_Cases.png

Fig. I: JastEMF's Use-Cases

For convenient reasons we will call the first two use-cases the specification of metamodel semantics and the last use-case a JastAdd evaluator adaptation against the EMF. Since JastEMF's integration process is equal for all its use-cases, we will in the following just speak about the specification of metamodel semantics.

Metamodels, ReCRAGs and Metamodel Semantics

To understand JastEMF's usage, application area and integration process for Ecore metamodels and JastAdd ReCRAGs it is important to define what we consider metamodel semantics --- i.e. which parts of an Ecore metamodel are further specified using a JastAdd ReCRAG:

Definition (Metamodel Semantics): Let MM be a metamodel and MME(MM) be the finite set of its elements. Let MME_syntax(MM) and MME_semantic(MM) be disjunct subsets of MME(MM), whereas MME(MM) = MME_syntax(MM) + MME_semantic(MM). Let ME(M) be the set of entities of a model instance M\MM. Since M\MM, all entities e\ME(M) have a type t(e)\MME(MM). Let S(MM) be a function that defines for all M\MM for each entity e\ME(M) with t(e)\E_semantic(MM) the value of e. We call S(MM) a metamodel semantic for MM. Iff MME_syntax(MM) specifies a spanning tree for each M\MM, S(MM) can be specified with a reference attribute grammar (RAG).

W.r.t. that definition we split the Ecore modeling language as follow in syntactic and semantic parts:

  • MME_syntax = {metaclasses, containment references, non derived attributes}
  • MME_semantic = {non-containment references, derived attributes, operations}

It is obvious, that the elements MME_syntax of an Ecore metamodel specify a tree structure for each model instance whereas the ones of MME_semantic arbitrarily depend on and manipulate the instance's spanning tree --- i.e., impose a graph on top of it. Thus, we consider an Ecore metamodel's non-containment references, derived attributes and operations its semantics. And JastEMF's approach is to use a JastAdd ReCRAG to specify their value and implementation w.r.t. the metamodel.

Integration Projects

Starting point for JastEMF is a project containing an Ecore metamodel --- represented by a generator model (GenModel) --- and arbitrary many JastAdd ReCRAG specifications for its semantics. As context-free structure for the ReCRAG specifications --- i.e. the AST the project's rewriteable, circular, reference, attribute grammar is based on --- the metamodel's containment references are used. Thus, the ReCRAG's AST must be isomorph to the metamodel's containment reference graph.

We call a project satisfying these conditions an integration project. Using only EMF tools and JastAdd a developer can generate an EMF implementation for the metamodel and a JastAdd evaluator for the ReCRAG, but he cannot use the evaluator to reason about model instances. Both, the metamodel and the evaluator, have absolutely no knowledge about each other. Even worse, the evaluator maintains its own AST repository and the model has only method skeletons for its semantics. However, if JastEMF is used to steer the model and evaluator generation --- i.e. to call EMF and JastAdd throughout its execution --- the result would be an EMF model whose semantic methods are implemented. The integrated project has the API of the metamodel and the semantics of the evaluator.

Additionally, JastEMF produces a tightly integration. With tightly, we mean that the result is one class hierarchy. The evaluator is woven into the EMF model. There is no need for adapters from the evaluator to the model or vice versa. In fact, JastAdd's internal AST repository (non-terminals and terminals) is completely deleted and instead the model repository is used, such that EMF's model manipulation semantics --- notifications, interfaces etc. --- are satisfied. On the other hand, any semantic constructs within the model are deleted from the model's implementation and instead the ones generated by JastAdd are used. In the end, both, repository and semantics, are integrated within the same classes --- thus, it is a tightly integration.

Integration Process

The complete integration process is observed and steered by an integration manager, which is responsible to interact with JastAdd, the EMF and the components that generate integration related artefacts like refactoring scripts or repository adaptations. The following figure summarizes JastEMF's integration process:

https://bitbucket.org/jastemf/jastemf-plugins/wiki/figures/JastEMF_Integration_Process.png

Fig. II: JastEMF's Integration Process

It consists of three phases. Starting from the project to integrate, phase I generates based on the generator model a JastAdd Repository Adaptation Specification and a JDT Refactoring Script. The Repository Adaptation Specification adapts the JastAdd evaluator to generate in such a way, that is uses instead of its own internal repository the one of the EMF metamodel. It consists not only of attribute specifications, but also of many intertype declarations --- especially a set of JastEMF internal source code annotations that mark and provide information for evaluator parts to adapt later. JastEMF uses this Repository Adaptation Specification together with the developed metamodel semantics (JastAdd Attribute Grammar Specifications) to trigger JastAdd's generation process and retrieve a Repository adapted Evaluator. In phase II this evaluator is refactored in such a way, that it satisfies the metamodel's and JastAdd's API. First, the, generated JDT Refactoring Script is applied. It incorporates metamodel naming conventions and package structures. After doing so, the previously mentioned JastEMF annotations --- introduced by the repository adaptations --- are processed using the JDT. The result is an Integration Prepared Evaluator. Finally, in phase III, EMF and its JMerge tool are used to generate a metamodel implementation, that is immediately merged with the prepared evaluator. The result is an EMF metamodel implementation with the evaluator's semantics.

User Interface

The user has not to be aware of the integration process. For him JastEMF is a black-box he can call using an Ant task. The task is configurated with the generator model to use, the package for the generated integration artefacts, the package for the JastAdd generated AST classes and an embedded call to JastAdd's command line interface, such that it is no problem to configurate JastAdd as used to. Of course, the embedded JastAdd call has not to specify the AST classes' package and output directory again.

Updated