... | @@ -11,6 +11,7 @@ is for you. |
... | @@ -11,6 +11,7 @@ is for you. |
|
|
|
|
|
When invoking the Generator, it will (roughly) perform the following actions:
|
|
When invoking the Generator, it will (roughly) perform the following actions:
|
|
|
|
|
|
|
|
[#invocation_workflow]
|
|
.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]
|
|
|
|
|
... | @@ -97,8 +98,66 @@ cumbersome creation of the actual method statements is hidden within the class i |
... | @@ -97,8 +98,66 @@ cumbersome creation of the actual method statements is hidden within the class i |
|
|
|
|
|
== Working with models
|
|
== Working with models
|
|
|
|
|
|
|
|
IMPORTANT: a general introduction should be added
|
|
|
|
|
|
=== Incremental construction of `SModel` instances
|
|
=== Incremental construction of `SModel` instances
|
|
|
|
|
|
=== Building a model from EMF
|
|
Adding new classes to an `SModel` instance is pretty straightforward: its default implementation
|
|
|
|
(`SimpleSModel`) already provides a `addModelClass(clazz)` method.
|
|
|
|
|
|
|
|
However one often encouters the issue of some kind of cyclic reference in a model, i.e. a class `C0`
|
|
|
|
referencing other classes `C1, ... Cn` which in turn keep references until one of these references
|
|
|
|
`C0` again. In this case only calling `SimpleSModel.addModelClass(C0)` will not work as it requires
|
|
|
|
`C1, ... Cn` to already be created. This leads to `C0` requiring itself to be created already.
|
|
|
|
|
|
|
|
Thus a `SClass` does not need to be created in one go but can be extended later on. To keep track
|
|
|
|
of all classes which are already (at least to some extend) build, the `STypeRegistry` was created.
|
|
|
|
It will work as a repository for all ``SClass``es
|
|
|
|
So instead of creating a `SClass` from scratch each time it is referenced, the `STypeRegistry`
|
|
|
|
should be queried. Only if the query does not yield any results, a new class has to be constructed.
|
|
|
|
|
|
|
|
.Building a `SClass` only if required
|
|
|
|
```scala
|
|
|
|
val clazz: SClass = STypeRegistry
|
|
|
|
.query(clazzName, clazzPackage)
|
|
|
|
.getOrElse {
|
|
|
|
val newClazz: SClass = new SClass(name = clazzName, sPackage = clazzPackage)
|
|
|
|
STypeRegistry.addType(newClazz)
|
|
|
|
newClazz
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The `STypeRegistry` already provides instances for some default data types so they do not need to be
|
|
|
|
created.
|
|
|
|
|
|
|
|
=== Building a model from _EMF_
|
|
|
|
|
|
|
|
Currently the generator only supports generating models from _EMF_. When dealing with an _ecore_
|
|
|
|
some additional problems have to be faced. The most prominent one is that _EMF_ does not use the
|
|
|
|
basic data types of Java and Scala directly but wraps them with an _EMF_ specific class instead.
|
|
|
|
|
|
|
|
When resolving such a type without further attention, it will simply be converted to an `SType`.
|
|
|
|
Hence compilation (see <<compilation>>) will fail as the required types are not present and they do
|
|
|
|
not work as expected (e.g. the `+` operator may not be applied to an `EString`).
|
|
|
|
|
|
|
|
To solve this issue, the _EMF_ types need to be mapped to their Java-equivalents. This is what the
|
|
|
|
`EmfTypeTranslator` should be used for. Its `getSClassFromEmf` method will provide the matching
|
|
|
|
types for all _EMF_ wrappers and nothing for all other classes.
|
|
|
|
|
|
|
|
=== Modifying `SModel` instances
|
|
|
|
|
|
|
|
To change the contents of a `SModel`, the whole _ACR_ implements the _Visitor pattern_footnote:[https://en.wikipedia.org/wiki/Visitor_pattern].
|
|
|
|
This approach is used by the whole <<invocation_workflow,Generator workflow>>.
|
|
|
|
|
|
|
|
More precisely the following __Visitor__s are predefined:
|
|
|
|
|
|
|
|
* `GetterSetterGeneratingVisitor` will generate the necessary methods for all attributes
|
|
|
|
* `SyncEnhancingVisitor` will make the setters notify the _Synchronization context_ when an
|
|
|
|
attribute is updated and insert the model's classes into the Synchronization's inheritance
|
|
|
|
hierarchy
|
|
|
|
* `SModelFSWriter` will write the model's classes to the file systems, compile them and generate
|
|
|
|
a JAR file for the whole model
|
|
|
|
|
|
|
|
== Preparing a model for synchronization
|
|
|
|
|
|
== Writing to the File system |
|
== Writing to the File system [[compilation]] |