• Keine Ergebnisse gefunden

4 PLATFORM INDEPENDENT ANALYSIS AND DESIGN

4.1 General Techniques

4.1.2 Transformation Traces

In order to capture the transformation history during the semi-automatic construction of the design models of a Web application a way to track the execution of transformations, i.e.

transformation traces, is needed. These traces are used on the one hand to support incre-mental updates of the models, allowing the reapplication of transformations without loss of manually added information by the developer. On the other hand, the trace information is also needed to resolve relationships between modeling elements transformed by transfor-mation rules of previous transfortransfor-mations runs.

To capture transformation trace information, a new metaclass TransformationTrace is in-troduced, which is a specialization of the UML metaclass Abstraction, which in turn is a specialized dependency, see Figure 20. In this chapter metaclasses from the UML meta-model are in general presented with a white background. This is conform with the usual way of defining trace dependencies in UML because the predefined stereotype «trace» is also an extension of the metaclass Abstraction. The notation for dependencies with a dashed line and an arrow is inherited from UML dependencies. The name of the transfor-mation trace denotes the name of the transfortransfor-mation rule that created the trace.

TransformationTrace NamedElement

Abstraction Dependency +client

1..* +clientDependency *

+supplier

1..* +supplierDependency *

Figure 20. Metamodel for transformation traces

Model Driven Software Engineering for Web Applications

In Figure 21 an example for a transformation trace is given for a Web application model comprising a content class Project with one attribute name. The (global) model is refined by the transformation RequirementsAndContent2Navigation presented in 4.4.2.1. The re-sulting refined (global) model comprises an additional navigation class which was created by the rule ContentClass2NavigationClass from the content class Project as denoted by the corresponding transformation trace. Additionally, the attribute name of the content class was mapped to a corresponding navigation property of the navigation class by the rule Property2NavigationProperty as denoted by another transformation trace.

P roje ct

P roje ct na me : String

<< navigation class>>

Project name : S trin g na me : String

P roje ct na me : String

RequirementsAndContent2Navigation RequirementsAndContent2Navigation

ContentClass2NavigationClass Property2NavigationProperty

<<transformation trace>>

P roje ct na me : String

<< navigation class>>

Project ContentClass2NavigationClass

Property2NavigationProperty

<<transformation trace>> name : S trin g

Figure 21. Example for transformation trace

The following ATL rule CreateTrace is called from the imperative part of a transformation rule presented in the following sections to create a transformation trace.

rule CreateTrace( sourceEl : UWE!NamedElement, targetEl : UWE!NamedElement, ruleName : String )

{

to t : UWE!TransformationTrace (

name <- ruleName,

supplier <- Set( UWE!NamedElement ) { sourceEl }, client <- Set( UWE!NamedElement ) { targetEl } )

}

To get the source or target elements of a transformation trace the ATL helpers get-TraceSource and getTraceTarget are used while hasget-TraceSource and hasTraceTarget are used to query if a trace already exists.

79

helper context UWE!NamedElement def : getTraceSource( ruleName : String ) : UWE!NamedElement =

let ts : Set( UWE!NamedElement ) = UWE!TransformationTrace.allInstances()->

select( t | t.name = ruleName and t.client->includes( self ) )->

collect( t | t.supplier )->flatten() in

if ts->size() > 0 then ts->asSequence()->first() else OclUndefined endif;

helper context UWE!NamedElement def : hasTraceSource( ruleName : String ) : Boolean = not self.getTraceSource( ruleName ).oclIsUndefined();

helper context UWE!NamedElement def : getTraceTarget( ruleName : String ) : UWE!NamedElement =

let ts : Set( UWE!NamedElement ) = UWE!TransformationTrace.allInstances()->

select( t | t.name = ruleName and t.supplier->includes( self ) )->

collect( t | t.client )->flatten() in

if ts->size() > 0 then ts->asSequence()->first() else OclUndefined endif;

helper context UWE!NamedElement def : hasTraceTarget( ruleName : String ) : Boolean = not self.getTraceTarget( ruleName ).oclIsUndefined();

An example for using transformation traces to support incremental updates is depicted in Figure 22. The Web application model after the first application of the transformation Re-quirementsAndContent2Navigation depicted in Figure 21 was extended by adding a new attribute description to the content class Project. When the transformation Requirement-sAndContent2Navigation is run again then the transformation traces created in previous runs are used to determine which new model elements should be created. For the content class Project a transformation trace for the rule ContentClass2NavigationClass already ex-ists, hence this class is not matched by this rule. The same holds for the attribute name and the rule Property2NavigationProperty, but it does not hold for the new attribute descrip-tion, hence a corresponding new navigation property and a new transformation trace are created.

Model Driven Software Engineering for Web Applications

P roje ct na me : String de scription : Str ing

<< navigation class>>

Project name : S trin g description : String

<< navigation class>>

Project name : S trin g P roje ct

na me : String de scription : Str ing

ContentClass2NavigationClass Property2NavigationProperty

<<transformation trace>>

ContentClass2NavigationClass Property2NavigationProperty

<<transformation trace>>

RequirementsAndContent2Navigation

P roje ct na me : String de scription : Str ing

<< navigation class>>

Project name : S trin g description : String

<< navigation class>>

Project name : S trin g ContentClass2NavigationClass

Property2NavigationProperty

<<transformation trace>>

P roje ct na me : String de scription : Str ing

RequirementsAndContent2Navigation

ContentClass2NavigationClass Property2NavigationProperty

<<transformation trace>>

Figure 22. Example for using transformation traces for incremental update

The general pattern for a transformation rule that matches only model elements for which a corresponding transformation trace does not yet exist and that creates a new transformation trace looks as follows:

rule TrafoX {

from x : MM!X ( not x.hasTraceTarget( ‘TrafoX’ ) ) to y : MM!Y ( … )

-- imperative part of the rule do

{

CreateTrace( x, y, ‘TrafoX’ );

} }

If a transformation rule extends another transformation rule, then there is no need to handle trace information in the subrule, i.e. no additional imperative part is needed for that pur-pose.

In addition to incremental updates, trace information can also be used to query the results of previous transformation runs, i.e. to query the source and target elements of a specific transformation rule of a previous transformation run. In the following example a Web process element was first mapped to an operation element by the transformation rule Sim-pleProcess2Operation in a previous transformation run. In another transformation the

81

transformation rule CreateProcessDataAndFlowForSimpleProcess presented in 4.5.2.2 initializes a local variable o with the target element of the transformation rule SimpleProc-ess2Operation of the previous transformation run.

rule CreateProcessDataAndFlowForSimpleProcess {

from pc : UWE!ProcessClass ( … ) using

{

o : UWE!Operation = pc.webProcess.getTraceTarget( 'SimpleProcess2Operation' );

}

to

}

The inclusion of transformation traces sometimes makes transformations rules cumber-some to read, especially for refinement transformations as those presented in this chapter.

Therefore, those parts of the rules that handle transformation traces are not included in this chapter. For their detailed code see B.3.