• Keine Ergebnisse gefunden

Transformation CreateProcessDataAndFlow

4 PLATFORM INDEPENDENT ANALYSIS AND DESIGN

4.5 Process

4.5.2 Process Data and Flow

4.5.2.2 Transformation CreateProcessDataAndFlow

context ProcessActivity inv ProcessActivityFinalNode : self.processClass.outLinks->isEmpty() implies

self.node->exists( n | n.oclIsKindOf( ActivityFinalNode ) )

A process activity must not have an initial node.

context ProcessActivity inv ProcessActivityInitialNode : not self.node->exists( n | n.oclIsKindOf( InitialNode ) )

If the process class of a user action is associated to a content class then exactly one input pin has to be defined for the user action and its type has to conform to the content class.

Otherwise, no input pin must be defined and at least one incoming control flow has to enter the user action.

context UserAction inv UserActionInput :

if self.processClass.contentClass->isEmpty() then

self.input->isEmpty() and self.incoming->notEmpty() else

self.input->size() = 1 and self.input->forAll( pin |

pin.type.conformsTo( self.processClass.contentClass ) ) endif

For each output pin of a user action a process property of the associated process class has to exist with its name matching the name of the output pin and its type conforming to the type of the output pin.

context UserAction inv UserActionOutput :

self.output->forAll( pin | self.processClass.processProperties->exists( p | p.name = pin.name and p.type.conformsTo( pin.type ) ) )

Notation

Stereotyped UML class diagrams are used for modeling the process data and stereotyped UML activity diagrams are used for modeling the process flow. For a definition of the cor-responding UML profile see A.5.

Model Driven Software Engineering for Web Applications

are mapped to call operation actions in the process flow model. The transformation com-prises three transformation rules which are outlined below and detailed in B.3.8.

CreateProcessDataAndFlowForWebProcess CreateProcessDataAndFlowForSimpleProcess CreateProcessDataAndFlowForEdit

CreateProcessDataAndFlow Requirements

Model

Process Flow Model Process Data

Model Process Model

Navigation Model With Integrated

Processes Content

Model

CreateProcessDataAndFlowForWebProcess CreateProcessDataAndFlowForSimpleProcess CreateProcessDataAndFlowForEdit

CreateProcessDataAndFlow Requirements

Model

Process Flow Model Process Data

Model Process Model

Navigation Model With Integrated

Processes Content

Model

Figure 50. Transformation CreateProcessDataAndFlow

Rule CreateProcessDataAndFlowForWebProcess

For general Web processes, i.e. neither edit processes nor simple processes, only the pa-rameters and the activity parameter nodes of the corresponding process activity are gener-ated by the rule CreateProcessDataAndFlowForWebProcess, as in the case of the Web process AddProject of the running example, see Figure 51. The resulting process flow is thus incomplete and has to be refined by the developer as presented in the next section. If the Web process does not have an exit link then an activity final node is created instead of the output activity parameter node. The local variables targetSeq and nTargetSeq are de-fined to simulate the conditional creation of target elements using iterative target pattern elements, see [ATL06a]. In comparison to the rule implementation in B.3.8 the following details have been omitted below: target bindings that are not relevant for understanding the rule, and targets for the parameters of the process activity.

ProjectManage r : Projec tMa nager Project : P rojec t

Figure 51. Incomplete process flow for web process AddProject derived by rule CreateProcessDataAndFlowForWebProcess

