VIATRA/Transformation/Adapter Framework/Adapter Implementations
Apart from the VIATRA transformation debugger, the VIATRA transformation adapter framework contains a number of default adapter implementations, that realize model transformation related use cases:
Trace coder listener
The transformation debug configuration contains a transformation debugger that follows the breakpoint-based approach. However, the execution sequence of VIATRA-based event-driven model transformations is typically non-deterministic. The trace coder is responsible for logging the transformation execution sequence (i.e.: order of transformation rule activation firings). This *transformation trace* can later be analyzed or used during re-execution of the transformation.
Transformation traces are hierarchical object structures aiming at storing transformation execution sequences. Transformation traces consist of activation and rule parameter traces. Activation traces identify the fired rule, and rule parameter traces specify which elements have triggered the execution of the given rule. Based on this information, the transformation can be re-executed for further evaluation, or erroneous rules can be detected during post mortem analysis.
Similar to the previously introduced components, the trace coder listener utilizes interchangeable subcomponents:
- Activation coder: Creates Activation Trace objects, using the parameters extracted from the activation object.
- Trace model serializer: Responsible for saving and loading trace models
Trace Executor adapter
This adapter is responsible for re-executing a transformation sequence recorded by the trace coder adapter. Particularly useful during debugging, as it allows the determinization of the otherwise random execution sequence of VIATRA event-driven transformations. It operates the following way: as the transformation is being executed, the activation at hand is compared to the upcoming entry in a previously loaded transformation trace. If the activation matches the trace record, it is executed, if not the executor finds the matching one.
As seen here, the trace executor component utilizes the same sub-components as the trace coder.
Noteable information regarding the trace executor:
- The usage of this adapter has a heavy effect on transformation performance, it is only advised to use it on small scale test models.
- Also keep in mind that the trace executor needs an already existing transformation trace, hence it should not be used simultaneously with the trace coder.
Adapters and listeners can be added to new or already existing VIATRA transformations in a simple and straightforward fashion. The VIATRA transformation API allows the transformation developer to attach these adapters and listeners directly to the model transformation, without needing to alter the transformation code itself. The transformation API classes create a modified, adapter supporting background structure, however this step is completely transparent to the transformation developer. Both Batch and event driven VIATRA transformations are supported, and will be presented in this section. The example shown here uses the VIATRA CPS example model transformations, to emphasize, that adding adapters does not require any change in the transformation code.
Adding adapters to a VIATRA transformation
Note that these examples only show the method for adding adapters to VIATRA transformations. The Adapters used in these examples will not work if used all together (especially true to the trace coder and executor components). In order to ensure that the adapters do not have adverse effects on each other use the predefined adapter configurations or individual adapters.
transformation = BatchTransformation.forEngine(engine) //Create trace coder listener //This listener is responsible for storing the transformation execution sequence (i.e.: order of transformation rule activation firings) //This transformation trace can later be analyzed or used during re-execution //Transformation trace --> hierarchical object structure --> aiming at storing a transformation execution sequence. //Consists of Activation and rule parameter traces --> activation traces identify the fired rule, and specify which elements have triggered the execution of the given rule. .addListener( new TraceCoder(URI.createURI("transformationtrace/batchtrace.transformationtrace"))) //Create trace executor adapter //This adapter is responsible for re-executing a transformation sequence recorded by the trace coder adapter. //Particularly useful during debugging, as it allows the determinization of the otherwise random execution sequence of VIATRA event-driven transformations. //Note, that the usage of this adapter has a heavy effect on transformation performance, it is only advised to use it on small scale test models. //Also keep in mind that the trace executor needs an already existing transformation trace, hence it should not be used simultaneously with the trace coder. .addAdapter(new TraceExecutor(URI.createURI("transformationtrace/trace.transformationtrace"))) //This listener implements a basic logging functionality .addListener(new LoggingEVMListener(logger)) .build
transformation = EventDrivenTransformation.forEngine(engine) .setConflictResolver(createConflictResolver) .addRule(hostRule) .addRule(applicationRule) .addListener( new TraceCoder(URI.createURI("transformationtrace/trace.transformationtrace"))) .addAdapter(new TraceExecutor(URI.createURI("transformationtrace/edtrace.transformationtrace"))) .addListener(new LoggingEVMListener(logger)) .build