... | @@ -2,32 +2,103 @@ |
... | @@ -2,32 +2,103 @@ |
|
:sectanchors:
|
|
:sectanchors:
|
|
:sectlinks:
|
|
:sectlinks:
|
|
:imagesdir: ../assets/generated
|
|
:imagesdir: ../assets/generated
|
|
|
|
:toc:
|
|
|
|
|
|
If you want to find out how to extend the generator and adapt it to fit your own needs, this page
|
|
If you want to find out how to extend the Generator and adapt it to fit your own needs, this page
|
|
is for you.
|
|
is for you.
|
|
|
|
|
|
== General architecture and workflow
|
|
== General architecture and workflow
|
|
|
|
|
|
When invoking the generator, it will (roughly) perform the following actions:
|
|
When invoking the Generator, it will (roughly) perform the following actions:
|
|
|
|
|
|
.Basic invocation workflow
|
|
.Basic invocation workflow
|
|
image::invocation_workflow.png[width=90%, align=center, link={imagesdir}/invocation_workflow.png]
|
|
image::invocation_workflow.png[width=90%, align=center, link={imagesdir}/invocation_workflow.png]
|
|
|
|
|
|
Each of these steps has a corresponding Scala class (called _Services_ hereafter) to take care of
|
|
Each of these steps has a corresponding Scala class (called _Services_ hereafter) to take care of
|
|
it. So, when extending the generator there are two basic approaches:
|
|
it. So, when extending the Generator there are two basic approaches:
|
|
|
|
|
|
[loweralpha]
|
|
[loweralpha]
|
|
. modifying one of the _Services_ (either directly or by means of subclassing)
|
|
. modifying one of the _Services_ (either directly or by means of subclassing)
|
|
. intercepting the workflow by adding more _Services_
|
|
. intercepting the workflow by adding more _Services_
|
|
|
|
|
|
To give you a rough idea of what _Services_ are available and where they will be located, here is an
|
|
To give you a rough idea of what _Services_ are available and where they will be located, here is an
|
|
overview of the generator's architecture:
|
|
overview of the Generator's architecture:
|
|
|
|
|
|
.The coarse-scale architecture of the generator
|
|
.The coarse-scale architecture of the Generator
|
|
image::architecture.png[width=90%, align=center, link={imagesdir}/architecture.png]
|
|
image::architecture.png[width=90%, align=center, link={imagesdir}/architecture.png]
|
|
|
|
|
|
== The Scala abstract class representation
|
|
== The Scala _Abstract class representation_
|
|
|
|
|
|
|
|
The _Abstract class representation_ (ACR) is the hearth of the Generator. It forms the meta-model
|
|
|
|
for the code to generate and provides facilities to adapt model instances for different purposes.
|
|
|
|
|
|
|
|
In short each element of a Scala class has a matching class in the _ACR_. E.g. a method will be
|
|
|
|
represented by an instance of `SMethod`, attributes become ``SAttribute``s and a class itself will
|
|
|
|
be mapped to a `SClass`. As the main purpose of the Generator is to provide executable software
|
|
|
|
models, an abstraction of a model, the `SModel` is provided as well. It is pretty straightforward
|
|
|
|
and simply provides all the classes in the model.
|
|
|
|
|
|
|
|
=== Types and Classes
|
|
|
|
|
|
|
|
Models seldom start from scratch. Instead, they will reuse certain data types, such as ``String``s,
|
|
|
|
``Integer``s, etc. as attributes in the classes that are specified by the model. Usually these data
|
|
|
|
types are provided by some library and may be mapped to a basic data types of the target programming
|
|
|
|
language (or a converter is provided along with them).
|
|
|
|
|
|
|
|
The Generator follows a similar approach: it provides an abstraction for user-supplied classes (i.e.
|
|
|
|
the classes specified within the model). This is the `SClass` class already mentioned above.
|
|
|
|
Additionally a `SType` class is provided to handle predefined data types. When generating source
|
|
|
|
code these types are expected to exist "as are" and will not be tackled further. I.e. no `.scala`
|
|
|
|
files will be created for `SType` instances.
|
|
|
|
|
|
|
|
As _types_ and _classes_ are concepts only found at a more abstract level and are irrelevant when it
|
|
|
|
comes to Scala source code, they share a common superclass - `STypedElement` - which will be used
|
|
|
|
whenever type information (no matter if it is user-supplied or generic) is needed.
|
|
|
|
|
|
|
|
=== Working with the _ACR_ on a more abstract level
|
|
|
|
|
|
|
|
The _ACR_ forms a trade-off between an abstract meta-model on one side, and a straightforward (hence
|
|
|
|
simplified) usage on the other side. Therefore low-level abstraction will oftentimes be wrapped by
|
|
|
|
some higher abstraction. E.g. a `SMethod` consists of abstract ``SMethodStatement``s and may thus
|
|
|
|
provide abstract functionality for modification. However a `SMethodStatement` simply wraps a
|
|
|
|
`String` (the actual statement). Dealing with the statements _themselves_ may therefore become
|
|
|
|
pretty cumbersome at a certain point. To circumvent this issue, the __ACR__'s elements should be
|
|
|
|
extended by means of subclassing to provide more tailored versions which handle the additional
|
|
|
|
complexity.
|
|
|
|
|
|
|
|
A good example for this approach is the extension of the `SMethod` class to easily generate
|
|
|
|
__Getter__s and __Setter__s for attributes:
|
|
|
|
|
|
|
|
.Example for modifying the _ACR_ on a more abstract level
|
|
|
|
[source, scala]
|
|
|
|
----
|
|
|
|
class SMethod(val name: String,
|
|
|
|
val result: STypedElement,
|
|
|
|
val params: Seq[SMethodParameter],
|
|
|
|
var implementation: Seq[SMethodStatement]) {
|
|
|
|
|
|
|
|
// implementation omitted
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class SGetter(attr: SAttribute) extends SMethod(
|
|
|
|
name = s"get${attr.name.firstLetterToUpperCase}",
|
|
|
|
result = attr.attrType,
|
|
|
|
params = Seq.empty,
|
|
|
|
implementation = Seq(SMethodStatement(content = attr.name, usedTypes = Set(attr.attrType))) {
|
|
|
|
|
|
|
|
// implementation omitted
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
|
|
|
__Getter__s may now be generated by only specifying the attribute they are created for - the
|
|
|
|
cumbersome creation of the actual method statements is hidden within the class implementation.
|
|
|
|
|
|
== Working with models
|
|
== Working with models
|
|
|
|
|
|
|
|
=== Incremental construction of `SModel` instances
|
|
|
|
|
|
|
|
=== Building a model from EMF
|
|
|
|
|
|
== Writing to the File system |
|
== Writing to the File system |