rule CreateProcessDataAndFlowForWebProcess {

from pc : UWE!ProcessClass ( pc.ownedBehavior->isEmpty() and pc.webProcess.oclIsTypeOf( UWE!WebProcess ) )

using

127

{

source : UWE!NavigationClass = let ls : Set( UWE!Link ) = pc.inLinks in if ls->isEmpty() then OclUndefined else ls->any().source endif;

target : UWE!NavigationClass = let ls : Set( UWE!Link ) = pc.outLinks in if ls->isEmpty() then OclUndefined else ls->any().target endif;

targetSeq : Sequence( Boolean ) = if target.oclIsUndefined() then Sequence {}

else Sequence { true } endif;

nTargetSeq : Sequence( Boolean ) = if target.oclIsUndefined() then Sequence { true } else Sequence {} endif;

}

to tpc : UWE!ProcessClass (

ownedBehavior <- Sequence { pa },

),

pa : UWE!ProcessActivity (

name <- pc.name

),

-- create input activity parameter node entryAPN : UWE!ActivityParameterNode (

name <- source.contentClass.name, type <- source.contentClass,

),

-- conditionally create output activity parameter node

exitAPN : distinct UWE!ActivityParameterNode foreach( b in targetSeq ) (

name <- target.contentClass.name, type <- target.contentClass,

),

-- conditionally create activity final node

finalNode : distinct UWE!ActivityFinalNode foreach( b in nTargetSeq ) (

), }

Model Driven Software Engineering for Web Applications

Rule CreateProcessDataAndFlowForSimpleProcess

For simple processes the complete process flow and data is generated by the rule Create-ProcessDataAndFlowForSimpleProcess. The foundation for the generation is the associ-ated operation in the content model. For this operation a call operation action is creassoci-ated.

If the operation has a return type then a corresponding output pin for the call operation ac-tion is generated and connected by an outgoing object flow to the output activity parameter node. In the other case, if it has no return type then an activity final node is generated and a control flow from the call operation action to the activity final node, such as for example for the process RemoveProject depicted in Figure 52.

If the operation has no parameters (with direction in) then an object flow from the input activity parameter node to the target input pin of the call operation action is generated. The target input pin corresponds to the object on which the operation should be invoked. In the other case, if it has parameters, a process data class and a corresponding user action for capturing the input are generated. Further, for each parameter (1) an attribute of the process class, (2) an output pin of the user action, (3) an input pin of the call operation action and (4) an object flow connecting the output pin of the user action with the input pin of the call operation action are generated. Additionally, a fork node is generated with an incoming object flow from the input activity parameter node, an outgoing object flow to the target input pin of the call operation action and an outgoing control flow to the user action. An example for the latter case is again the process RemoveProject depicted in Figure 52. For this process a process data class RemoveProjectInput, a corresponding user action Re-moveProjectInput and a call operation action removeProject is generated. Further, the pa-rameter project of the operation removeProject is mapped to a corresponding process property of the process data class, an output pin of the user action and an input pin of the call operation action. Additionally, the required activity edges, the target input pin of the call operation action (for determining on which object the operation should be invoked) and the activity final node are generated.

In comparison to the rule implementation in B.3.8 the following details have been omitted below: target bindings that are not relevant for understanding the rule, targets for the activ-ity parameters, the activactiv-ity parameters nodes and the optional activactiv-ity final node, the target for the composite relationship for the generated process class, and targets for the activity edges.

129

<<p roce ss class>>

Re mov eProjectInput

ProjectMana ger : Project Manager

<<user action>>

RemoveProjectInput pr oject pr ojectManager

rem ove Project pr oject target

<<process class>>

RemoveProject

1

-pr oject : Project

Figure 52. Automatically derived process data and flow for simple process RemoveProject de-rived by rule CreateProcessDataAndFlowForSimpleProcess

