|
|
= ModelJoin integration
|
|
|
Rico Bergmann <rico.bergmann1@tu-dresden.de>
|
|
|
v0.1, 2019-03-21
|
|
|
:sectanchors:
|
|
|
:sectlinks:
|
|
|
:imagesdir: ../assets/generated
|
|
|
:toc: preamble
|
|
|
|
|
|
This document introduces the https://sdqweb.ipd.kit.edu/wiki/ModelJoin[ModelJoin] integration built
|
|
|
into the _CodeGenerator_. It will describe the driving abstraction in depth and also take a look at
|
|
|
how this abstraction will then be used to generate specific views on different Synchronization
|
|
|
models for our Synchronization UI.
|
|
|
|
|
|
To provide a broad overview of how things work together, here is the general _CodeGenerator_
|
|
|
workflow as well as how ModelJoin fits into that process:
|
|
|
|
|
|
[[invocation_workflow_modeljoin]]
|
|
|
.Basic invocation workflow for the ModelJoin integration. Parts specific to ModelJoin are highlighted in light grey.
|
|
|
image::invocation_workflow_modeljoin.png[width=90%, align=center, link={imagesdir}/invocation_workflow.png]
|
|
|
|
|
|
== About ModelJoin
|
|
|
|
|
|
_ModelJoin_ is a simple DSL used to specify unified views on different heterogeneous models. That
|
|
|
is, instances from multiple models may be merged according to a number of simple rules such as the
|
|
|
equality of attribute values. In order to get familiar with _ModelJoin_ we highly recommend reading
|
|
|
its technical report footnote:ModelJoinTR[Burger et al. "ModelJoin - A Textual Domain-Specific
|
|
|
Language for the Combination of Heterogeneous Models", 2014 URL:
|
|
|
https://publikationen.bibliothek.kit.edu/1000037908].
|
|
|
|
|
|
From now on, we will assume you are familiar with _ModelJoin_ and its general structure.
|
|
|
|
|
|
== ModelJoin abstraction
|
|
|
|
|
|
The _ModelJoin_ abstraction is our logical representation of _ModelJoin_ files. At a conceptual
|
|
|
level it is nothing more than a reification of the formal components of a _ModelJoin_ description.
|
|
|
That is, all parts of the _ModelJoin_ grammar are made explicit through corresponding Java classes.
|
|
|
|
|
|
[NOTE]
|
|
|
====
|
|
|
Although the _CodeGenerator_ is written in Scala for the most part, we decided to use Java for
|
|
|
the _ModelJoin_ abstraction. This decision was mainly driven by two reasons:
|
|
|
|
|
|
- The abstraction focuses on structure rather than functionality. Indeed it would have been
|
|
|
possible to use `case classes` or even create a fancy Scala-DSL, however a simple approach driven
|
|
|
by object-orientation was more than sufficient for the scope of our project.
|
|
|
- The abstraction should be as independent from the _CodeGenerator_ as possible. It is predestined
|
|
|
to be refactored into a separate project on day. If this happens, way more developers will be able
|
|
|
to modify the abstraction to their individual needs as no Scala knowledge is required.
|
|
|
====
|
|
|
|
|
|
In the end, the whole abstraction simply boils down to the above mentioned simple concept - although
|
|
|
of course there are some implementation specific details. This quickly becomes clear when taking a
|
|
|
look at (an excerpt of the) implementation diagram:
|
|
|
|
|
|
[[implementation_diagram]]
|
|
|
.A part of the implementation diagram of the _ModelJoin_ abstraction
|
|
|
image::modeljoin_abstraction.png[width=90%, align=center, link={imagesdir}/modeljoin_abstraction.png]
|
|
|
|
|
|
The `grammar` package contains all reified elements of the _ModelJoin_ grammar. Yet, in
|
|
|
order to keep things together, a number of helper classes are necessary. These are located under
|
|
|
`core` and mainly act as wrappers for other elements of _ModelJoin_ descriptions. However these
|
|
|
classes are of no real further interest for the other parts of our abstraction. Therefore they
|
|
|
mostly act as mere data-holders without much functionality attached.
|
|
|
|
|
|
Some examples for these helper classes are `OCLConstraint` or `ClassResource` which act as wrappers
|
|
|
for arbitrary OCL expressions footnote:OCL[Object Constraint Language. Homepage:
|
|
|
https://www.omg.org/spec/OCL/] and fully qualified references to classes within a source model.
|
|
|
|
|
|
Both the `ModelJoin` as well as the `JoinExpression` classes act as mere data-holders so a look at
|
|
|
their respective JavaDoc pages should suffice to get an idea of how they work. Things get more
|
|
|
interesting when looking at the `keep` expressions.
|
|
|
|
|
|
=== Composite structure of `keep` expressions
|
|
|
|
|
|
In general, there are six different types of `keep` expressions. Those are:
|
|
|
|
|
|
- `keep aggregate`
|
|
|
- `keep attributes`
|
|
|
- `keep calculated`
|
|
|
- `keep reference`
|
|
|
- `keep subtype`
|
|
|
- `keep supertype`
|
|
|
|
|
|
The last three of these expression are structured compositely. That is, they in turn contain an
|
|
|
arbitrary number of nested `keep` expressions.
|
|
|
|
|
|
[[keep_expressions_composite]]
|
|
|
.The composite structure of `keep` expressions
|
|
|
image::modeljoin_keeps_composite.png[width=90%, align=center, link={imagesdir}/modeljoin_keeps_composite.png]
|
|
|
|
|
|
To accommodate for this structure, the _Visitor
|
|
|
Pattern_ is used footnote:[See https://en.wikipedia.org/wiki/Visitor_pattern for a short
|
|
|
introduction]. See the JavaDoc of `KeepExpressionVisitor` for details.
|
|
|
|
|
|
=== Generating the ModelJoin representation
|
|
|
|
|
|
In order to instantiate all elements of a _ModelJoin_ description through a natural and fluid
|
|
|
interface, a number of _Builder_ implementations footnote:[See
|
|
|
https://en.wikipedia.org/wiki/Builder_pattern for a short introduction] are available. Those are
|
|
|
either located directly within their corresponding classes, or in the `util` package if they span
|
|
|
multiple classes. The `ModelJoinBuilder` is available to generate entire _ModelJoin_ descriptions
|
|
|
whereas the `JoinFactory` takes care of the creation process for individual joins.
|
|
|
|
|
|
Putting things together, a complete construction process may look like this:
|
|
|
|
|
|
[source, java]
|
|
|
----
|
|
|
ClassResource person = ClassResource.fromQualifiedName("contact.Person");
|
|
|
ClassResource employee = ClassResource.fromQualifiedName("company.Employee");
|
|
|
AttributePath dateOfBirth = AttributePath.from(personClass, "dateOfBirth");
|
|
|
|
|
|
ModelJoinBuilder.createNewModelJoin()
|
|
|
.add(JoinFactory.createNew()
|
|
|
.natural()
|
|
|
.join(person)
|
|
|
.with(employee)
|
|
|
.as(ClassResource("unified.Person")
|
|
|
.keep(KeepAttributesExpression
|
|
|
.keepAttributes(dateOfBirth))
|
|
|
.done()
|
|
|
)
|
|
|
.build();
|
|
|
----
|
|
|
|
|
|
== Intercepting the generation workflow
|
|
|
|
|
|
// TODO
|
|
|
|
|
|
TBD
|
|
|
|