rule CreateProcessDataAndFlowForSimpleProcess {

from pc : UWE!ProcessClass ( pc.ownedBehavior->isEmpty() and pc.webProcess.oclIsTypeOf( UWE!SimpleProcess ) )

using {

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

inputPar : Sequence( UWE!Parameter ) = o.ownedParameter->select( p | p.direction <> #return );

parSeq : Sequence( Boolean ) = if inputPar->isEmpty() then Sequence {}

else Sequence { true } endif;

typeSeq : Sequence( Boolean ) = if o.type.oclIsUndefined() then Sequence {}

else Sequence { true } endif;

}

to tpc : UWE!ProcessClass (

ownedBehavior <- Sequence { pa },

),

pa : UWE!ProcessActivity (

name <- pc.name,

Model Driven Software Engineering for Web Applications

),

-- create call operation action with target and input pins coa : UWE!CallOperationAction

(

name <- o.name, operation <- o,

input <- inputPin->including( targetPin ), output <- resultPin,

target <- targetPin ),

targetPin : UWE!InputPin (

name <- 'target', type <- o.class_

),

inputPin : distinct UWE!InputPin foreach ( p in inputPar ) (

name <- p.name, type <- p.type,

),

-- create user action and process data class if operation has parameters userAction : distinct UWE!UserAction foreach ( b in parSeq )

(

name <- pc.name + 'Input', processClass <- inputPC,

),

inputPC : distinct UWE!ProcessClass foreach ( b in parSeq ) (

name <- pc.name + 'Input',

),

-- create process properties and output pins

pp : distinct UWE!ProcessProperty foreach( p in inputPar ) (

name <- p.name, type <- p.type,

),

outputPin : distinct UWE!OutputPin foreach ( p in inputPar )

131

(

name <- p.name, type <- p.type ),

-- conditionally create output pin

resultPin : distinct UWE!OutputPin foreach ( b in typeSeq ) (

name <- 'result', type <- o.type,

),

-- conditionally create fork node if operation has parameters forkNode : distinct UWE!ForkNode foreach ( b in parSeq ) (

), }

Rule CreateProcessDataAndFlowForEdit

The complete process flow and data is generated for edit processes by the rule CreateProc-essDataAndFlowForEdit. For each edit process a process data class with a copy of the at-tributes (per default only those with a primitive type or an enumeration type) of the corre-sponding content class is generated. Further, a user action that uses this process data class for receiving input from the user is constructed. An input pin of this user action receives an object flow from the input activity parameter node to specify which object should be ed-ited. Finally, an outgoing control flow from the user action is connected to an activity final node. An example for the edit process EditUserProject is depicted in Figure 53. In com-parison to the rule implementation in B.3.8 the following details have been omitted below:

target bindings that are not relevant for understanding the rule, targets for the input pa-rameter, the input activity parameters node and the activity final node, the target for the composite relationship for the generated process class, and targets for the activity edges.

Model Driven Software Engineering for Web Applications

< <pro cess class>>

Edit UserProjectInput

<<process class>>

EditUse rProjec t

1

Use rProjec t : Us erP roje ct

< <user action> >

EditUserProjectInput userPr oject

-name : Stri ng -descrip tion : String -id : Stri ng

<<pro cess class>>

contentCl ass = DANUBIA::Conte nt::UserProject

Figure 53. Automatically derived process data and flow for edit process EditUserProject de-rived by rule CreateProcessDataAndFlowForEdit

rule CreateProcessDataAndFlowForEdit {

from pc : UWE!ProcessClass ( pc.ownedBehavior->isEmpty() and pc.webProcess.oclIsTypeOf( UWE!Edit ) )

using {

source : UWE!NavigationClass = let ls : Set( UWE!Link ) = pc.inLinks in if ls->isEmpty() then OclUndefined else ls->any().source endif;

}

to tpc : UWE!ProcessClass (

ownedBehavior <- Sequence { pa },

),

pa : UWE!ProcessActivity (

name <- pc.name,

),

-- create user action

userAction : UWE!UserAction (

name <- pc.name + 'Input', input <- Sequence { inputPin },

),

inputPin : UWE!InputPin

133

(

name <- source.contentClass.name.firstToLower(), type <- source.contentClass,

),

-- create process data class inputPC : UWE!ProcessClass (

name <- pc.name + 'Input',

contentClass <- source.contentClass, ownedAttribute <- pp

),

pp : distinct UWE!ProcessProperty foreach( cp in source.contentClass.allOwnedAttribute()->

select( p | p.type.oclIsKindOf( UWE!DataType ) and not p.isMultivalued() ) ) (

name <- cp.name, type <- cp.type, lower <- cp.lower, upper <- cp.upper, editProperty <- cp ),

}