18 - DVCfg_AutomationInterfaceDocumentations
DaVinci Configurator AutomationInterfaceDevelopment Documentation of the AutomationInterface (AI)DaVinci Configurator Team
December 9, 2016
© 2016
Vector Informatik GmbH
Ingersheimerstr. 24
70499 Stuttgart
Contents1Introduction81.1General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
1.2Facts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
2Getting started with Script Development92.1General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
2.2Automation Script Development Types . . . . . . . . . . . . . . . . . . . . . . . .
9
2.3Script File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
2.4Script Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.4.1Script Project Development . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.4.2Java JDK Setup. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.4.3IntelliJ IDEA Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.4.4Gradle Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
3AutomationInterface Architecture153.1Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.2Languages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
3.2.1Why Groovy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
3.3Script Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
3.3.1Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
3.3.2Script Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
3.3.3Script Locations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
3.4Script loading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
3.4.1Internal Script Reload Behavior . . . . . . . . . . . . . . . . . . . . . . . .
18
3.5Script editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
3.6Licensing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
3.7Script Coding Conventions and Constraints . . . . . . . . . . . . . . . . . . . . .
19
3.7.1Usage of static fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
3.7.2Usage of Outer Closure Scope Variables . . . . . . . . . . . . . . . . . . .
21
3.7.3States over script task execution . . . . . . . . . . . . . . . . . . . . . . .
21
3.7.4Usage of Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
3.7.5Usage of DaVinci Configurator private Classes Methods or Fields . . . . .
21
4AutomationInterface API Reference224.1Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
4.2Script Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
4.2.1Script Task Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
4.2.1.1Script Creation with IDE Code Completion Support . . . . . . .
24
4.2.1.2Script Task isExecutableIf . . . . . . . . . . . . . . . . . . . . . .
25
4.2.2Description and Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.3Script Task Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.3.1Available Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.3.1.1Application Types . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.3.1.2Project Types. . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
4.3.1.3UI Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
4.3.1.4Generation Types . . . . . . . . . . . . . . . . . . . . . . . . . .
29
4.4Script Task Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
4.4.1Execution Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
© 2016, Vector Informatik GmbH
2 of
207
Contents4.4.1.1Code Block Arguments . . . . . . . . . . . . . . . . . . . . . . .
32
4.4.2Task Execution Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
4.4.3Script Path API during Execution . . . . . . . . . . . . . . . . . . . . . .
33
4.4.3.1Path Resolution by Parent Folder. . . . . . . . . . . . . . . . .
34
4.4.3.2Path Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
4.4.3.3Script Folder Path Resolution. . . . . . . . . . . . . . . . . . .
35
4.4.3.4Project Folder Path Resolution . . . . . . . . . . . . . . . . . . .
35
4.4.3.5SIP Folder Path Resolution . . . . . . . . . . . . . . . . . . . . .
36
4.4.3.6Temp Folder Path Resolution . . . . . . . . . . . . . . . . . . . .
36
4.4.3.7Other Project and Application Paths. . . . . . . . . . . . . . .
37
4.4.4Script logging API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
4.4.5User Interactions and Inputs. . . . . . . . . . . . . . . . . . . . . . . . .
38
4.4.5.1UserInteraction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
4.4.6Script Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
4.4.6.1Script Exceptions. . . . . . . . . . . . . . . . . . . . . . . . . .
40
4.4.6.2Script Task Abortion by Exception . . . . . . . . . . . . . . . . .
40
4.4.6.3Unhandled Exceptions from Tasks . . . . . . . . . . . . . . . . .
41
4.4.7User defined Classes and Methods. . . . . . . . . . . . . . . . . . . . . .
42
4.4.8Usage of Automation API in own defined Classes and Methods . . . . . .
43
4.4.8.1Access the Automation API like the Script code{} Block. . . .
43
4.4.8.2Access the Project API of the current active Project . . . . . . .
43
4.4.9User defined Script Task Arguments in Commandline. . . . . . . . . . .
44
4.4.9.1Call Script Task with Task Arguments . . . . . . . . . . . . . . .
46
4.4.10 Stateful Script Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
4.5Project Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
4.5.1Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
4.5.2Accessing the active Project . . . . . . . . . . . . . . . . . . . . . . . . . .
49
4.5.3Creating a new Project. . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
4.5.3.1Mandatory Settings . . . . . . . . . . . . . . . . . . . . . . . . .
52
4.5.3.2General Settings . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
4.5.3.3Target Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
4.5.3.4Post Build Settings. . . . . . . . . . . . . . . . . . . . . . . . .
54
4.5.3.5Folders Settings. . . . . . . . . . . . . . . . . . . . . . . . . . .
54
4.5.3.6DaVinci Developer Settings . . . . . . . . . . . . . . . . . . . . .
56
4.5.4Opening an existing Project . . . . . . . . . . . . . . . . . . . . . . . . . .
57
4.5.4.1Parameterized Project Load. . . . . . . . . . . . . . . . . . . .
58
4.5.4.2Open Project Details. . . . . . . . . . . . . . . . . . . . . . . .
59
4.5.5Saving a Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
4.5.6Opening AUTOSAR Files as Project . . . . . . . . . . . . . . . . . . . . .
60
4.6Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
4.6.1Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
4.6.2Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
4.6.2.1Read the ActiveEcuc. . . . . . . . . . . . . . . . . . . . . . . .
62
4.6.2.2Write the ActiveEcuc . . . . . . . . . . . . . . . . . . . . . . . .
65
4.6.2.3Read the SystemDescription. . . . . . . . . . . . . . . . . . . .
67
4.6.2.4Write the SystemDescription . . . . . . . . . . . . . . . . . . . .
68
4.6.3BswmdModel in AutomationInterface. . . . . . . . . . . . . . . . . . . .
70
4.6.3.1BswmdModel Package and Class Names . . . . . . . . . . . . . .
70
4.6.3.2Reading with BswmdModel . . . . . . . . . . . . . . . . . . . . .
70
4.6.3.3Writing with BswmdModel . . . . . . . . . . . . . . . . . . . . .
71
4.6.3.4Sip DefRefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
© 2016, Vector Informatik GmbH
3 of
207
Contents4.6.3.5BswmdModel DefRefs . . . . . . . . . . . . . . . . . . . . . . . .
72
4.6.3.6Switching from Domain Models to BswmdModel . . . . . . . . .
73
4.6.4MDF Model in AutomationInterface . . . . . . . . . . . . . . . . . . . . .
73
4.6.4.1Reading the MDF Model . . . . . . . . . . . . . . . . . . . . . .
74
4.6.4.2Writing the MDF Model. . . . . . . . . . . . . . . . . . . . . .
76
4.6.4.3Simple Property Changes . . . . . . . . . . . . . . . . . . . . . .
77
4.6.4.4Creating single Child Members (0:1) . . . . . . . . . . . . . . . .
77
4.6.4.5Creating and adding Child List Members (0:*) . . . . . . . . . .
78
4.6.4.6Updating existing Elements . . . . . . . . . . . . . . . . . . . . .
80
4.6.4.7Deleting Model Objects . . . . . . . . . . . . . . . . . . . . . . .
81
4.6.4.8Duplicating Model Objects . . . . . . . . . . . . . . . . . . . . .
82
4.6.4.9Special properties and extensions . . . . . . . . . . . . . . . . . .
82
4.6.4.10 AUTOSAR Root Object. . . . . . . . . . . . . . . . . . . . . .
83
4.6.4.11 ActiveEcuC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
4.6.4.12 DefRef based Access to Containers and Parameters. . . . . . .
84
4.6.4.13 Ecuc Parameter and Reference Value Access . . . . . . . . . . .
85
4.6.5SystemDescription Access . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
4.6.6Transactions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
4.6.6.1Transactions API. . . . . . . . . . . . . . . . . . . . . . . . . .
89
4.6.6.2Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
4.6.7Post-build selectable Variance . . . . . . . . . . . . . . . . . . . . . . . . .
91
4.6.7.1Investigate Project Variance. . . . . . . . . . . . . . . . . . . .
91
4.6.7.2Variant Model Objects. . . . . . . . . . . . . . . . . . . . . . .
92
4.7Generation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
4.7.1Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
4.7.1.1Default Project Settings . . . . . . . . . . . . . . . . . . . . . . .
94
4.7.1.2Generate One Module . . . . . . . . . . . . . . . . . . . . . . . .
95
4.7.1.3Generate Multiple Modules . . . . . . . . . . . . . . . . . . . . .
96
4.7.1.4Generate Multi Instance Modules. . . . . . . . . . . . . . . . .
96
4.7.1.5Generate External Generation Step. . . . . . . . . . . . . . . .
96
4.7.1.6Evaluate generation or validation results. . . . . . . . . . . . .
97
4.7.2Generation Task Types. . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
4.8Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
4.8.1Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
4.8.2Access Validation-Results . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
4.8.3Model Transaction and Validation-Result Invalidation . . . . . . . . . . . 101
4.8.4Solve Validation-Results with Solving-Actions . . . . . . . . . . . . . . . . 101
4.8.4.1Solver API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
4.8.5Advanced Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4.8.5.1Access Validation-Results of a Model-Object . . . . . . . . . . . 104
4.8.5.2Access Validation-Results of a DefRef . . . . . . . . . . . . . . . 104
4.8.5.3Filter Validation-Results using an ID Constant . . . . . . . . . . 104
4.8.5.4Identification of a Particular Solving-Action . . . . . . . . . . . . 105
4.8.5.5Validation-Result Description as MixedText . . . . . . . . . . . . 106
4.8.5.6Further IValidationResultUI Methods . . . . . . . . . . . . . . . 106
4.8.5.7IValidationResultUI in a variant (Post Build Selectable) Project 107
4.8.5.8Erroneous CEs of a Validation-Result . . . . . . . . . . . . . . . 107
4.8.5.9Examine Solving-Action Execution . . . . . . . . . . . . . . . . . 108
4.8.5.10 Create a Validation-Result in a Script Task . . . . . . . . . . . . 109
4.9Update Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.9.1Method Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
© 2016, Vector Informatik GmbH
4 of
207
Contents4.9.2Example: Content of Input Files has changed. . . . . . . . . . . . . . . . . 111
4.9.3Example: List of Input Files shall be changed . . . . . . . . . . . . . . . . 112
4.9.4Prerequisites. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
4.10 Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.10.1 Communication Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.10.1.1 CanControllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
4.10.1.2 CanFilterMasks. . . . . . . . . . . . . . . . . . . . . . . . . . . 116
4.10.2 Diagnostics Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
4.10.2.1 DemEvents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
4.10.3 Runtime System Domain. . . . . . . . . . . . . . . . . . . . . . . . . . . 120
4.10.3.1 Mapping component ports. . . . . . . . . . . . . . . . . . . . . 120
4.10.3.2 Data Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.11 Persistency. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
4.11.1 Model Export . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
4.11.1.1 Export ActiveEcuc . . . . . . . . . . . . . . . . . . . . . . . . . . 141
4.11.1.2 Export Post-build selectable Variants . . . . . . . . . . . . . . . 141
4.11.1.3 Advanced Export. . . . . . . . . . . . . . . . . . . . . . . . . . 142
4.11.2 Model Import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
4.12 Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.12.1 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.12.2 Converters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
4.13 Advanced Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
4.13.1 Java Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
4.13.1.1 Script Task Creation in Java Code . . . . . . . . . . . . . . . . . 147
4.13.1.2 Java Code accessing Groovy API . . . . . . . . . . . . . . . . . . 147
4.13.1.3 Java Code in dvgroovy Scripts . . . . . . . . . . . . . . . . . . . 148
4.13.2 Unit testing API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.13.2.1 JUnit4 Integration . . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.13.2.2 Execution of Spock Tests . . . . . . . . . . . . . . . . . . . . . . 150
4.13.2.3 Registration of Unit Tests in Scripts . . . . . . . . . . . . . . . . 150
5Data models in detail1525.1MDF model - the raw AUTOSAR data. . . . . . . . . . . . . . . . . . . . . . . 152
5.1.1Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
5.1.2The models inheritance hiearchy . . . . . . . . . . . . . . . . . . . . . . . 152
5.1.2.1MIObject and MDFObject . . . . . . . . . . . . . . . . . . . . . 152
5.1.3The models containment tree . . . . . . . . . . . . . . . . . . . . . . . . . 153
5.1.4The ECUC model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
5.1.5Order of child objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
5.1.6AUTOSAR references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
5.1.7Model changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
5.1.7.1Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
5.1.7.2Undo/redo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
5.1.7.3Event handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
5.1.7.4Deleting model objects. . . . . . . . . . . . . . . . . . . . . . . 157
5.1.7.5Access to deleted objects . . . . . . . . . . . . . . . . . . . . . . 157
5.1.7.6Set-methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
5.1.7.7Changing child list content . . . . . . . . . . . . . . . . . . . . . 157
5.1.7.8Change restrictions. . . . . . . . . . . . . . . . . . . . . . . . . 157
5.2Post-build selectable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
5.2.1Model views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
5.2.1.1What model views are . . . . . . . . . . . . . . . . . . . . . . . . 158
© 2016, Vector Informatik GmbH
5 of
207
Contents5.2.1.2The IModelViewManager project service. . . . . . . . . . . . . 158
5.2.1.3Variant siblings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
5.2.1.4The Invariant model views . . . . . . . . . . . . . . . . . . . . . 161
5.2.1.5Accessing invisible objects . . . . . . . . . . . . . . . . . . . . . . 163
5.2.1.6IViewedModelObject. . . . . . . . . . . . . . . . . . . . . . . . 164
5.2.2Variant specific model changes. . . . . . . . . . . . . . . . . . . . . . . . 164
5.2.3Variant common model changes . . . . . . . . . . . . . . . . . . . . . . . . 165
5.3BswmdModel details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
5.3.1BswmdModel - DefinitionModel . . . . . . . . . . . . . . . . . . . . . . . . 166
5.3.1.1Types of DefinitionModels. . . . . . . . . . . . . . . . . . . . . 167
5.3.1.2DefRef Getter methods of Untyped Model . . . . . . . . . . . . . 168
5.3.1.3References. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
5.3.1.4Post-build selectable with BswmdModel . . . . . . . . . . . . . . 171
5.3.1.5Creation ModelView of the BswmdModel . . . . . . . . . . . . . 172
5.3.1.6Lazy Instantiating . . . . . . . . . . . . . . . . . . . . . . . . . . 173
5.3.1.7Optional Elements . . . . . . . . . . . . . . . . . . . . . . . . . . 173
5.3.1.8Class and Interface Structure of the BswmdModel . . . . . . . . 173
5.3.1.9BswmdModel write access. . . . . . . . . . . . . . . . . . . . . 174
5.4Model utility classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
5.4.1AsrPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
5.4.2AsrObjectLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
5.4.2.1Object links depend on the MDF object type . . . . . . . . . . . 177
5.4.2.2Restrictions of object links . . . . . . . . . . . . . . . . . . . . . 178
5.4.2.3Examples for object link strings. . . . . . . . . . . . . . . . . . 178
5.4.3DefRefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
5.4.3.1TypedDefRefs. . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
5.4.3.2DefRef Wildcards. . . . . . . . . . . . . . . . . . . . . . . . . . 180
5.4.4CeState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
5.4.4.1Getting a CeState object . . . . . . . . . . . . . . . . . . . . . . 181
5.4.4.2IParameterStatePublished . . . . . . . . . . . . . . . . . . . . . . 182
5.4.4.3IContainerStatePublished . . . . . . . . . . . . . . . . . . . . . . 183
6AutomationInterface Content1846.1Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
6.2Folder Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
6.3Script Development Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
6.3.1DVCfg_AutomationInterfaceDocumentation.pdf . . . . . . . . . . . . . . 184
6.3.2Javadoc HTML Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
6.3.3Script Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
6.4Libs and BuildLibs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
7Automation Script Project1867.1Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
7.2Automation Script Project Creation. . . . . . . . . . . . . . . . . . . . . . . . . 186
7.3Project File Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
7.4IntelliJ IDEA Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.4.1Supported versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.4.2Building Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.4.3Debugging with IntelliJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.4.4Troubleshooting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
7.5Project Migration to newer DaVinci Configurator Version . . . . . . . . . . . . . 189
7.6Debugging Script Project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
© 2016, Vector Informatik GmbH
6 of
207
Contents7.7Build System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
7.7.1Jar Creation and Output Location . . . . . . . . . . . . . . . . . . . . . . 190
7.7.2Gradle File Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
7.7.2.1projectConfig.gradle File settings . . . . . . . . . . . . . . . . . . 191
7.7.3Advanced Build Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
7.7.3.1Gradle dvCfgAutomation API Reference. . . . . . . . . . . . . 192
8AutomationInterface Changes between Versions1938.1Changes in MICROSAR AR4-R17 - Cfg5.14 . . . . . . . . . . . . . . . . . . . . . 193
8.1.1General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
8.1.2Script Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
8.1.2.1Stateful Script Tasks . . . . . . . . . . . . . . . . . . . . . . . . . 193
8.1.3Automation Script Project . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
8.1.3.1Groovy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
8.1.3.2Supported IntelliJ IDEA Version . . . . . . . . . . . . . . . . . . 193
8.1.3.3BuildSystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
8.1.4Converter Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
8.1.5UserInteraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
8.1.6Project Load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
8.1.6.1AUTOSAR Arxml Files . . . . . . . . . . . . . . . . . . . . . . . 194
8.1.7Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
8.1.7.1Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
8.1.7.2MDF Model Read and Write . . . . . . . . . . . . . . . . . . . . 195
8.1.7.3SystemDescription Access . . . . . . . . . . . . . . . . . . . . . . 195
8.1.7.4ActiveEcuc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
8.1.8Persistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
8.1.9Generation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
8.1.10 BswmdModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
8.1.10.1 Writing with BswmdModel . . . . . . . . . . . . . . . . . . . . . 196
8.1.11 BswmdModel Groovy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
8.1.12 Domain Diagnostics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
8.1.13 Domain Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
8.1.14 Domain Runtime System. . . . . . . . . . . . . . . . . . . . . . . . . . . 196
8.2Changes in MICROSAR AR4-R16 - Cfg5.13 . . . . . . . . . . . . . . . . . . . . . 197
8.2.1General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.2.2API Stability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.2.3Beta Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
9Appendix198Nomenclature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Figures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Listings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
ToDos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
© 2016, Vector Informatik GmbH
7 of
207
1 Introduction1.1 GeneralThe user of the DaVinci Configurator Pro can create scripts, which will be executed inside of
the Configurator to:
• Create projects
• Update projects
• Manipulate the data model with an access to the whole AUTOSAR model
• Generate code
• Executed repetitive tasks with code, without user interaction
• More
The scripts are written by the
user with the DaVinci Configurator AutomationInterface.
1.2 FactsInstallationThe DaVinci Configurator Pro can execute customer defined scripts out of the
box. No additional scripting language installation is required by the customer.
LanguagesThe scripts are written in Groovy or Java. See
3.2 on page 16 for details.
Debugging SupportThe scripts can be debugged via IntelliJ IDEA. See
7.6 on page 190.DocumentationThe AutomationInterface provides a comprehensive documentation:
• This document
• Javadoc HTML pages as class reference
• Script samples and templates
– ScriptProject creation assistant in the DaVinci Configurator
• API documentation inside of an IDE
• Integrated Definition (BSWMD) description for all modules in the SIP
Code CompletionYou have code completion for Groovy and Java for the DaVinci Configu-
rator AutomationInterface. You have to use IntelliJ IDEA for code
completion.1There is also a SIP based code completion for contained Module, Container and Parameter
definitions. This eases the traversal through the AUTOSAR model.
1See chapter
7 on page 186 for details.
© 2016, Vector Informatik GmbH
8 of
207
2 Getting started with Script Development2.1 GeneralThis chapter gives a short introduction of how to get started with script file or script project
creation.
Attention: You need at least one of the
License Options .WF or .MD to develop scripts.
The script project creation assistant will not be available otherwise.
2.2 Automation Script Development TypesThe DaVinci Configurator supports two types of automation scripts:
• Script files (.dvgroovy files)
• Script projects (.jar files)
Script FileThe script file provides the
simplest way to implement an automation script.
When the script gets bigger you should migrate to a script project.
To create a script file proceed with chapter
2.3.Script ProjectThe script project is
more effort to create and maintain, but provides IDE
support for:
• Code completion
• Syntax highlighting
• API Documentation
• Debug support
• Build support
It is the
recommended way to develop scripts, containing more tasks or multiple classes.
To create a script project proceed with chapter
2.4 on page 11.2.3 Script FileThe script file is the simplest way to implement an automation script. It could be sufficient
for small tasks and if the developer does not need support by the tool during implementing the
script and if debugging is not required.
PrerequisitesBefore you start, please make sure that you have a
SIP containing a DaVinci
Configurator 5 available on your system.
© 2016, Vector Informatik GmbH
9 of
207



Chapter 2.Getting started with Script DevelopmentCreationInside your SIP you find examples of automation script files.
Create your own
script folder and copy an example, e.g. ...ScriptSamples/SimpleScript.dvgroovy to your
folder.
Rename the script file and open it in any text editor. In case of SimpleScript.dvgroovy
it consists of several tasks.
One of the tasks will print a "HelloApplication" string to the
console.
Figure 2.1: Script Samples location
Open the DaVinci Configurator inside your SIP. If not yet visible open the Views
• Script Locations
• Script Tasks
via the View menu.
In the
Script Locations View select the location folder User@Machine. On its context menu
you can
Add a script location. Select your own script folder.
Figure 2.2: Script Locations View
Alternatively you could add the script location to the Session folder. In this case the script
location would only be stored in the current session.
Switch to the
Script Tasks View. It provides an overview over the tasks contained in your
script.
Figure 2.3: Script Tasks View
© 2016, Vector Informatik GmbH
10 of
207

Chapter 2.Getting started with Script DevelopmentExecute the SimpleAppTask by double-click or by the Execute Command contained in its
context menu or by the Execute Button of the Task View and check that "HelloApplication" is
printed in the console.
You can modify the implementation according to your needs. For the AutomationInterface
API Reference see chapter
4 on page 22. It is sufficient to edit and save the modifications in
your editor. The file is automatically reloaded by the DaVinci Configurator then and can be
executed immediately.
DebuggingIt is not possible to debug a script file, if you want to debug, please migrate to a
script project, see chapter
2.4.2.4 Script ProjectThe script project is the preferred way to develop an automation script, if the content is more
than one simple task.
A script project is a normal IDE project (IntelliJ IDEA recommended), with compile bindings
to the DaVinci Configurator AutomationInterface.
The DaVinci Configurator will load a script project as a single .jar file. So the script project
must be built and packaged into a .jar file before it can be executed.
PrerequisitesBefore you start,
please make sure that the following items are available on
your system:
•
SIP containing a DaVinci Configurator 5
•
Java JDK: For the development with the IntelliJ IDEA a "Java SE Development Kit 8"
(JDK 8) is required. Please install the JDK 8 as described in chapter
2.4.2 on page 13.•
IDE: For the script project development the
recommended IDE is
IntelliJ IDEA. Please
install IntelliJ IDEA as described in chapter
2.4.3 on page 14.•
Build system: To build the script project the build system Gradle is required. See
chapter
2.4.4 on page 14 for installation instructions.
Project CreationOpen the DaVinci Configurator inside your SIP. If not yet visible open the
following Views via the View menu:
• Script Locations
• Script Tasks
Switch to the View
Script Tasks and select the Button
Create New Script Project....
Figure 2.4: Create New Script Project... Button
Note: If the button is not available, please make sure you have least one of the
License
Options .WF or .MD to develop scripts.
© 2016, Vector Informatik GmbH
11 of
207

Chapter 2.Getting started with Script DevelopmentThe
New Automation Script Project dialogs is opened. Click
Next because you are reading
the document.
On the second page first you have to select a Script template on which the new project shall be
based on. Please select Default Automation Project and click
Next.
On the third page
Project Settings, please specify the following items:
•
Script Project Name– Define a name for your new project.
•
Project Location– Select a parent folder in which your project shall be created in.
Note: A new folder with the project name is created in this folder.
•
Gradle Distribution URL– Select one option:
∗
Gradle Default· This will download the required Gradle build system. To use this option you
need
internet access.
∗
Custom URL· Specify an URL to your own Gradle distribution.
New settings are displayed to specify the path. To setup your own Gradle
build system see
2.4.4 on page 14.•
Open IntelliJ IDEA– Select this option if the project shall automatically be opened in IntelliJ IDEA after
creation. In case IntelliJ IDEA is not installed on your system a warning will be
issued.
Figure 2.5: Project Settings
Proceed until the dialog is finished.
© 2016, Vector Informatik GmbH
12 of
207

Chapter 2.Getting started with Script DevelopmentA new project will be created. Necessary tasks as setting up the IntelliJ IDEA and building the
project are automatically initiated. At the end IntelliJ IDEA will be started with the created
project.
You can now modify the implementation according to your needs. For the AutomationInterface
API Reference see chapter
4 on page 22. To edit and rebuild the project use IntelliJ IDEA.
After each build the project is automatically reloaded by the DaVinci Configurator and can be
executed there.
IntelliJ IDEA UsageEnsure that the Gradle JVM and the Project SDK are set in the IntelliJ
IDEA Settings. For details see
2.4.3 on the following page.Having modified and saved MyScript.groovy in the IntelliJ IDEA editor you can build the
project by pressing the
Run Button provided in the toolbar. The functionality of this Run
Button is determined by the option selected in the Menu beneath this button. In this menu
<ProjectName> [build] shall be selected.
Figure 2.6: Project Build
For more information to IntelliJ IDEA usage please see chapter
7.4 on page 187. If you have
trouble with IntelliJ, see
7.4.4 on page 189.DebuggingTo debug the script project follow the instructions in chapter
7.6 on page 190.DaVinci Configurator viewsThe View
Script Tasks provides an overview over the scripts
and tasks contained in the project. The newly created project already contains a sample script
file MyScript.groovy.
The Default Automation Project sample script file contains one task that prints a "Hel-
loApplication" string to the console. Run and check it as already described in
2.3 on page 9.
If you have selected a different Script Sample the MyScript.groovy will contain the sample
code.
The View
Script Locations contains the path to the script project build folder containing the
built .jar file.
2.4.1 Script Project DevelopmentFor more details to the development of a script project see chapter
7 on page 186.2.4.2 Java JDK SetupInstall a JDK 8 on your system. The
Java JDK website provides download versions for different
systems. Download an appropriate version.
The architecture is not relevant, both x86 and x64 are valid.
The JDK is needed for the Java Compiler for IntelliJ IDEA and Gradle.
© 2016, Vector Informatik GmbH
13 of
207


Chapter 2.Getting started with Script Development2.4.3 IntelliJ IDEA SetupInstall IntelliJ IDEA on your system. The
IntelliJ IDEA website provides download versions
for different applications. Download a version that supports Java and Groovy and that is in
the list of supported versions (see list
7.4.1 on page 187).Code completion and compilation additionally require that the Project SDK is set. Therefore
open the File ->
Project Structure Dialog in IntelliJ IDEA and switch to the settings dialog
for
Project. If not already available set an appropriate option for the
Project SDK. Please
set the value to a valid Java JDK ( see
2.4.2 on the previous page). Do not select a JRE.
Figure 2.7: Project SDK Setting
To enable building of projects ensure that the Gradle JVM is set. Therefore open the File
->
Settings Dialog in IntelliJ IDEA and find the settings dialog for
Gradle. If not already
available set an appropriate option for the
Gradle JVM. Please set the value to the same Java
JDK as the Project SDK above.
Do not select a JRE.
If you do not have the Gradle settings, please make sure that the Gradle plugin inside of
IntelliJ IDEA is installed. Open the File ->
Settings Dialog then Plugins and select the
Gradle plugin.
Figure 2.8: Gradle JVM Setting
2.4.4 Gradle SetupIf your system has internet access you can use the default Gradle Build System provided by
the DaVinci Configurator. In this case you
do not have to install Gradle. If you are a Vector
internal user you could also
skip the Gradle installation.
If you want to use your own Gradle Build System install it on your system. The
Gradle website
provides the required download version for the Gradle Build System. Please
download the
version 3.0. See chapter
7.7 on page 190 for more details to the Build System.
© 2016, Vector Informatik GmbH
14 of
207
3 AutomationInterface Architecture3.1 ComponentsThe DaVinci Configurator consists of three components:
• Core components
• AutomationInterface (AI) - also called Automation API
• Scripting engine
The other part is the script provided by the user.
The Scripting engine will load the script, and the script uses the AutomationInterface to perform
tasks. The AutomationInterface will translate the requests from the script into Core components
calls.
Figure 3.1: DaVinci Configurator components and interaction with scripts
The separation of the AutomationInterface and the Core components has multiple benefits:
• Stable API for script writters
– Including checks, that the API will not break in following releases
• Well defined and documented API
• Abstraction from the internal heavy lifting
– This ease the usage for the user, because the automation interfaces are tailored to
the use cases.
PublishedApiAll AutomationInterface classes are marked with a special annotation to
high-light the fact that it is part of the published API. The annotation is called @PublishedApi.
So every class marked with @PublishedApi can be used by the client code. But if a class is
not marked with @PublishedApi or is marked with @Deprecated it should not be used by any
client code, nor shall a client call methods via reflection or other runtime techniques.
© 2016, Vector Informatik GmbH
15 of
207
Chapter 3.AutomationInterface ArchitectureYou should
not access DaVinci Configurator private or package private classes, methods or
fields.
3.2 LanguagesThe DaVinci Configurator provides out of the box language support for:
• Jav
a1• Groo
vy2The recommended scripting language is
Groovy which shall be preferred by all users.
3.2.1 Why GroovyFlat Learning CurveGroovy is concise, readable with an expressive syntax and is easy to
learn for Java develop
ers3.• Groovy syntax is 95%-compatible with Jav
a4• Any Java developer will be able to code in Groovy without having to know nor understand
the subtleties of this language
This is very important for teams where there’s not much time for learning a new language.
Domain-Specific Languages (DSL)Groovy has a flexible and malleable syntax, advanced
integration and customization mechanisms, to integrate readable business rules in your appli-
cations.
The DSL features of Groovy are extensively used in DaVinci Automation API to provide simple
and expressive syntax.
Powerful FeaturesGroovy supports Closures, builders, runtime & compile-time meta-programming,
functional programming, type inference, and static compilation.
WebsiteThe website of Groovy is
http://groovy-lang.org. It provides a good documentation
and starting guides for the Groovy language.
Groovy BookThe book
"Groovy in Action, Second Edition"5 provides a comprehensive
guide to Groovy programming language. It is written by the developers of Groovy.
1http://http://www.java.com [2016-05-09]
2http://groovy-lang.org [2016-05-09]
3Copied from
http://groovy-lang.org [2016-05-09]
4Copied from
http://melix.github.io/blog/2010/07/27/experience_feedback_on_groovy.html [2016-05-09]
5Groovy in Action, Second Edition by Dierk König, Paul King, Guillaume Laforge, Hamlet D’Arcy, Cédric
Champeau, Erik Pragt, and Jon Skeet June 2015 ISBN 9781935182443
https://www.manning.com/books/groovy-in-action-second-edition [2016-05-09]
© 2016, Vector Informatik GmbH
16 of
207

Chapter 3.AutomationInterface Architecture3.3 Script StructureA script always contains one or more script tasks. A script is represented by an instance of
IScript, the contained tasks are instances of IScriptTask.
Figure 3.2: Structure of scripts and script tasks
You create the IScript and IScriptTask instance with the API described in chapter
4.2 on
page 23.The script task type (IScriptTaskType) defines where the task could be executed. It also
defines the signature of the task’s code {} block. See chapter
4.3 on page 27 for the available
script task types.
3.3.1 ScriptsScript contain the tasks to execute and are loaded from the script locations specified in the
DaVinci Configurator.
The DaVinci Configurator supports two types of automation scripts:
• Script files (.dvgroovy files)
• Script projects (.jar files)
For details to the script project, see chapter
7 on page 186.© 2016, Vector Informatik GmbH
17 of
207
Chapter 3.AutomationInterface Architecture3.3.2 Script TasksScript tasks are the executable units of scripts, which are executed at certain points in the
DaVinci Configurator (specified by the IScriptTaskType). Every script task has a code {}
block, which contains the logic to execute.
3.3.3 Script LocationsScript locations define where script files are loaded from. These locations are edited in the
DaVinci Configurator Script Locations view. You can also start the Configurator with the
option –scriptLocations to specify additional locations.
The DaVinci Configurator could load scripts from different script locations:
• SIP
• Project
• User-defined directories
• More
3.4 Script loadingAll scripts contained in the script locations are automatically loaded by the DaVinci Configu-
rator. If new scripts are added to script locations these scripts are automatically loaded.
If a script changes during runtime of the DaVinci Configurator the whole script is reloaded and
then executable, without a restart of the tool or a reload of the project.
This enables script development during the runtime of the DaVinci Configurator
• No project reload
• No tool restart
• Faster feedback loops
Note: A jar file of a script project
should be updated by the Gradle build system, not by hand.
Because the Java VM is holding a lock to the file. If you try to replace the file in the explorer
you will get an error message.
3.4.1 Internal Script Reload BehaviorYour script can be loaded and unloaded automatically multiple times during the execution of
the DaVinci Configurator. More precise, when a script is currently not used and there are
memory constraints your script will be automatically unloaded.
If the script will be executed again, it is automatically reloaded and then executed. So it is
possible that the script initialization code is called multiple times in the DaVinci Configurator
lifecycle. But this is no issue, because the script and the tasks
shall not have any internal
state during initialization.
© 2016, Vector Informatik GmbH
18 of
207
Chapter 3.AutomationInterface ArchitectureMemory Leak PreventionThe feature above is implemented to prevent leaking memory from
an automation script into the DaVinci Configurator memory. So when the memory run low, all
unused scripts are unloaded, which will also free leaked memory of scripts.
But this
does not mean that is impossible to construct memory leaks from an automation
script. E.g. Open file handles without closing them will still cause a memory leak.
3.5 Script editingThe DaVinci Configurator does not contain any editing support for scripts, like:
• Script editor
• Debugger
• REPL (Read-Eval-Print-Loop)
These tasks are delegated to other development tools:
• IntelliJ IDEA (recommended)
• EclipseIDE
• Notepad++
See chapter
7 on page 186 for script development and debugging with IntelliJ IDEA.
3.6 LicensingThe DaVinci Configurator requires certain license options to develop and/or execute script
tasks.
The required license options differ between development and execution time. Normally you
need more license options to develop scripts than you need to execute them.
The default license options are:
• .PRO option for execution
• .WF option for development and debugging
The license option .MD includes the option .WF for automation scripts. So you can also use
.MD as replacement of .WF.
Some script task may require different options during development or execution. It is also
possible that the execution does not require any license option. See chapter
4.3 on page 27 for
details, which script task type requires which license.
3.7 Script Coding Conventions and ConstraintsThis section describes conventions, which you are advised to apply.
© 2016, Vector Informatik GmbH
19 of
207
Chapter 3.AutomationInterface ArchitectureRequirement Levels - Wording• Shall: This word, or the terms "Mandatory", "Required" or "Must", mean that the rule or
convention is an absolute requirement.
• Shall not: This word, or the terms "Must not" mean that the rule or convention is an
absolute prohibition.
• Should: This word, or the adjective "Recommended", mean that there may exist valid
reasons in particular circumstances to ignore a particular item, but the full implications
must be understood and carefully weighed before choosing a different course.
• Should not: This phrase, or the phrase "Not recommended" mean that there may exist
valid reasons in particular circumstances when the particular behavior is acceptable or
even useful, but the full implications should be understood and the case carefully weighed
before implementing any behavior described with this label.
• May: This word, or the adjective "Optional", mean that an item is truly optional.
See also "RFC 2119: Key words for use in RFCs to Indicate Requirement Lev
els"6.3.7.1 Usage of static fieldsYou
shall not use any static fields in your script code or other written classes inside of your
project. Except static final constants of simple immutable types like (normally compile time
constants):
• int
• boolean
• double
• String
• ...
Static fields will cause memory leaks, because the fields are not garbage collected. Exam-
ple:
scriptTask("Name"){
code{
MyClass.leakVariable.add("Leaked Memory")
}
}
class MyClass{
static List leakVariable = []
}
Listing 3.1: Static field memory leak
The use of static fields of the AutomationInterface is allowed.
6https://www.ietf.org/rfc/rfc2119.txt© 2016, Vector Informatik GmbH
20 of
207
Chapter 3.AutomationInterface Architecture3.7.2 Usage of Outer Closure Scope VariablesThe same static field rule applies to variables passed from outer Closure scopes into a script
task code{} block. You
shall not cache/save data into such variables.
Example:
scriptTask("Name"){
def invalidVariable = [] //List
code{
invalidVariable.add("Leaked Memory")
}
}
Listing 3.2: Memory leak with closure variable
3.7.3 States over script task executionYou
shall not hold or save any states over multiple script task executions in your classes.
The script task should be state less. All states are provided by the Automation API or the data
models.
If you need to cache data over multiple executions, see chapter
4.4.10 on page 47 for a solu-
tion.
3.7.4 Usage of ThreadsA script task
shall not create any Thread, Executor, ThreadPool or ForkJoinPool in-
stances. If multithreading is required, the Automation API provides the corresponding meth-
ods.
A different thread will not provide any Automation APIs and will cause IllegalStateExcep-
tions.
3.7.5 Usage of DaVinci Configurator private Classes Methods or FieldsA script task
should not call or rely on any non published API or private (also package private)
classes, methods or fields. You also should not use any reflection techniques to reflect about
Configurator internal APIs. Otherwise it is not guaranteed that your script will work with other
DaVinci Configurator versions. See
3.1 on page 15 for details about PublishedApi.
But it is valid to use reflection for your own script code.
© 2016, Vector Informatik GmbH
21 of
207
4 AutomationInterface API Reference4.1 IntroductionThis chapter contains the description of the DaVinci Configurator AutomationInterface. The
figure
4.1 shows the APIs and the containment structure of the different APIs.
Figure 4.1: The API overview and containment structure
The components have an hierarchical order, where and when the components are usable. When a
component is contained in another the component is only usable, when the other is active.
© 2016, Vector Informatik GmbH
22 of
207
Chapter 4.AutomationInterface API ReferenceUsage examples:
• The Generation API is only usable inside of a loaded Project
• The Workflow Update API is only usable outside of a loaded Project
4.2 Script CreationThis section lists the APIs to create, execute and query information for script tasks. The
sections document the following aspects:
• Script task creation
• Description and help texts
• Task executable query
4.2.1 Script Task CreationTo create a script task you have to call one of the scriptTask() methods. The last parameter
of the scriptTask methods can be used to set additional options of the task. Every script task
needs one IScriptTaskType. See chapter
4.3 on page 27 for all available task types.
The code{ } block is
required for every IScriptTask. The block contains the code, which is
executed when the task is executed.
Script Task with default TypeThe method scriptTask() will create an script task for the
default IScriptTaskType DV_PROJECT.
scriptTask("TaskName"){
code{
// Task execution code here
}
}
Listing 4.1: Task creation with default type
Script Task with Task TypeYou could also define the used IScriptTaskType at the script-
Task() methods.
The methods
• scriptTask(String, IApplicationScriptTaskType, Closure)
• scriptTask(String, IProjectScriptTaskType, Closure)
will create an script task for passed IScriptTaskType. The two methods differentiate, if a
project is required or not. See chapter for all available task types
4.3 on page 27© 2016, Vector Informatik GmbH
23 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName", DV_APPLICATION){
code{
// Task execution code here
}
}
Listing 4.2: Task creation with TaskType Application
scriptTask("TaskName", DV_PROJECT){
code{
// Task execution code here
}
}
Listing 4.3: Task creation with TaskType Project
Multiple Tasks in one ScriptIt is also possible to define multiple tasks in one script.
scriptTask("TaskName"){
code{ }
}
scriptTask("SecondTask"){
code{ }
}
Listing 4.4: Define two tasks is one script
4.2.1.1 Script Creation with IDE Code Completion SupportThe IDE could not know which API is available inside of a script file. So a glue code is needed
to tell the IDE, what API is callable inside of a script file.
The ScriptApi.daVinci() method enables the IDE code completion support in a script file.
You have to write the daVinci{ } block and inside of the block the code completion is available.
The following sample shows the glue code for the IDE:
import static com.vector.cfg.automation.api.ScriptApi.*
//daVinci enables the IDE code completion support
daVinci{
// Normal script code here
scriptTask("TaskName"){
code{// Script task execution code here
}
}
}
Listing 4.5: Script creation with IDE support
The daVinci{} block is only required for code completion support in the IDE. It has no effect
during runtime, so the daVinci{} is optional in script files (.dvgroovy)
© 2016, Vector Informatik GmbH
24 of
207
Chapter 4.AutomationInterface API Reference4.2.1.2 Script Task isExecutableIfYou can set an isExecutableIf handler, which is called before the IScriptTask is executed.
The code can evaluate, if the IScriptTask shall be executable. If the handler returns true, the
code of the IScriptTask is executable, otherwise false. See class IExecutableTaskEvaluator
for details.
The Closure isExecutable has to return a boolean. The passed arguments to the closure are
the same as the code{ } block arguments.
Inside of the Closure a property notExecutableReasons is available to set reasons why it is not
executable. It is highly recommended to set reasons, when the Closure returns false.
scriptTask("TaskName"){
isExecutableIf{ taskArgument ->
// Decide, if the task shall be executable
if(taskArgument == "CorrectArgument"){
return true}
notExecutableReasons.addReason "The argument is not 'CorrectArgument'"
return false}
code{ taskArgument ->
// Task execution code here
}
}
Listing 4.6: Task with isExecutableIf
4.2.2 Description and HelpScript DescriptionThe script can have an optional description text. The description shall
list what this script contains. The method scriptDescription(String) sets the description
of the script.
The description shall be a short overview. The String can be multiline.
// You can set a description for the whole script
scriptDescription "The Script has a description"
scriptTask("Task"){
code{}
}
Listing 4.7: Script with description
Task DescriptionA script task can have an optional description text. The description shall
help the user of the script task to understand what the task does. The method taskDescrip-
tion(String) sets the description of the script task.
The description shall be a short overview. The String can be multiline.
© 2016, Vector Informatik GmbH
25 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
taskDescription "The description of the task"
code{ }
}
Listing 4.8: Task with description
Task HelpA script task can also have an optional help text. The help text shall describe in
detail what the task does and when it could be executed. The method taskHelp(String) sets
the help of the script task.
The help shall be elaborate text about what the task does and how to use it. The String can
be multiline.
The help text is automatically expanded with the help for user defined script task arguments,
see IScriptTaskBuilder.newUserDefinedArgument(String, Class, String).
scriptTask("TaskName"){
taskDescription "The short description of the task"
taskHelp """
The long help text
of the script with multiple lines
And paragraphs ...
""".stripIndent()
// stripIndent() will strip the indentation of multiline strings
// The three """ are needed, if you want to write a multiline string
code{ }
}
Listing 4.9: Task with description and help text
© 2016, Vector Informatik GmbH
26 of
207

Chapter 4.AutomationInterface API Reference4.3 Script Task TypesThe IScriptTaskType instances define where a script task is executed in the DaVinci Configu-
rator. The types also define the arguments passed to the script task execution and what return
type an execution has.
Every script task needs an IScriptTaskType. The type is set during creation of the script
tasks.
License OptionsFor the common explanation of the required license options, see chapter
3.6on page 19.InterfacesAll task types implement the interface IScriptTaskType. The following figure
show the type and the defined sub types:
Figure 4.2: IScriptTaskType interfaces
4.3.1 Available TypesThe class IScriptTaskTypeApi defines all available IScriptTaskTypes in the DaVinci Config-
urator. All task types start with the prefix DV_.
None at parameters and return types mean, that any arguments could be passed and return to
or from the task. Normally it will be nothing. The arguments are used, when the task is called
in unit tests for example.
4.3.1.1 Application TypesApplicationThe type
DV_APPLICATION is for application wide script tasks. A task could
create/open/close/update projects. Use this type, if you need full control over the project
handling, or you want to handle multiple project at once.
© 2016, Vector Informatik GmbH
27 of
207
Chapter 4.AutomationInterface API ReferenceNameApplication
Code identifierDV_APPLICATION
Task type interfaceIApplicationScriptTaskType
ParametersNone
Return typeNone
ExecutionStandalone
Required license optionDevelopment: .WF Execution: .PRO
4.3.1.2 Project TypesProjectThe type
DV_PROJECT is for project script tasks. A task could access the currently
loaded project. Manipulate the data, generate and save the project. This is the default type, if
no other type is specified.
NameProject
Code identifierDV_PROJECT
Task type interfaceIProjectScriptTaskType
ParametersNone
Return typeNone
ExecutionStandalone
Required license optionDevelopment: .WF Execution: .PRO
Module activationThe type
DV_ON_MODULE_ACTIVATION allows the script to hook any Mod-
ule Activation in a loaded project. Every DV_ON_MODULE_ACTIVATION task is automatically
executed, when an "Activate Module" operation is executed. The script task is called after the
module was created.
NameModule activation
Code identifierDV_ON_MODULE_ACTIVATION
Task type interfaceIProjectScriptTaskType
ParametersMIModuleConfiguration moduleConfiguration
Return typeVoid
ExecutionAutomatically during module activation
Required license optionDevelopment: .WF Execution: .PRO
Module deactivationThe type
DV_ON_MODULE_DEACTIVATION allows the script to hook any
Module Deactivation in a loaded project. Every DV_ON_MODULE_DEACTIVATION task is automat-
ically executed, when an "Deactivate Module" operation is executed. The script task is called
before the module is deleted.
NameModule deactivation
Code identifierDV_ON_MODULE_DEACTIVATION
Task type interfaceIProjectScriptTaskType
ParametersMIModuleConfiguration moduleConfiguration
Return typeVoid
ExecutionAutomatically during module deactivation
Required license optionDevelopment: .WF Execution: .PRO
© 2016, Vector Informatik GmbH
28 of
207
Chapter 4.AutomationInterface API Reference4.3.1.3 UI TypesEditor selectionThe type
DV_EDITOR_SELECTION allows the script task to access the currently
selected element of an editor. The task is executed in context of the selection and is not callable
by the user without an active selection.
NameEditor selection
Code identifierDV_EDITOR_SELECTION
Task type interfaceIProjectScriptTaskType
ParametersMIObject selectedElement
Return typeVoid
ExecutionIn context menu of an editor selection
Required license optionDevelopment: .WF Execution: .PRO
Editor multiple selectionsThe type
DV_EDITOR_MULTI_SELECTION allows the script task to
access the currently selected elements of an editor. The task is executed in context of the
selection and is not callable by the user without an active selection. The type is also usable
when the DV_EDITOR_SELECTION apply.
NameEditor multiple selections
Code identifierDV_EDITOR_MULTI_SELECTION
Task type interfaceIProjectScriptTaskType
ParametersList<MIObject> selectedElements
Return typeVoid
ExecutionIn context menu of an editor selection
Required license optionDevelopment: .WF Execution: .PRO
4.3.1.4 Generation TypesGeneration StepThe type
DV_GENERATION_STEP defines that the script task is executable as
a GenerationStep during generation. The user has to explicitly create an GenerationStep in the
Project Settings Editor, which references the script task.
NameGeneration Step
Code identifierDV_GENERATION_STEP
Task type interfaceIProjectScriptTaskType
ParametersEGenerationPhaseType phase
EGenerationProcessType processType
IValidationResultSink resultSink
Return typeVoid
ExecutionSelected as GenerationStep in GenerationProcess
Required license optionDevelopment: .MD Execution: None
See chapter
4.7.2 on page 98 for usage samples.
Custom Workflow StepThe type
DV_CUSTOM_WORKFLOW_STEP defines that the script task
is executable as a CustomWorkflow step in the CustomWorkflow process. The user has to
explicitly create an CustomWorkflow step in the Project Settings Editor, which references the
script task.
© 2016, Vector Informatik GmbH
29 of
207
Chapter 4.AutomationInterface API ReferenceNameCustom Workflow Step
Code identifierDV_CUSTOM_WORKFLOW_STEP
Task type interfaceIProjectScriptTaskType
ParametersNone
Return typeVoid
ExecutionSelected as Custom Workflow Step in the Project Settings Editor
Required license optionDevelopment: .WF Execution: .PRO
See chapter
4.7.2 on page 98 for usage samples.
Generation Process StartThe type
DV_ON_GENERATION_START defines that the script task is
automatically executed when the generation is started.
NameGeneration Process Start
Task type interfaceIProjectScriptTaskType
Code identifierDV_ON_GENERATION_START
ParametersList<EGenerationPhaseType> generationPhases
List<IGenerator> executedGenerators
Return typeVoid
ExecutionAutomatically before GenerationProcess
Required license optionDevelopment: .MD Execution: None
See chapter
4.7.2 on page 98 for usage samples.
Generation Process EndThe type
DV_ON_GENERATION_END defines that the script task is
automatically executed when the generation has finished.
NameGeneration Process End
Code identifierDV_ON_GENERATION_END
Task type interfaceIProjectScriptTaskType
ParametersEGenerationProcessResult processResult
List<IGenerator> executedGenerators
Return typeVoid
ExecutionAutomatically after GenerationProcess
Required license optionDevelopment: .MD Execution: None
See chapter
4.7.2 on page 98 for usage samples.
© 2016, Vector Informatik GmbH
30 of
207
Chapter 4.AutomationInterface API Reference4.4 Script Task ExecutionThis section lists the APIs to execute and query information for script tasks. The sections
document the following aspects:
• Script task execution
• Logging API
• Path resolution
• Error handling
• User defined classes and methods
• User defined script task arguments
4.4.1 Execution ContextEvery IScriptTask could be be executed, and retrieve passed arguments and other context
information. This execution information of a script task is tracked by the IScriptExecution-
Context.
The IScriptExecutionContext holds the context of the execution:
• The script task arguments
• The current running script task
• The current active script logger
• The active project, if existing
• The script temp folder
• The script task user defined arguments
The IScriptExecutionContext is also the entry point into every automation API, and pro-
vide access to the different API classes. The classes are describes in their own chapters like
IProjectHandlingApiEntryPoint or IWorkflowApiEntryPoint.
The context is immediately active, when the code block of an IScriptTask is called.
Groovy CodeThe client sample illustrates the seamless usage of the IScriptExecutionCon-
text class in Groovy:
scriptTask("taskName", DV_APPLICATION){
code{ // The IScriptExecutionContext is automatically active here
// Call methods of the IScriptExecutionContext
def logger = scriptLogger
def temp = paths.tempFolder
// Use an automation API
workflow{
// Now the Workflow API is active
}
}
}
Listing 4.10: Access automation API in Groovy clients by the IScriptExecutionContext
© 2016, Vector Informatik GmbH
31 of
207
Chapter 4.AutomationInterface API ReferenceIn Groovy the IScriptExecutionContext is automatically activated inside of the code{}
block.
Java CodeFor java clients the method IScriptExecutionContext.getInstance(Class)
provides access to the API classes, which are seamlessly available for the groovy clients:
// Java code
// Passed from the script task:
IScriptExecutionContext scriptContext = ...;
// Retrieve automation API in Java
IWorkflowApi workflow = scriptContext.getInstance(IWorkflowApiEntryPoint.
class).getWorkflow();
IWorkflowContext workflowCtx = workflow.getWorkflow();
// In groovy code it would be:
workflow{
}
Listing 4.11: Access to automation API in Java clients by the IScriptExecutionContext
In Java code the context is always the first parameter passed to every task code (see IScript-
TaskCode).
4.4.1.1 Code Block ArgumentsThe code block can have arguments passed into the script task execution. The arguments passed
into the code{ } block are defined by the IScriptTaskType of the script task. See chapter
4.3
on page 27 for the list of arguments (including types) passed by each individual task type.
scriptTask("Task"){
code{ arg1, arg2, ... -> // arguments here defined by the IScriptTaskType
}
}
scriptTask("Task2"){
// Or you could specify the type of the arguments for code completion
code{ String arg1, List<Double> arg2 ->
}
}
Listing 4.12: Script task code block arguments
The arguments can also retrieved with IScriptExecutionContext.getScriptTaskArguments().
4.4.2 Task Execution SequenceThe figure
4.3 on the next page shows the overview sequence when a script task gets executed
by the user and the interaction with the IScriptExecutionContext. Note that the context
gets created each time the task is executed.
© 2016, Vector Informatik GmbH
32 of
207

Chapter 4.AutomationInterface API ReferenceFigure 4.3: Script Task Execution Sequence
4.4.3 Script Path API during ExecutionScript tasks could resolve relative and absolute file system paths with the IAutomationPath-
sApi.
As entry point call paths in a code{ } block (see IScriptExecutionContext.getPaths()).
There are multiple ways to resolve relative paths:
• by Script folder
• by Temp folder
• by SIP folder
• by Project folder
• by any parent folder
© 2016, Vector Informatik GmbH
33 of
207
Chapter 4.AutomationInterface API Reference4.4.3.1 Path Resolution by Parent FolderThe resolvePath(Path parent, Object path) method resolves a file path relative to supplied
parent folder.
This method converts the supplied path based on its type:
• A CharSequence, including String or GString. Interpreted relative to the parent direc-
tory. A string that starts with file: is treated as a file URL.
• A File: If the file is an absolute file, it is returned as is. Otherwise, the file’s path is
interpreted relative to the parent directory.
• A Path: If the path is an absolute path, it is returned as is. Otherwise, the path is
interpreted relative to the parent directory.
• A URI or URL: The URL’s path is interpreted as the file path. Currently, only file: URLs
are supported.
• A IHasURI: The returned URI is interpreted as defined above.
• A Closure: The closure’s return value is resolved recursively.
• A Callable: The callable’s return value is resolved recursively.
• A Supplier: The supplier’s return value is resolved recursively.
• A Provider: The provider’s return value is resolved recursively.
The return type is java.nio.file.Path.
scriptTask("TaskName"){
code{
// Method resolvePath(Path, Object) resolves a path relative to the supplied folder
Path parentFolder = Paths.get('.')
Path p = paths.resolvePath(parentFolder, "MyFile.txt")
/* The resolvePath(Path, Object) method will resolve
* relative and absolute paths to a java.nio.file.Path object.
*/
}
}
Listing 4.13: Resolves a path with the resolvePath() method
4.4.3.2 Path ResolutionThe resolvePath(Object) method resolves the Object to a file path. Relative paths are
preserved, so relative paths are not converted into absolute paths.
This method converts the supplied path same as the resolvePath(Path, Object) method.
The return type is java.nio.file.Path. See
4.4.3.1. But it does
NOT convert relative paths
into absolute.
© 2016, Vector Informatik GmbH
34 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
code{
// Method resolvePath() resolves a path and preserve relative paths
Path p = paths.resolvePath("MyFile.txt")
/* The resolvePath() method will resolve
* relative and absolute paths to a java.nio.file.Path object.
* Is also preserves relative paths.
*/
}
}
Listing 4.14: Resolves a path with the resolvePath() method
4.4.3.3 Script Folder Path ResolutionThe resolveScriptPath(Object) method resolves a file path relative to the script directory
of the executed IScript.
This method converts the supplied path same as the resolvePath(Path, Object) method.
The return type is java.nio.file.Path. See
4.4.3.1 on the previous page.scriptTask("TaskName"){
code{
// Method resolveScriptPath() resolves a path relative to the script folder
Path p = paths.resolveScriptPath("MyFile.txt")
/* The resolveScriptPath() method will resolve
* relative and absolute paths to a java.nio.file.Path object.
*/
}
}
Listing 4.15: Resolves a path with the resolveScriptPath() method
4.4.3.4 Project Folder Path ResolutionThe resolveProjectPath(Object) method resolves a file path relative to the project directory
(see getDpaProjectFolder()) of the current active project.
This method converts the supplied path same as the resolvePath(Path, Object) method.
The return type is java.nio.file.Path. See
4.4.3.1 on the preceding page.There must be an active project to use this method. See chapter
4.5.2 on page 49 for details
about active projects.
© 2016, Vector Informatik GmbH
35 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
code{
// Method resolveProjectPath() resolves a path relative active project folder
Path p = paths.resolveProjectPath("MyFile.txt")
/* The resolveProjectPath() method will resolve
* relative and absolute paths to a java.nio.file.Path object.
*/
}
}
Listing 4.16: Resolves a path with the resolveProjectPath() method
4.4.3.5 SIP Folder Path ResolutionThe resolveSipPath(Object) method resolves a file path relative to the SIP directory (see
getSipRootFolder()).
This method converts the supplied path same as the resolvePath(Path, Object) method.
The return type is java.nio.file.Path. See
4.4.3.1 on page 34.scriptTask("TaskName"){
code{
// Method resolveSipPath() resolves a path relative SIP folder
Path p = paths.resolveSipPath("MyFile.txt")
/* The resolveSipPath() method will resolve
* relative and absolute paths to a java.nio.file.Path object.
*/
}
}
Listing 4.17: Resolves a path with the resolveSipPath() method
4.4.3.6 Temp Folder Path ResolutionThe resolveTempPath(Object) method resolves a file path relative to the script temp di-
rectory of the executed IScript. A new temporary folder is created for each IScriptTask
execution.
This method converts the supplied path same as the resolvePath(Path, Object) method.
The return type is java.nio.file.Path. See
4.4.3.1 on page 34.scriptTask("TaskName"){
code{
// Method resolveTempPath() resolves a path relative to the temp folder
Path p = paths.resolveTempPath("MyFile.txt")
/* The resolveTempPath() method will resolve
* relative and absolute paths to a java.nio.file.Path object.
*/
}
}
Listing 4.18: Resolves a path with the resolveTempPath() method
© 2016, Vector Informatik GmbH
36 of
207
Chapter 4.AutomationInterface API Reference4.4.3.7 Other Project and Application PathsThe IAutomationPathsApi will also resolve any other Vector provided path variable like $(Ecuc-
File). The call would be paths.ecucFile, add the variable to resolve as a Groovy prop-
erty.
Short list of available variables (not complete, please see DaVinci Configurator help for more
details):
• EcucFile
• OutputFolder
• SystemFolder
• AutosarFolder
• more ...
scriptTask("TaskName", DV_PROJECT){
code{
// The property OutputFolder is the folder of the generated artifacts
Path folder = paths.outputFolder
}
}
Listing 4.19: Get the project output folder path
scriptTask("TaskName"){
code{
// The property sipRootFolder is the folder of the used SIP
Path folder = paths.sipRootFolder
}
}
Listing 4.20: Get the SIP folder path
4.4.4 Script logging APIThe script task execution (IScriptExecutionContext) provides a script logger to log events
during an execution. The method getScriptLogger() returns the logger. The logger can be
used to log:
• Errors
• Warnings
• Debug messages
• More...
You shall
always prefer the usage of the
logger before using the println() of stdout or
stderr.
In any code block without direct access to the script API, you can write the following code to
access the logger: ScriptApi.scriptLogger
© 2016, Vector Informatik GmbH
37 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
code{
// Use the scriptLogger to log messages
scriptLogger.info "My script is running"
scriptLogger.warn "My Warning"
scriptLogger.error "My Error"
scriptLogger.debug "My debug message"
scriptLogger.trace "My trace message"
// Also log an Exception as second argument
scriptLogger.error("My Error",
new RuntimeException("MyException"))
}
}
Listing 4.21: Usage of the script logger
The ILogger also provides a formatting syntax for the format String. The syntax is {IndexNum-
ber} and the index of arguments after the format String.
It is also possible to use the Groovy GString syntax for formatting.
scriptTask("TaskName"){
code{ argument ->
// Use the format methods to insert data
scriptLogger.infoFormat("My script {0} with:{1}", scriptTask, argument)
}
}
Listing 4.22: Usage of the script logger with message formatting
scriptTask("TaskName"){
code{ argument ->
// Use the Groovy GString syntax to insert data
scriptLogger.info "My script $scriptTask with: $argument"
}
}
Listing 4.23: Usage of the script logger with Groovy GString message formatting
4.4.5 User Interactions and InputsThe UserInteraction and UserInput API provides methods to directly communicate with the
user, via MessageBoxes or Input dialogs.
You should use the API only if you want do communicate directly with the user, because some
API calls may block and wait for user interaction. So you should not use the API for batch
jobs.
4.4.5.1 UserInteractionThe UserInteraction API provides methods to display messages to the user directly. In UI
mode the DaVinci Configurator will prompt a message box an will block until the user has
acknowledged the message. In console (non UI) mode, the message is logged to the console in
a user logger.
© 2016, Vector Informatik GmbH
38 of
207
Chapter 4.AutomationInterface API ReferenceThe user logger will display error, warnings and infos by default. The logger name will not be
displayed.
The user interaction is good to display information where the user has to respond to immediately.
Please use the feature sparingly, because users do not like to acknowledge multiple messages for
a single script task execution.
The code block userInteractions{} provides the API inside of the block. The following
methods can be used:
• errorToUser()
• warnToUser()
• infoToUser()
• messageToUser(ELogLevel, Object)
The severity (error, warning, info) will change the display (icons, text) of the message box. No
other semantic is applied by the severity.
scriptTask("TaskName", DV_APPLICATION){
code{
userInteractions{
warnToUser("Warning displayed to the user as message box")
}
// You could also write
userInteractions.errorToUser("Error message for the user")
}
}
Listing 4.24: UserInteraction from a script
© 2016, Vector Informatik GmbH
39 of
207

Chapter 4.AutomationInterface API Reference4.4.6 Script Error Handling4.4.6.1 Script ExceptionsAll exceptions thrown by any script task execution are sub types of ScriptingException.
Figure 4.4: ScriptingException and sub types
4.4.6.2 Script Task Abortion by ExceptionThe script task can throw an ScriptClientExecutionException to abort the execution of an
IScriptTask, and display a meaningful message to the user.
scriptTask("TaskName"){
code{
// Stop the execution and display a message to the user
throw new ScriptClientExecutionException("Message to the User")
}
}
Listing 4.25: Stop script task execution by throwing an ScriptClientExecutionException
Exception with Console Return CodeAn ScriptClientExecutionException with an return
code of type Integer will also abort the execution of the IScriptTask.
© 2016, Vector Informatik GmbH
40 of
207
Chapter 4.AutomationInterface API ReferenceBut it
also changes the return code of the console application, if the IScriptTask was executed
in the console application. This could be used when the console application of the DaVinci
Configurator is called for other scripts or batch files.
scriptTask("TaskName"){
code{
// The return code will be returned by the DvCmd.exe process
def returnCode = 50
throw new ScriptClientExecutionException(returnCode, "Message to the User")
}
}
Listing 4.26: Changing
the
return
code
of
the
console
application
by
throwing
an
ScriptClientExecutionException
Reserved Return CodesThe returns codes 0-20 are reversed for internal use of the DaVinci
Configurator, and are not allowed to be used by a client script. Also negative returns codes are
not permitted.
4.4.6.3 Unhandled Exceptions from TasksWhen a script task execution throws any type of Exception (more precise Throwable) the
script task is marked as failed and the Exception is reported to the user.
© 2016, Vector Informatik GmbH
41 of
207
Chapter 4.AutomationInterface API Reference4.4.7 User defined Classes and MethodsYou can define your own methods and classes in a script file. The methods a called like any
other method.
scriptTask("Task"){
code{
userMethod()
}
}
def userMethod(){
return "UserString"
}
Listing 4.27: Using your own defined method
Classes can be used like any other class. It is also possible to define multiple classes in the
script file.
scriptTask("Task"){
code{
new UserClass().userMethod()
}
}
class UserClass{
def userMethod(){
return "ReturnValue"
}
}
Listing 4.28: Using your own defined class
You can also create classes in different files, but then you have to write imports in your script
like in normal Groovy or Java code.
The script should be structured as any other development project, so if the script file gets too
big, please refactor the parts into multiple classes and so on.
daVinci BlockThe classes and methods must be outside of the daVinci{ } block.
import static com.vector.cfg.automation.api.ScriptApi.*
daVinci{
scriptTask("Task"){
code{}
}
}
def userMethod(){}
class UserClass{}
Listing 4.29: Using your own defined method with a daVinci block
Code CompletionNote that the code completion for the Automation API will not work auto-
matically in own defined classes and methods. You have to open for example a scriptCode{}
© 2016, Vector Informatik GmbH
42 of
207
Chapter 4.AutomationInterface API Referenceblock. The chapter
4.4.8 describes how to use the Automation API for your own defined classes
and methods.
4.4.8 Usage of Automation API in own defined Classes and MethodsIn your own methods and classes the automation API is not automatically available differently
as inside of the script task code{} block. But it is often the case, that methods need access to
the automation API.
The class
ScriptApi provides static methods as entry points into the automation API.
The static methods either return the API objects, or you could pass a Closure, which will
activate the API inside of the Closure.
4.4.8.1 Access the Automation API like the Script code{} BlockThe ScriptApi.scriptCode(Closure) method provides access to all automation APIs the
same way as inside of the normal script code{} block.
This is useful, when you want to call script code API inside of your own methods and classes.
def yourMethod(){
// Needs access to an automation API
ScriptApi.scriptCode{
// API is now available
workflow.update()
}
}
Listing 4.30: ScriptApi.scriptCode{} usage in own method
The ScriptApi.scriptCode() method can be used to call API in Java style.
def yourMethod(){
// Needs access to an automation API
ScriptApi.scriptCode().workflow.update()
}
Listing 4.31: ScriptApi.scriptCode() usage in own method
Java note: The ScriptApi.scriptCode() returns the IScriptExecutionContext.
4.4.8.2 Access the Project API of the current active ProjectThe ScriptApi.activeProject() method provides access to the project automation API of
the currently active project. This is useful, when you want to call project API inside of your
own methods and classes.
© 2016, Vector Informatik GmbH
43 of
207
Chapter 4.AutomationInterface API Referencedef yourMethod(){
// Needs access to an automation API
ScriptApi.activeProject{
// Project API is now available
transaction{
// Now model modifications are allowed
}
}
}
Listing 4.32: ScriptApi.activeProject{} usage in own method
The ScriptApi.activeProject() method returns the current active IProject.
def yourMethod(){
// Needs access to an automation API
IProject theActiveProject = ScriptApi.activeProject()
}
Listing 4.33: ScriptApi.activeProject() usage in own method
4.4.9 User defined Script Task Arguments in CommandlineA script task can create IScriptTaskUserDefinedArgument, which can be set by the user
(e.g. from the commandline) to pass user defined arguments to the script task execution. An
argument can be optional or required. The arguments are type safe and checked before the task
is executed.
Possible valueTypes are:
• String
• Boolean
• Void: For parameter where only the existence is relevant.
• File: The existence of the file is checked. To reference non existing paths use String
instead.
• Path: Same as File
• Integer
• Long
• Double
The help text is automatically expanded with the help for user defined script task argu-
ments.
© 2016, Vector Informatik GmbH
44 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
/** newUserDefinedArgument(String argName, Class<T> valueType, String help)
*/
def countArg = newUserDefinedArgument("count", Integer,
"The amount of elements to create")
def nameArg = newUserDefinedArgument("name", String,
"The element name to create")
code{
int count = countArg.value
String name = nameArg.value
scriptLogger.info "The arguments --name and --count were $name, $count"
}
}
Listing 4.34: Define and use script task user defined arguments from commandline
scriptTask("TaskName"){
/** newUserDefinedArgument(String argName, Class<T> valueType, String help)
*/
def procArg = newUserDefinedArgument("p", Void,
"Enables the processing")
code{
if(procArg.hasValue){
scriptLogger.info "The argument -p was defined"
}
}
}
Listing 4.35: Script task UserDefined argument with no value
scriptTask("TaskName"){
/** newUserDefinedArgument(String argName, Class<T> valueType,
* T defaultValue, String help)
*/
def procArg = newUserDefinedArgument("p", Double, 25.0,
"Help text ...")
code{
double value = procArg.value
scriptLogger.info "The argument -p was $value"
}
}
Listing 4.36: Script task UserDefined argument with default value
© 2016, Vector Informatik GmbH
45 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
/** newUserDefinedArgument(String argName, Class<T> valueType, String help)
*/
def multiArg = newUserDefinedArgument("multiArg", String, "Help text ...")
/** The client calls the task with arguments:
* --multiArg "ArgOne" --multiArg "ArgTwo"
*/
code{
List<String> values = multiArg.values // Call values instead of value
scriptLogger.info "The argument --multiArg had values: $values"
}
}
Listing 4.37: Script task UserDefined argument with multiple values
4.4.9.1 Call Script Task with Task ArgumentsThe commandline option taskArgs is used to specify the arguments passed to a script task to
execute:
--taskArgs <TASK_ARGS>
Passes arguments to the specified script tasks.
The arguments have the following syntax:
Syntax: --taskArgs "<TaskName>" "<Arguments to Task>"
E.g. --taskArgs "MyTask" "-s --projectCfg MyFile.cfg"
If only one task is executed, the "<TaskName>" can be omitted.
For multiple task arguments the following syntax apply:
Syntax: --taskArgs "<TaskName>" "<Arguments to Task>"
"<TaskName2>" "<Arguments to Task2>"
E.g. --taskArgs "MyTask" "-s --projectCfg MyFile.cfg"
"Task2" "-d --saveTo saveFile.txt"
Note: The newlines in the listing are only for visualization.
If the task name is not unique, your can specify the full qualified name with script name
--taskArgs "MyScript:MyTask" "-s --projectCfg MyFile.cfg"
Arguments with spaces inside the script task argument could be quoted with ""
--taskArgs "MyScript:MyTask" "-s --projectCfg \"Path to File\MyFile.cfg\" -d"
The task help of a task will print the possible arguments of a script task.
--scriptTaskHelp taskName
© 2016, Vector Informatik GmbH
46 of
207
Chapter 4.AutomationInterface API Reference4.4.10 Stateful Script TasksScript tasks normally have no state or cached data, but it can be useful to cache data during
an execution, or over multiple task executions. The IScriptExecutionContext provides two
methods to save and restore data for that purpose:
• getExecutionData() - caches data during one task execution
• getSessionData() - caches data over multiple task executions
Execution DataCaches data during a single script task execution, which allows to save cal-
culated values or services needed in multiple parts of the task, without recalculating or creating
it. Note: When the task is executed again the executionData will be empty.
scriptTask("TaskName"){
code{
// Cache a value for the execution
executionData.myCacheValue = 500
def val = executionData.myCacheValue // Retrieve the value anywhere
scriptLogger.info "The cached value is $val"
// Or access it from any place with ScriptApi.scriptCode like:
def sameValue = ScriptApi.scriptCode.executionData.myCacheValue
}
}
Listing 4.38: executionData - Cache and retrieve data during one script task execution
Session DataCaches data over multiple task executions, which allows to implement a stateful
task, by saving and retrieving any data calculated by the task itself.
Caution: The data is saved globally so the usage of the sessionData can lead to memory
leaks or OutOfMemoryErrors. You have to take care not to store too much memory in the
sessionData.
The DaVinci Configurator will also free the sessionData, when the system run low on free
memory. So you have to deal with the fact, that the sessionData was freed, when the script
task getting executed again. But the data is not deallocated during a running execution.
scriptTask("TaskName"){
// Setup - set the value the first time, this is only executed once (during initialization)
sessionData.myExecutionCount = 1
code{
// Retrieve the value
def executionCount = sessionData.myExecutionCount
scriptLogger.info "The task was executed $executionCount times"
// Update the value
sessionData.myExecutionCount = executionCount + 1
}
}
Listing 4.39: sessionData - Cache and retrieve data over multiple script task executions
© 2016, Vector Informatik GmbH
47 of
207
Chapter 4.AutomationInterface API ReferenceAPI usageBoth methods executionData and sessionData return the same API of type
IScriptTaskUserData.
The IScriptTaskUserData provides methods to retrieve and store properties by a key (like a
Map). The retrieval and store methods are Object based, so any Object can be a key. The
exception are Class instances (like String.class, which required that the value is an instance
of the Class).
On retrieval if a property does not exist an UnknownPropertyException is thrown. Properties
can be set multiple times and will override the old value. The keys of the properties used to
retrieve and store data are compared with Object.equals(Object) for equality.
The listing below describes the usage of the API:
scriptTask("TaskName"){
code{
def val
// The sessionData and executionData have the same API
// You have multiple ways to set a value
executionData.myCacheId = "VALUE"
executionData.set("myCacheId", "VALUE")
executionData["myCacheId"] = "VALUE"
// Or with classes for a service locator pattern
executionData.set(Integer.
class, 50) // Possible for any Class
executionData[Integer] = 50
// There are the same ways to retrieve the values
val = executionData.myCacheId
val = executionData.get("myCacheId")
val = executionData["myCacheId"]
// Or with classes for a service locator pattern
val = executionData.get(Integer.
class)
val = executionData[Integer]
// You can also ask if the property exists
boolean exists = executionData.has("myCacheId")
}
}
Listing 4.40: sessionData and executionData syntax samples
© 2016, Vector Informatik GmbH
48 of
207
Chapter 4.AutomationInterface API Reference4.5 Project HandlingProject handling comprises creating new projects, opening existing projects or accessing the
currently active project.
IProjectHandlingApi provides methods to access to the active project, for creating new
projects and for opening existing projects.
getProjects() allows accessing the IProjectHandlingApi like a property.
scriptTask('taskName') {
code {
// IProjectHandlingApi is available as "projects" property
def projectHandlingApi = projects
}
}
Listing 4.41: Accessing IProjectHandlingApi as a property
projects(Closure) allows accessing the IProjectHandlingApi in a scope-like way.
scriptTask('taskName') {
code {
projects {
// IProjectHandlingApi is available inside this Closure
}
}
}
Listing 4.42: Accessing IProjectHandlingApi in a scope-like way
4.5.1 ProjectsProjects in the AutomationInterface are represented by IProject instances. These instances
can be created by:
• Creating a new project
• Loading an existing project
You can only access IProject instances by using a Closure block at IProjectHandlingApi or
IProjectRef class. This shall prevent memory leaks, by not closing open projects.
4.5.2 Accessing the active ProjectThe IProjectHandlingApi provides access to the active project. The active project is either
(in descending order):
• The last IProject instance activated with a Closure block
– Stack-based - so multiple opened projects are possible and the last (inner) Closure
block is used.
• The passed project to a project task
• Or the loaded project in the current DaVinci Configurator in an application task
© 2016, Vector Informatik GmbH
49 of
207

Chapter 4.AutomationInterface API ReferenceThe figure
4.5 describes the behavior to search for the active project of a script task.
Figure 4.5: Search for active project in getActiveProject()
It is possible that there is no active project, e.g. no project was loaded.
You can switch the active project, by calling the with(Closure) method on an IProject
instance.
// Retrieve theProject from other API like load a project
IProject theProject = ...;
theProject.with {
// Now theProject is the new active project inside of this closure
}
Listing 4.43: Switch the active project
To access the active project you can use the activeProject(Closure) and getActivePro-
ject() methods.
© 2016, Vector Informatik GmbH
50 of
207
Chapter 4.AutomationInterface API ReferencescriptTask('taskName') {
code {
if (projects.projectActive) {
// active IProject is available as "activeProject" property
scriptLogger.info "Active project: ${projects.activeProject.projectName}"
projects.activeProject {
// active IProject is available inside this Closure
scriptLogger.info "Active project: ${projectName}"
}
}
else {
scriptLogger.info 'No project active'
}
}
}
Listing 4.44: Accessing the active IProject
isProjectActive() returns true if and only if there is an active IProject. If isProjectAc-
tive() returns true it is safe to call getActiveProject().
getActiveProject() allows accessing the active IProject like a property.
activeProject(Closure) allows accessing the active IProject in a scope-like way. This will
enable the project specific API inside of the Closure.
4.5.3 Creating a new ProjectThe method createProject(Closure) creates a new project as specified by the given Closure.
Inside the closure the ICreateProjectApi is available.
The new project is not opened and usable until IProjectRef.openProject(Closure) is called
on the returned IProjectRef.
scriptTask('taskName', DV_APPLICATION) {
code {
def newProject = projects.createProject {
projectName 'NewProject'
projectFolder paths.resolveTempPath('projectFolder')
}
scriptLogger.info("Project created and saved to: $newProject")
// Now open the project
newProject.openProject{
// Inside here the project can be used
}
}
}
Listing 4.45: Creating a new project (mandatory parameters only)
The next is a more sophisticated example of creating a project with multiple settings:
© 2016, Vector Informatik GmbH
51 of
207
Chapter 4.AutomationInterface API ReferencescriptTask('taskName', DV_APPLICATION) {
code {
def newProject = projects.createProject {
projectName 'NewProject'
projectFolder paths.resolveTempPath('projectFolder')
general {
author 'projectAuthor'
version '0.9'
}
postBuild {
loadable
trueselectable
true}
folders.ecucFileStructure = ONE_FILE_PER_MODULE
folders.moduleFilesFolder = 'Appl/GenData'
folders.templatesFolder = 'Appl/Source'
target.vVIRTUALtargetSupport =
falsedaVinciDeveloper.createDaVinciDeveloperWorkspace =
false}
}
}
Listing 4.46: Creating a new project (with some optional parameters)
The ICreateProjectApi contains the methods to parameterize the creation of a new project.
4.5.3.1 Mandatory SettingsProject NameSpecify the name newly created project with setProjectName(String). The
name given here is postfixed with ".dpa" for the new project’s .dpa file.
The following constraints apply:
• Constraints.IS_VALID_PROJECT_NAME
4.12.1 on page 144Project FolderSpecify the folder in which to create the new project in with setProject-
Folder(Object). The value given here is converted to Path using the converter ScriptCon-
verters.TO_SCRIPT_PATH
4.12.2 on page 145.The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 1454.5.3.2 General SettingsUse getGeneral() or general(Closure) to specify the new project’s general settings. The
provided settings are defined in ICreateProjectGeneralApi.
© 2016, Vector Informatik GmbH
52 of
207
Chapter 4.AutomationInterface API ReferenceAuthorThe author for the new project can be specified with setAuthor(String). This is an
optional parameter defaulting to the name of the currently logged in user if the parameter is
not provided explicitly.
The following constraints apply:
• Constraints.IS_NON_EMPTY_STRING
4.12.1 on page 144VersionThe version for the new project can be specified with setVersion(Object). This
is an optional parameter defaulting to "1.0" if the parameter is not provided explicitly. The
value given here is converted to IVersion using ScriptConverters.TO_VERSION
4.12.2 on
page 145.The following constraints apply:
• Constraints.IS_NOT_NULL
4.12.1 on page 144DescriptionThe description for the new project can be specified with setDescription(String).
This is an optional parameter defaulting to "" if the parameter is not provided explicitly.
The following constraints apply:
• Constraints.IS_NOT_NULL
4.12.1 on page 144Start Menu EntriessetCreateStartMenuEntries(boolean) defines whether or not to create
start menu entries for the new project. This is an optional parameter defaulting to false if the
parameter is not provided explicitly.
4.5.3.3 Target SettingsUse getTarget() or target(Closure) to specify the new project’s target settings for compiler,
derivatives and pin layouts.
ICreateProjectTargetApi contains the API to specify the new project’s target settings.
Available DerivativesgetAvailableDerivatives() returns all possible input values for set-
Derivative(DerivativeInfo).
DerivativeSet the derivative for the new project with setDerivative(DerivativeInfo).
This is an optional parameter defaulting to the first element in the collection returned by
getAvailableDerivatives() (or null if the collection is empty). The value given here must
be one of the values returned by getAvailableDerivatives().
Available CompilersgetAvailableCompilers() returns all possible input values for set-
Compiler(ImplementationProperty). Note: the available compilers depend on the currently
configured derivative. This method will return the empty collection if no derivative has been
configured at the time it is called.
© 2016, Vector Informatik GmbH
53 of
207
Chapter 4.AutomationInterface API ReferenceCompilerSet the compiler for the new project with setCompiler(ImplementationProperty).
This is an optional parameter defaulting to the first element in the collection returned by
getAvailableCompilers() (or null if the collection is empty). The value given here must be
one of the values returned by getAvailableCompilers().
Available Pin LayoutsgetAvailablePinLayouts() returns all possible input values for set-
PinLayout(ImplementationProperty). Note: the available pin layouts depend on the cur-
rently configured derivative. This method will return the empty collection if no derivative has
been configured at the time it is called.
Pin LayoutSet the pin layout of the selected derivative for the new project with setPinLay-
out(ImplementationProperty). This is an optional parameter defaulting to the first element
in the collection returned by getAvailablePinLayouts() (or null if the collection is empty).
The value given here must be one of the values returned by getAvailablePinLayouts().
vVIRTUALtarget SupportsetvVIRTUALtargetSupport(boolean) specifies whether or not
to support the vVIRTUALTarget for the new project. This is an optional parameter defaulting
to false if the parameter is not provided explicitly.
The following constraints apply:
• vVIRTUALtarget support may not be available depending on the purchased license
4.5.3.4 Post Build SettingsUse getPostBuild() or postBuild(Closure) to specify the new project’s post build settings
for Post-build selectable and or loadable projects.
ICreateProjectPostBuildApi contains the API to specify the new project’s post build set-
tings.
Post-build Loadable SupportsetLoadable(boolean) sets whether or not to support Post-
build loadable for the new project. This is an optional parameter defaulting to false if the
parameter is not provided explicitly.
Post-Build Selectable SupportsetSelectable(boolean) sets whether or not to support
Post-build selectable for the new project. This is an optional parameter defaulting to false if
the parameter is not provided explicitly.
4.5.3.5 Folders SettingsUse getFolders() or folders(Closure) to specify the new project’s folders settings.
ICreateProjectFolderApi contains the methods to specify the new project’s folders set-
tings.
© 2016, Vector Informatik GmbH
54 of
207
Chapter 4.AutomationInterface API ReferenceModule Files FolderSet the module files folder for the new project with setModuleFiles-
Folder(Object). This is an optional parameter defaulting to ".\Appl\GenData" if the param-
eter is not provided explicitly. The value given here is converted to Path using ScriptCon-
verters.TO_PATH
4.12.2 on page 145. Normally a relative path (to be interpreted relative to
the project folder) should be given here.
The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145Templates FolderSet the templates folder for the new project with setTemplatesFolder(Object).
This is an optional parameter defaulting to ".\Appl\Source" if the parameter is not provided
explicitly.
The value given here is converted to Path using ScriptConverters.TO_PATH
4.12.2 on page 145.
Normally a relative path (to be interpreted relative to the project folder) should be given
here.
The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145Service Components FolderSet the service component files folder for the new project with
setServiceComponentFilesFolder(Object).
This is an optional parameter defaulting to
".\Config\ServiceComponents" if the parameter is not provided explicitly.
The value given here is converted to Path using ScriptConverters.TO_PATH
4.12.2 on page 145.
Normally a relative path (to be interpreted relative to the project folder) should be given
here.
The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145Application Components FolderSet the application component files folder for the new project
with setApplicationComponentFilesFolder(Object). This is an optional parameter default-
ing to ".\Config\ApplicationComponents" if the parameter is not provided explicitly.
The value given here is converted to Path using ScriptConverters.TO_PATH
4.12.2 on page 145.
Normally a relative path (to be interpreted relative to the project folder) should be given
here.
The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145Log Files FolderSet the log files folder for the new project with setLogFilesFolder(Object).
This is an optional parameter defaulting to ".\Config\Log" if the parameter is not provided
explicitly.
The value given here is converted to Path using ScriptConverters.TO_PATH
4.12.2 on page 145.
Normally a relative path (to be interpreted relative to the project folder) should be given
here.
The following constraints apply:
© 2016, Vector Informatik GmbH
55 of
207
Chapter 4.AutomationInterface API Reference• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145Measurement And Calibration Files FolderSet the measurement and calibration files folder
for the new project with setMeasurementAndCalibrationFilesFolder(Object). This is an
optional parameter defaulting to ".\Config\McData" if the parameter is not provided explic-
itly.
The folder object passed to the method is converted to Path using ScriptConverters.TO_PATH
4.12.2
on page 145. Normally a relative path (to be interpreted relative to the project folder) should
be given here.
The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145AUTOSAR Files FolderSet the AUTOSAR files folder for the new project with setAu-
tosarFilesFolder(Object). This is an optional parameter defaulting to ".\Config\AUTOSAR"
if the parameter is not provided explicitly.
The value given here is converted to Path using ScriptConverters.TO_PATH
4.12.2 on page 145.
Normally a relative path (to be interpreted relative to the project folder) should be given
here.
The following constraints apply:
• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145ECUC File StructureThe literals of EEcucFileStructure define the alternative ECUC file
structures supported by the new project. The following alternatives are supported:
SINGLE_FILE results in a single ECUC file containing all module configurations.
ONE_FILE_PER_MODULE results in a separate ECUC file for each module configuration all located
in a common folder.
ONE_FILE_IN_SEPARATE_FOLDER_PER_MODULE results in a separate ECUC file for each module
configuration each located in its separate folder.
Set the ECUC file structure to use for the new project with the method setEcucFileStruc-
ture(EEcucFileStructure). This is an optional parameter defaulting to EEcucFileStruc-
ture.SINGLE_FILE if the parameter is not provided explicitly.
4.5.3.6 DaVinci Developer SettingsUse getDaVinciDeveloper() to specify the new project’s DaVinci Developer settings.
ICreateProjectDaVinciDeveloperApi contians the methods for specifying the new project’s
DaVinci Developer settings.
Create DEV WorkspacesetCreateDaVinciDeveloperWorkspace(boolean) specifies whether
or not to create a DaVinci Developer workspace for the new project. This is an optional pa-
rameter defaulting to true if and only if a compatible DaVinci Developer installation can be
detected and the parameter is not provided explicitly.
© 2016, Vector Informatik GmbH
56 of
207
Chapter 4.AutomationInterface API ReferenceDEV ExecutableSet the DaVinci Developer executable for the new project with setDaVin-
ciDeveloperExecutable(Object). This is an optional parameter defaulting to the location of
a compatible DaVinci Developer installation (if there is any) if the parameter is not provided
explicitly.
The value given here is converted to Path using ScriptConverters.TO_SCRIPT_PATH
4.12.2 on
page 145.The following constraints apply:
• Constraints.IS_COMPATIBLE_DA_VINCI_DEV_EXECUTABLE
4.12.1 on page 145DEV WorkspaceSet the DaVinci Developer workspace for the new project with setDaVin-
ciDeveloperWorkspace(Object). This is an optional parameter defaulting to
".\Config\Developer\<ProjectName>.dcf" if the parameter is not provided explicitly.
The value given here is converted to Path using ScriptConverters.TO_PATH
4.12.2 on page 145.
Normally a relative path (to be interpreted relative to the project folder) should be given
here.
The following constraints apply:
• Constraints.IS_DCF_FILE
4.12.1 on page 145• Constraints.IS_CREATABLE_FOLDER
4.12.1 on page 145 (applies to the parent Path of
the given Path to the DaVinci Developer executable)
Import Mode PresetsetUseImportModePreset(boolean) specifies whether or not to use the
import mode preset for the new project. This is an optional parameter defaulting to true if
the parameter is not provided explicitly.
Object LockingsetLockCreatedObjects(boolean) specifies whether or not to lock created
objects for the new project. This is an optional parameter defaulting to true if the parameter
is not provided explicitly.
Selective ImportThe literals of ESelectiveImport define the alternative modes for the se-
lective import into the DaVinci Developer workspace during project updates. The following
alternatives are supported:
ALL results in selective import for all elements.
COMMUNICATION_ONLY results in selective import for communication elements only.
Set the selective import mode for the new project with setSelectiveImport(ESelectiveImport).
This is an optional parameter defaulting to ESelectiveImport.ALL if the parameter is not pro-
vided explicitly.
4.5.4 Opening an existing ProjectYou can open an existing DaVinci Configurator Dpa project with the automation interface.
The method openProject(Object, Closure) opens the project at the given .dpa file location,
delegates the given code to the opened IProject.
© 2016, Vector Informatik GmbH
57 of
207
Chapter 4.AutomationInterface API ReferenceThe project is automatically closed after leaving the Closure code of the openProject(Object,
Closure) method.
The Object given as .dpa file is converted to Path using ScriptConverters.TO_SCRIPT_PATH
4.12.2
on page 145scriptTask('taskName', DV_APPLICATION) {
code {
// replace getDpaFileToLoad() with the path to the .dpa file to be loaded
projects.openProject(getDpaFileToLoad()) {
// the opened IProject is available inside this Closure
scriptLogger.info 'Project loaded and ready'
}
}
}
Listing 4.47: Opening a project from .dpa file
4.5.4.1 Parameterized Project LoadYou can also configure how a Dpa project is loaded, e.g. by disabling the generators.
The method parameterizeProjectLoad(Closure) returns a handle on the project specified by
the given Closure. Using the IOpenDpaProjectApi, the Closure may further customize the
project’s opening procedure.
The project is not opened until openProject() is called on the returned IProjectRef.
scriptTask('taskName', DV_APPLICATION) {
code {
def project = projects.parameterizeProjectLoad {
// replace getDpaFileToLoad() with the path to the .dpa file to be loaded
dpaFile getDpaFileToLoad()
// prevent activation of generators and validation
loadGenerators
falseenableValidation
false}
project.openProject {
// the opened IProject is available inside this Closure
scriptLogger.info 'Project loaded and ready'
}
}
}
Listing 4.48: Parameterizing the project open procedure
IOpenProjectApi contains the methods for parameterizing the process of opening a project.
DPA FileThe method setDpaFile(Object) sets the .dpa file of the project to be opened.
The value given here is converted to Path using ScriptConverters.TO_SCRIPT_PATH
4.12.2 on
page 145.GeneratorsUsing setLoadGenerators(boolean) specifies whether or not to activate gener-
ators (including their validations) for the opened project.
© 2016, Vector Informatik GmbH
58 of
207
Chapter 4.AutomationInterface API ReferenceValidationsetEnableValidation(boolean) specifies whether or not to activate validation
for the opened project.
4.5.4.2 Open Project DetailsIProjectRef is a handle on a project not yet loaded but ready to be opened. This could be
used to open the project.
IProjectRef instances can be obtained from form the following methods:
• IProjectHandlingApi.createProject(Closure)
4.5.3 on page 51• IProjectHandlingApi.parameterizeProjectLoad(Closure)
4.5.4 on the previous pageThe IProject is not really opened until IProjectRef.openProject(Closure) is called. Here,
the project is opened and the given Closure is executed on the opened project. When IPro-
jectRef.openProject(Closure) returns the project has already been closed.
4.5.5 Saving a ProjectIProject.saveProject() saves the current state including all model changes of the project to
disc.
scriptTask('taskName', DV_APPLICATION) {
code {
// replace getDpaFileToLoad() with the path to the .dpa file to be loaded
def project = projects.openProject(getDpaFileToLoad()) {
// modify the opened project
transaction {
operations.activateModuleConfiguration(sipDefRef.EcuC)
}
// save the modified project
saveProject()
}
}
}
Listing 4.49: Opening, modifying and saving a project
© 2016, Vector Informatik GmbH
59 of
207
Chapter 4.AutomationInterface API Reference4.5.6 Opening AUTOSAR Files as ProjectSometimes it could be helpful to load AUTOSAR arxml files instead of a full-fledged DaVinci
Configurator project.
For example to modify the content of a file for test cases with the
AutomationInterface, instead of using an XML editor.
You could load multiple arxml files into a temporary project, which allowed to read and write
the loaded file content with the normal model APIs.
The following elements are loaded by default, without specifying the AUTOSAR files:
• ModuleDefinitions from the SIP: To allow the usage of the BswmdModel
• AUTOSAR standard definition: Refinement resolution of definitions
Caution: Some APIs and services may not be available for this type of project, like:
• Update workflow: You can’t update a non existing project
• Validation: The validation is disabled by default
• Generation: The generators are not loaded by default
The method parameterizeArxmlFileLoad(Closure) allows to load multiple arxml files into a
temporary project. The given Closure is used to customize the project’s opening procedure by
the IOpenArxmlFilesProjectApi.
The arxml file project is not opened until openProject() is called on the returned IProjec-
tRef.
scriptTask('taskName', DV_APPLICATION) {
code {
def project = projects.parameterizeArxmlFileLoad {
// Add here your arxml files to load
arxmlFiles(arxmlFilesToLoad)
rawAutosarDataMode =
true}
project.openProject {
scriptLogger.info 'Project loaded and ready'
}
}
}
Listing 4.50: Opening Arxml files as project
Arxml FilesAdd arxml files to load with the method arxmlFiles(Collection). Multiple
files and method calls are allowed. The given values are converted to Path instances using
ScriptConverters.TO_SCRIPT_PATH
4.12.2 on page 145.Raw AUTOSAR Data Modethe method setRawAutosarDataMode(boolean) specifies whether
or not to use the raw ATUOSAR data model.
This will disable most of the provided services and APIs, like:
• Ecuc access
• BswmdModel support
• Generation
© 2016, Vector Informatik GmbH
60 of
207
Chapter 4.AutomationInterface API Reference• Validation
• Worflow
• Domain API
• ChangeInspector
• and more
Currently only this mode is supported! You have to set rawAutosarDataMode = true.
© 2016, Vector Informatik GmbH
61 of
207
Chapter 4.AutomationInterface API Reference4.6 Model4.6.1 IntroductionThe model API provides means to retrieve AUTOSAR model content and to modify AUTOSAR
data. This comprises Ecuc data (module configurations and their content) and System Descrip-
tion data.
In this chapter you’ll first find a brief introduction into the model handling. Here you also find
some simple cut-and-paste examples which allow starting easily with low effort. Subsequent
sections describe more and more details which you can read if required.
Chapter
5 on page 152 may additionally be useful to understand detailed concepts and as a
reference to handle special use cases.
4.6.2 Getting StartedThe model API basically provides two different approaches:
• The
MDF model is the low level AUTOSAR model. It stores all data read from AU-
TOSAR XML files. Its structure is base on the AUTOSAR MetaModel. In
5.1 on page 152
you find detailed information about this model.
• The
BswmdModel is a model which wraps the MDF model to provide convenient and
type-safe access to the Ecuc data. It contains, definition based classes for module con-
figurations, containers, parameters and references. The class CanGeneral for example
as type-safe implementation in contrast to the generic AUTOSAR class MIContainer in
MDF.
It is strongly recommended to use the BswmdModel model to deal with Ecuc data
because it simplifies scripting a lot.
4.6.2.1 Read the ActiveEcucThis section provides some typical examples as a brief introduction for reading the Ecuc by
means of the BswmdModel. See chapter
4.6.3.2 on page 70 for more details.
The following example specifies no types for the local variables. It therefore requires no import
statements. A drawback on the other hand is that the type is only known at runtime and you
have no type support in the IDE:
© 2016, Vector Informatik GmbH
62 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName"){
code {
// Gets the module DefRef searching all definitions of this SIP
def moduleDefRef = sipDefRef.EcuC
// Creates all BswmdModel instances with this definition. A List<EcuC> in this case.
def ecucModules = bswmdModel(moduleDefRef)
// Gets the EcucGeneral container of the first found module instance
def ecuc = ecucModules.single
def ecucGeneral = ecuc.ecucGeneral
// Gets an (enum) parameter of this container
def cpuType = ecucGeneral.CPUType
}
}
Listing 4.51: Read with BswmdModel objects starting with a module DefRef (no type
declaration)
In contrast to the listing above the next one implements the same behavior but specifies all
types:
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.CPUType
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.ECPUType
scriptTask("TaskName"){
code {
// Gets the ecuc module configuration
EcuC ecuc = bswmdModel(EcuC.DefRef).single
// Gets the EcucGeneral container
EcucGeneral ecucGeneral = ecuc.ecucGeneral
// Gets an enum parameter of this container
CPUType cpuType = ecucGeneral.CPUType
if (cpuType.value == ECPUType.CPU32Bit) {
"Do something ..."
}
}
}
Listing 4.52: Read with BswmdModel objects starting with a module DefRef (strong typing)
© 2016, Vector Informatik GmbH
63 of
207
Chapter 4.AutomationInterface API ReferenceThe bswmdModel() API takes an optional closure argument which is being called for each
created BswmdModel object. This object is used as parameter of the closure:
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.ECPUType
scriptTask("TaskName"){
code {
// Executes the closure with all instances of this definition
bswmdModel(EcuC.DefRef) {
// The related BswmdModel instance is parameter of this closure
ecuc ->
if (ecuc.ecucGeneral.CPUType.value == ECPUType.CPU32Bit) {
"Do something ..."
}
}
}
}
Listing 4.53: Read with BswmdModel objects with closure argument
Additionally to the DefRef, an already available MDF model object can be specified to create
the related BswmdModel object for it:
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.ECPUType
scriptTask("TaskName"){
code {
// Gets the MDF model instance of the Ecuc General container
def container = mdfModel(EcucGeneral.DefRef).single
// Executes the closure with this MDF object instance
bswmdModel(container, EcucGeneral.DefRef) {
// The related BswmdModel instance is parameter of this closure
ecucGeneral ->
if (ecucGeneral.CPUType.value == ECPUType.CPU32Bit) {
"Do something ..."
}
}
}
}
Listing 4.54: Read with BswmdModel object for an MDF model object
© 2016, Vector Informatik GmbH
64 of
207
Chapter 4.AutomationInterface API Reference4.6.2.2 Write the ActiveEcucThis section provides some typical examples as a brief introduction for writing the Ecuc by
means of the BswmdModel. See chapter
4.6.3.3 on page 71 for more details.
For the most cases the entry point for writing the ActiveEcuc is a (existing) module configuration
object which can be retrieved with the bswmdModel() API. Because the model is in read-only
state by default, every call to an API which creates or deletes elements has to be executed in
a transaction() block.
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcuC ecuc = bswmdModel(EcuC.DefRef).single
//Gets the EcucGeneral container or create one if it is missing
EcucGeneral ecucGeneral = ecuc.ecucGeneralOrCreate
// Gets an boolean parameter of this container or create one if it is missing
def ecuCSafeBswChecks = ecucGeneral.ecuCSafeBswChecksOrCreate
// Sets the parameter value to true
ecuCSafeBswChecks.value =
true}}}
Listing 4.55: Write with BswmdModel required/optional objects
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecuchardware.ecuccoredefinition.
EcucCoreDefinition
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcuC ecuc = bswmdModel(EcuC.DefRef).single
//Gets the EcucCoreDefinition list (creates ecucHardware if it is missing)
def ecucCoreDefinitions = ecuc.ecucHardwareOrCreate.ecucCoreDefinition
//Adds two EcucCores
EcucCoreDefinition core0 = ecucCoreDefinitions.createAndAdd("EcucCore0")
EcucCoreDefinition core1 = ecucCoreDefinitions.createAndAdd("EcucCore1")
if(ecucCoreDefinitions.exists("EcucCore0")) {
//Sets EcucCoreId to 0
ecucCoreDefinitions.byName("EcucCore0").ecucCoreId.setValue(0);
}
//Creates a new EcucCore by method 'byNameOrCreate'
EcucCoreDefinition core2 = ecucCoreDefinitions.byNameOrCreate("EcucCore2");
}}}
Listing 4.56: Write with BswmdModel multiple objects
© 2016, Vector Informatik GmbH
65 of
207
Chapter 4.AutomationInterface API Reference// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcuC ecuc = bswmdModel(EcuC.DefRef).single
//Duplicates container 'EcucGeneral' and all its children
EcucGeneral ecucGeneral_Dup = ecuc.ecucGeneral.duplicate()
}
}
}
Listing 4.57: Write with BswmdModel - Duplicate a container
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcucGeneral ecucGeneral = bswmdModel(EcucGeneral.DefRef).single
//Deletes 'ecucGeneral' from model
ecucGeneral.moRemove()
//Checks if the container 'ecucGeneral' was removed from repository
if(ecucGeneral.moIsRemoved()) {
"Do something ..."
}
}
}
}
Listing 4.58: Write with BswmdModel - Delete elements
© 2016, Vector Informatik GmbH
66 of
207
Chapter 4.AutomationInterface API Reference4.6.2.3 Read the SystemDescriptionThis section contains only one example for reading the SystemDescription by means of the MDF
model. See chapter
4.6.4.1 on page 74 for more details.
// Required imports
import com.vector.cfg.model.mdf.ar4x.swcomponenttemplate.datatype.dataprototypes.*
import com.vector.cfg.model.mdf.ar4x.commonstructure.datadefproperties.*
scriptTask("mdfModel", DV_PROJECT){
code {
// Create a type-safe AUTOSAR path
def asrPath =
AsrPath.create("/PortInterfaces/PiSignal_Dummy/DeSignal_Dummy",
MIVariableDataPrototype)
// Enter the MDF model tree starting at the object with this path
mdfModel(asrPath) { MIVariableDataPrototype prototype ->
// Traverse down to the swDataDefProps
prototype.swDataDefProps { MISwDataDefProps swDataDefPropsParam ->
// swDataDefPropsVariant is a List<MISwDataDefPropsConditional>
// Execute the following for ALL elements of this List
swDataDefPropsParam.swDataDefPropsVariant {
MISwDataDefPropsConditional swDataDefPropsCondParam ->
// Resolve the dataConstr reference (type MIDataConstr)
def target = swDataDefPropsCondParam.dataConstr.refTarget
// Get the swCalibrationAccess enum value
def access = swDataDefPropsCondParam.swCalibrationAccess
assert access == MISwCalibrationAccessEnum.NOT_ACCESSIBLE
}
}
}
}
}
Listing 4.59: Read system description starting with an AUTOSAR path in closure
The same sample as above, but in property access style instead of closures:
// Create a type-safe AUTOSAR path
def asrPath =
AsrPath.create("/PortInterfaces/PiSignal_Dummy/DeSignal_Dummy", MIVariableDataPrototype)
def prototype = mdfModel(asrPath)
def swDataDefPropsParam = prototype.swDataDefProps
// Execute the following for ALL swDataDefPropsVariant
swDataDefPropsParam.swDataDefPropsVariant.each{ swDataDefPropsCondParam ->
// Resolve the dataConstr reference (type MIDataConstr)
def target = swDataDefPropsCondParam.dataConstr.refTarget
// Get the swCalibrationAccess enum value
def access = swDataDefPropsCondParam.swCalibrationAccess
assert access == MISwCalibrationAccessEnum.NOT_ACCESSIBLE
}
Listing 4.60: Read system description starting with an AUTOSAR path in property style
© 2016, Vector Informatik GmbH
67 of
207
Chapter 4.AutomationInterface API Reference4.6.2.4 Write the SystemDescriptionWriting the system description looks quite similar to the reading, but you have to use methods
like (see chapter
4.6.4.2 on page 76 for more details):
• get<Element>OrCreate() or <element>OrCreate
• createAndAdd()
• byNameOrCreate()
You have to open a transaction before you can modify the MDF model, see chapter
4.6.6 on
page 88 for details.
The following samples show the different types of write API:
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) { dataPrototype ->
dataPrototype.category = "NewCategory"
}
}
Listing 4.61: Changing a simple property of an MIVariableDataPrototype
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
int count = 0
assert adminData ==
nulladminDataOrCreate {
count++
}
assert count == 1
assert adminData !=
null}
}
Listing 4.62: Creating non-existing member by navigating into its content with OrCreate()
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
assert adminData.sdg.empty
adminData {
sdg.createAndAdd(MISdg) {
gid = "NewGidValue"
}
}
assert adminData.sdg.first.gid == "NewGidValue"
}
}
Listing 4.63: Creating new members of child lists with createAndAdd() by type
© 2016, Vector Informatik GmbH
68 of
207
Chapter 4.AutomationInterface API Referencetransaction{
// The path points to an MISenderReceiverInterface
mdfModel(asrPath) { sendRecIf ->
def dataList = sendRecIf.dataElement
def dataElement = dataList.byNameOrCreate("MyDataElement")
dataElement.name = "NewName"
def dataElement2 = dataList.byNameOrCreate("NewName")
assert dataElement == dataElement2
}
}
Listing 4.64: Updating existing members of child lists with byNameOrCreate() by type
© 2016, Vector Informatik GmbH
69 of
207
Chapter 4.AutomationInterface API Reference4.6.3 BswmdModel in AutomationInterfaceThe AutomationInterface contains a generated BswmdModel.
The BswmdModel provides
classes for all Ecuc elements of the AUTOSAR model (ModuleConfigurations, Containers, Pa-
rameter, References). The BswmdModel is automatically generated from the SIP of the DaVinci
Configurator.
You should use the BswmdModel whenever possible to access Ecuc elements of the AUTOSAR
model. For accessing the Ecuc elements with the BswmdModel, see chapter
4.6.3.2.For a detailed description of the BswmdModel, see chapter
5.3.1 on page 166.4.6.3.1 BswmdModel Package and Class NamesThe generated model is contained in the Java package com.vector.cfg.automation.model.ecuc.
Every Module has its own sub packages with the name:
• com.vector.cfg.automation.model.ecuc.<AUTOSAR-PKG>.<SHORTNAME>
– e.g. com.vector.cfg.automation.model.ecuc.microsar.dio
– e.g. com.vector.cfg.automation.model.ecuc.autosar.ecucdefs.can
The packages then contain the class of the element like Dio for the module. The full path would
be com.vector.cfg.automation.model.ecuc.microsar.dio.Dio.
For the container DioGeneral it would be:
• com.vector.cfg.automation.model.ecuc.microsar.dio.diogeneral.DioGeneral
To use the BswmdModel in script files, you have to write an import, when accessing the
class:
//The required BswmdModel import of the class Dio
import com.vector.cfg.automation.model.ecuc.microsar.dio.Dio
scriptTask("TaskName"){
code{
Dio.DefRef //Usage of the class Dio
}
}
Listing 4.65: BswmdModel usage with import
4.6.3.2 Reading with BswmdModelThe bswmdModel() methods provide entry points to start navigation through the ActiveEcuc.
Client code can use the Closure overloads to navigate into the content of the found bswmd ob-
jects. Inside the called closure the related bswmd object is available as closure parameter.
The following types of entry points are provided here:
• bswmdModel(WrappedTypedDefRef) searches all objects with the specified definition and
returns the BswmdModel instances
• bswmdModel(MIHasDefinition, WrappedTypedDefRef) returns the BswmdModel instance
for the provided MDF model instance.
© 2016, Vector Informatik GmbH
70 of
207
Chapter 4.AutomationInterface API ReferenceWhen a closure is being used, the object found by bswmdModel() is provided as parameter when
the closure is called.
The bswmdModel() method itself returns the found objects too. Retrieving the objects member
and children (Container, Parameter) as properties or methods are then possible directly using
the returned object.
Example:
code {
// Gets the ecuc module configuration
EcuC ecuc = bswmdModel(EcuC.DefRef).single
}
Listing 4.66: Read with BswmdModel the EcuC module configuration
For more usage samples please see chapter
4.6.2.1 on page 62.4.6.3.3 Writing with BswmdModelAs well as for reading with BswmdModel the entry points for writing with BswmdModel are also
the bswmdModel() methods. There has to be at least one existing element in the ActiveEcuc
from which the navigation can be started. For the most cases the entry point for writing the
ActiveEcuc is the module configuration.
Example:
code {
transaction {
// Gets the ecuc module configuration
EcuC ecuc = bswmdModel(EcuC.DefRef).single
//Gets the EcucGeneral container or create one if it is missing
EcucGeneral ecucGeneral = ecuc.ecucGeneralOrCreate
}
}
Listing 4.67: Write with BswmdModel the EcucGeneral container
For more usage samples please see chapter
4.6.2.2 on page 65.NOTE: The model is in read-only state by default, so no objects could be created. For this reason
all calls to an API which creates or deletes elements has to be executed within a transaction()
block.
See
5.3.1.9 on page 174 for more details to the BswmdModel write API.
4.6.3.4 Sip DefRefsThe sipDefRef API provides access to retrieve generated DefRef instances from the SIP without
knowing the correct Java/Groovy imports. This is mainly useful in script files, where no IDE
helps with the imports.
If you are using an Automation Script Project you can ignore this API and use the
DefRefs provided by the generated classes, which is superior to this API, because they are
typesafe and compile time checked. See
4.6.3.5 on the next page for details.
© 2016, Vector Informatik GmbH
71 of
207
Chapter 4.AutomationInterface API ReferenceThe listing show the usage of the sipDefRef API with short names and definition paths.
code{
def theDefRef
// You can call sipDefRef.<ShortName>
theDefRef = sipDefRef.EcucGeneral
theDefRef = sipDefRef.Dio
theDefRef = sipDefRef.DioPort
// Or you can use the [] notation
theDefRef = sipDefRef["Dio"]
theDefRef = sipDefRef["DioChannelGroup"]
// If the DefRef is not unique you have to specify the full definition
theDefRef = sipDefRef["/MICROSAR/EcuC/EcucGeneral"]
theDefRef = sipDefRef["/MICROSAR/Dio"]
theDefRef = sipDefRef["/MICROSAR/Dio/DioConfig/DioPort"]
}
Listing 4.68: Usage of the sipDefRef API to retrieve DefRefs in script files
4.6.3.5 BswmdModel DefRefsThe generated BswmdModel classes contain DefRef instances for each definition element (Mod-
ules, Containers, Parameters). You should always prefer this API over the Sip DefRefs, because
this is type safe and checked during compile time.
You can use the DefRefs by calling <ModelClassName>.DefRef. The literal DefRef is a static
constant in the generated classes.
For simple parameters like Strings, Integer there is no generated class, so you have to call the
method on its parent container like <ParentContainerClass>.<ParameterShortName>DefRef.
There exist generated classes for Parameters of type Enumeration and References to Container
and therefore you have both ways to access the DefRef:
• <ModelClassName>.DefRef or
• <ParentContainerClass>.<ParameterShortName>DefRef
To use the DefRefs of the classes you have to add imports in script files, see chapter
4.6.3.1 on
page 70 for required import names.
© 2016, Vector Informatik GmbH
72 of
207
Chapter 4.AutomationInterface API Reference// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.CPUType
scriptTask("TaskName"){
code {
def theDefRef
//DefRef from EcucGeneral container
theDefRef = EcucGeneral.DefRef
//DefRef from generated parameter
theDefRef = CPUType.DefRef
//Or the same
theDefRef = EcucGeneral.CPUTypeDefRef
//DefRef from simple parameter
theDefRef = EcucGeneral.AtomicBitAccessInBitfieldDefRef
theDefRef = EcucGeneral.DummyFunctionDefRef
}
}
Listing 4.69: Usage of generated DefRefs form the bswmd model
4.6.3.6 Switching from Domain Models to BswmdModelYou can switch from domain models to the BswmdModel, if the domain model is backed by Ac-
tiveEcuC elements. Please read the documentation of the different domain models, for whether
this is possible for a certain domain model.
To switch from a domain model to the BswmdModel, you can call one of the methods for IHas-
ModelObjects like, bswmdModel(IHasModelObject, WrappedTypedDefRef). But you need a
DefRef to get the type safe BswmdModel object. The domain model documents, which DefRef
must be used for the certain domain model object.
// Domain model object of the communication domain
ICanController canDomainModel = ...
def canControllerBswmd = canDomainModel.bswmdModel(CanController.DefRef)
// Or use a closure
canDomainModel.bswmdModel(CanController.DefRef){ canControllerBswmd ->
//Use the bswmd object
}
Listing 4.70: Switch from a domain model object to the corresponding BswmdModel object
4.6.4 MDF Model in AutomationInterfaceAccess to the MDF model is required in all areas which are not covered by the BswmdModel.
This is the SystemDescription (non-Ecuc data) and details of the Ecuc model which are not
covered by the BswmdModel.
The MDF model implements the raw AUTOSAR data model and is based on the AUTOSAR
meta-model. For details about the MDF model, see chapter
5.1 on page 152.© 2016, Vector Informatik GmbH
73 of
207
Chapter 4.AutomationInterface API ReferenceFor more details concerning the methods mentioned in this chapter, you should also read the
JavaDoc sections in the described interfaces and classes.
4.6.4.1 Reading the MDF ModelThe mdfModel() methods provide entry points to start navigation through the MDF model.
Client code can use the Closure overloads to navigate into the content of the found MDF
objects. Inside the called closure the related MDF object is available as closure parameter.
The following types of entry points are provided here:
• mdfModel(TypedAsrPath) searches an object with the specified AUTOSAR path
• mdfModel(TypedDefRef) searches all objects with the specified definition
• mdfModel(Class) searches all objects with the specified model type (meta class)
When a closure is being used, the object found by mdfModel() is provided as parameter when
this closure is called:
code {
// Create a type-safe AUTOSAR path for a MIVariableDataPrototype
def asrPath =
AsrPath.create("/PortInterfaces/PiSignal_Dummy/DeSignal_Dummy", MIVariableDataPrototype)
// Use the Java-Style syntax
def dataDefPropsMdf = mdfModel(asrPath).swDataDefProps
// Or use the Closure syntax to navigate
// Enter the MDF model tree starting at the object with this path
mdfModel(asrPath) {
// Parameter type is MIVariableDataPrototype:
dataPrototype ->
// Traverse down to the swDataDefProps
dataPrototype.swDataDefProps {MISwDataDefProps props
println "Do something ..."
}
}
}
Listing 4.71: Navigate into an MDF object starting with an AUTOSAR path
The mdfModel() method itself returns the found object too. Retrieving the objects member
(as property) is then possible directly using the returned object.
An alternative is using a closure to navigate into the MDF object and access its member
there:
© 2016, Vector Informatik GmbH
74 of
207
Chapter 4.AutomationInterface API Reference// Get an MDF object and get its members directly
def obj = mdfModel(asrPath) // Type MIVariableDataPrototype
def props = obj.swDataDefProps // Type MISwDataDefProps
// Get an MDF object and get its members using a closure
def props2
def obj2 = mdfModel(asrPath) {
props2 = swDataDefProps
}
// The results are the same
assert obj == obj2
assert props == props2
Listing 4.72: Find an MDF object and retrieve some content data
Closures can be nested to navigate deeply into the MDF model tree:
mdfModel(asrPath) {
int count = 0
swDataDefProps {
// swDataDefPropsVariant is a List<MISwDataDefPropsConditional>
// Execute the following for ALL elements of this List
List v = swDataDefPropsVariant {
println "Do something ..."
count++
}
}
assert count >= 1
}
Listing 4.73: Navigating deeply into an MDF object with nested closures
When a member doesn’t exist during navigation into a deep MDF model tree, the specified
closure is not called:
mdfModel(asrPath) {
int count = 0
assert adminData ==
nulladminData {
count++
}
assert count == 0
}
Listing 4.74: Ignoring non-existing member closures
Retrieving a Child by Shortname or DefinitionThere are multiple ways to retrieve children
from an MDF model object, by the shortname or by its definition. The shortname can be used
at the object with childByName() or at the child list with byName().
childByNameThe childByName(MIARObject, String, Closure) method calls the passed
Closure, if the requrest child exists. And returns the child MIReferrable below the specified
object which has this relative AUTOSAR path (not starting with ’/’).
© 2016, Vector Informatik GmbH
75 of
207
Chapter 4.AutomationInterface API ReferenceMIContainer canGeneral = ...
canGeneral.childByName("CanMainFunctionRWPeriods"){ child->
//Do something
}
Listing 4.75: Get a MIReferrable child object by name
Lists containing Referrables• The method byName(String) retrieves the child with the shortname, or null, if no child
exists with this shortname.
• The method byName(String, Closure) retrieves the child with the shortname, or null,
if no child exists with this shortname. Then the closure is executed with the child as
closure parameter, if the child is not null. The child is finally returned.
• The method byName(Class, String) retrieves the child with the shortname and type,
or null, if no child exists with this shortname.
• The method byName(Class, String, Closure) retrieves the child with the shortname
and type, or null, if no child exists with this shortname. Then the closure is executed
with the child as closure parameter, if the child is not null. The child is finally returned.
• The method getAt(String) all members with this relative AUTOSAR path. Groovy
also allows to write list["ShortnameToSearchFor"].
// The asrPath points to an MISenderReceiverInterface
def prototype = mdfModel(asrPath)
// byName() with shortname
def data1 = prototype.dataElement.byName("DeSignal_Dummy")
assert data1.name == "DeSignal_Dummy"
// byName() with type and shortname
def data2 = prototype.dataElement.byName(MIVariableDataPrototype, "DeSignal2")
// getAt() with shortname
def data3 = prototype.dataElement["DeSignal3"]
Listing 4.76: Retrieve child from list with byName()
Lists containing Parameters and Containers• The method getAt(TypedDefRef) returns all children with the passed definition. Groovy
also allows to write list[DefRef].
4.6.4.2 Writing the MDF ModelWriting to the MDF model can be done with the same mdfModel(AsrPath) API, but you have
to call specific methods to modify the model objects. The methods are devided in the following
use cases:
• Change a simple property like Strings
• Change or create a single child relateion (0:1)
• Create a new child for a child list (0:*)
© 2016, Vector Informatik GmbH
76 of
207
Chapter 4.AutomationInterface API Reference• Update an existing child from a child list (0:*)
You have to open a transaction before you can modify the MDF model, see chapter
4.6.6 on
page 88 for details about transactions.
4.6.4.3 Simple Property ChangesThe properties of MDF model object simply be changed by with the setter method of the model
object. Simple setter exist for example for the types:
• String
• Enums
• Integer
• Double
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) { dataPrototype ->
dataPrototype.category = "NewCategory"
}
}
Listing 4.77: Changing a simple property of an MIVariableDataPrototype
4.6.4.4 Creating single Child Members (0:1)For single child members (0:1), the automation API provides and additional method for the
getter get<Element>OrCreate() for convenient child object creation. The methods will create
the element, instead of returning null.
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
int count = 0
assert adminData ==
nulladminDataOrCreate {
count++
}
assert count == 1
assert adminData !=
null}
}
Listing 4.78: Creating non-existing member by navigating into its content with OrCreate()
If the compile time child type is not instatiatable, you have to provide the concrete type by
get<Element>OrCreate(Class childType).
© 2016, Vector Informatik GmbH
77 of
207
Chapter 4.AutomationInterface API Referencetransaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
introductionOrCreate(MIBlockLevelContent) { docuBlock ->
assert docuBlock
instanceof MIBlockLevelContent
}
}
}
Listing 4.79: Creating child member by navigating into its content with OrCreate() with type
4.6.4.5 Creating and adding Child List Members (0:*)For child list members, the automation API provides many createAndAdd() methods for con-
venient child object creation. These method will always create the element, regardless if the
same element (e.g. same ShortName) already exists.
If you want to update element see the chapter
4.6.4.6 on page 80.transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
assert adminData.sdg.empty
adminData {
sdg.createAndAdd(MISdg) {
gid = "NewGidValue"
}
}
assert adminData.sdg.first.gid == "NewGidValue"
}
}
Listing 4.80: Creating new members of child lists with createAndAdd() by type
These methods are available — but be aware that not all of these methods are available for all
child lists. Adding parameters, for example, is only permitted in the parameter child list of an
MIContainer instance.
All Lists:• The method createAndAdd() creates a new MDF object of the lists content type and
appends it to this list. If the type is not instantiatable the method will thrown a Mod-
elException. The new object is finally returned.
• The method createAndAdd(Closure) creates a new MDF object of the lists content type
and appends it to this list. If the type is not instantiatable the method will thrown a
ModelException. Then the closure is executed with the new object as closure parameter.
The new object is finally returned.
• The method createAndAdd(Class) creates a new MDF object of the specified type and
appends it to this list. The new object is finally returned.
• The method createAndAdd(Class, Closure) creates a new MDF object of the specified
type and appends it to this list. Then the closure is executed with the new object as
closure parameter. The new object is finally returned.
© 2016, Vector Informatik GmbH
78 of
207
Chapter 4.AutomationInterface API Reference• The method createAndAdd(Class, Integer) creates a new MDF object of the specified
type and inserts it to this list at the specified index position. The new object is finally
returned.
• The method createAndAdd(Class, Integer, Closure) creates a new MDF object of
the specified type and inserts it to this list at the specified index position. Then the
closure is executed with the new object as closure parameter. The new object is finally
returned.
Lists containing Referrables• The method createAndAdd(String) creates a new child with the specified shortname
and appends it to this list. The new object is finally returned. The used type is the lists
content type. If the type is not instantiatable the method will thrown a ModelException.
• The method createAndAdd(String, Closure) creates a new MIReferrable with the
specified shortname and appends it to this list. Then the closure is executed with the new
object as closure parameter. The new object is finally returned. The used type is the lists
content type. If the type is not instantiatable the method will thrown a ModelException.
• The method createAndAdd(Class, String) creates a new MIReferrable with the spec-
ified type and shortname and appends it to this list. The new object is finally returned.
• The method createAndAdd(Class, String, Closure) creates a new MIReferrable with
the specified type and shortname and appends it to this list. Then the closure is executed
with the new object as closure parameter. The new object is finally returned.
• The method createAndAdd(Class, String, Integer) creates a new MIReferrable with
the specified type and shortname and inserts it to this list at the specified index position.
The new object is finally returned.
• The method createAndAdd(Class, String, Integer, Closure) creates a new MIRe-
ferrable with the specified type and shortname and inserts it to this list at the specified
index position. Then the closure is executed with the new object as closure parameter.
The new object is finally returned.
Lists containing Parameters and Containers• The method createAndAdd(TypedDefRef) creates a new Ecuc object (container or pa-
rameter) with the specified definition and appends it to this list. The new object is finally
returned.
• The method createAndAdd(TypedDefRef, Closure) creates a new Ecuc object (con-
tainer or parameter) with the specified definition and appends it to this list. Then the
closure is executed with the new object as closure parameter. The new object is finally
returned.
• The method createAndAdd(TypedDefRef, Integer) creates a new Ecuc object (con-
tainer or parameter) with the specified definition and inserts it to this list at the specified
index position. The new object is finally returned.
• The method createAndAdd(TypedDefRef, Integer, Closure) creates a new Ecuc ob-
ject (container or parameter) with the specified definition and inserts it to this list at
the specified index position. Then the closure is executed with the new object as closure
parameter. The new object is finally returned.
© 2016, Vector Informatik GmbH
79 of
207
Chapter 4.AutomationInterface API ReferenceLists containing Containers• The method createAndAdd(TypedDefRef, String) creates a new container with the
specified definition and shortname and appends it to this list.
The new container is
finally returned.
• The method createAndAdd(TypedDefRef, String, Closure) creates a new container
with the specified definition and shortname and appends it to this list. Then the closure
is executed with the new container as closure parameter. The new container is finally
returned.
• The method createAndAdd(TypedDefRef, String, Integer) creates a new container
with the specified definition and shortname and inserts it to this list at the specified index
position. The new container is finally returned.
• The method createAndAdd(TypedDefRef, String, Integer, Closure) creates a new
container with the specified definition and shortname and inserts it to this list at the
specified index position. Then the closure is executed with the new container as closure
parameter. The new container is finally returned.
4.6.4.6 Updating existing ElementsFor child list members, the automation API provides many byNameOrCreate() methods for
convenient child object update and creation on demand. These method will create the element
if id does not exists, or return the existing element.
transaction{
// The path points to an MISenderReceiverInterface
mdfModel(asrPath) { sendRecIf ->
def dataList = sendRecIf.dataElement
def dataElement = dataList.byNameOrCreate("MyDataElement")
dataElement.name = "NewName"
def dataElement2 = dataList.byNameOrCreate("NewName")
assert dataElement == dataElement2
}
}
Listing 4.81: Updating existing members of child lists with byNameOrCreate() by type
These methods are available — but be aware that not all of these methods are available for all
child lists. Updating container, for example, is only permitted in the parameter child list of an
MIContainer instance.
Lists containing Referrables• The method byNameOrCreate(String) retrieves the child with the passed shortname, or
creates the child, if it does not exist. The shortname is automatically set before returning
the new child.
• The method byNameOrCreate(TypedDefRef, String,Closure) retrieves the child with
the passed shortname, or creates the child, if it does not exist. The shortname is auto-
matically set before returning the new child. Then the closure is executed with the child
as closure parameter. The child is finally returned.
© 2016, Vector Informatik GmbH
80 of
207
Chapter 4.AutomationInterface API Reference• The method byNameOrCreate(Class, String) retrieves the child with the passed type
and shortname, or creates the child, if it does not exist. The shortname is automatically
set before returning the new child.
• The method byNameOrCreate(Class, String,Closure) retrieves the child with the passed
type and shortname, or creates the child, if it does not exist. The shortname is automat-
ically set before returning the new child. Then the closure is executed with the child as
closure parameter. The child is finally returned.
Lists containing Containers• The method byNameOrCreate(TypedDefRef, String) retrieves the child with the passed
definition and shortname, or creates the child, if it does not exist. The definition and
shortname are automatically set before returning the new child.
• The method byNameOrCreate(TypedDefRef, String, Closure) retrieves the child with
the passed definition and shortname, or creates the child, if it does not exist. The definition
and shortname are automatically set before returning the new child. Then the closure is
executed with the child as closure parameter. The child is finally returned.
4.6.4.7 Deleting Model ObjectsThe method moRemove(MIObject) deletes the specified object from the model. This method
must be called inside a transaction because it changes the model content.
Special case: If this method is being called on an active module configuration, it actually calls
IOperations.deactivateModuleConfiguration(MIModuleConfiguration) to deactivate the
module correctly.
// MIParameterValue param = ...
transaction {
assert !param.moIsRemoved()
param.moRemove()
assert param.moIsRemoved()
}
Listing 4.82: Delete a parameter instance
For details about model object deletion and access to deleted objects, read section
5.1.7.4 on
page 157 ff.
moIsRemovedThe getMoIsRemoved(MIObject) method returns true if the specified object
has been removed (deleted) from the MDF model.
MIObject obj = ...
if (!obj.moIsRemoved()) {
work with obj ...
}
Listing 4.83: Check is a model instance is deleted
© 2016, Vector Informatik GmbH
81 of
207
Chapter 4.AutomationInterface API Reference4.6.4.8 Duplicating Model ObjectsThe duplicate(MIObject) method copies (clones) a complete MDF model sub-tree and adds
it as child below the same parent.
• The source object must have a parent. The clone will be added to the same MDF feature
below the same parent then
• AUTOSAR UUIDs will not be cloned. The clone will contain new UUIDs to guarantee
unambiguousness
This method can clone any model sub-tree, also see IOperations.deepClone(MIObject, MIOb-
ject) for details.
Note: This operation must be executed inside of a transaction.
// MIContainer container = ...
transaction {
def newCont = container.duplicate()
// The duplicated container newCont
}
Listing 4.84: Duplicates a container under the same parent
4.6.4.9 Special properties and extensionsasrPathThe getAsrPath(MIReferrable) method returns the AUTOSAR path of the speci-
fied object.
MIContainer canGeneral = ...
AsrPath path = canGeneral.asrPath
Listing 4.85: Get the AsrPath of an MIReferrable instance
See chapter
5.4.1 on page 177 for more details about AsrPaths.
asrObjectLinkThe getAsrObjectLink(MIARObject) method returns the AsrObjectLink of
the specified object.
MIParameterValue param = ...
AsrObjectLink link = param.asrObjectLink
Listing 4.86: Get the AsrObjectLink of an AUTOSAR model instance
See chapter
5.4.2 on page 177 for more details about AsrObjectLinks.
defRefThe getDefRef() method returns the DefRef of the model object.
MIParameterValue param = ...
DefRef defRef = param.defRef
Listing 4.87: Get the DefRef of an Ecuc model instance
The MIParameterValue.setDefRef(DefRef) method sets the definition of this parameter to
the defRef.
© 2016, Vector Informatik GmbH
82 of
207
Chapter 4.AutomationInterface API ReferenceMIParameterValue param = ...
DefRef newDefinition = ...
param.defRef = newDefinition
Listing 4.88: Set the DefRef of an Ecuc model instance
If the specified DefRef has a wildcard, the parameter must have a parent to calculate the
absolute definition path - otherwise a ModelCeHasNoParentException will be thrown.
If is has no wildcard and no parent, the absolute definition path of the defRef will be used.
If the parameter has a parent or and parents definition does not match the defRefs parent
definition, this method fails with InconsistentParentDefinitionException.
The MIContainer.setDefRef(DefRef) method sets the definition of this container to the de-
fRef.
See chapter
5.4.3 on page 178 for more details about DefRefs.
ceStateThe CeState is an object which aggregates states of a related MDF object. Client
code can e.g. check with the CeState if an Ecuc object has a related pre-configuration value.
The getCeState(MIObject) method returns the CeState of the specified model object.
MIParameterValue param = ...
IParameterStatePublished state = param.ceState
Listing 4.89: Get the CeState of an Ecuc parameter instance
See chapter
5.4.4 on page 181 for more details about the CeState.
ceState - User-defined FlagThe method isUserDefined() returns true, if the ecuc config-
uration element like parameters is flagged as user-defined.
MIParameterValue param = ...
def flag = param.ceState.userDefined
Listing 4.90: Retrieve the user-defined flag of an Ecuc parameter in Groovy
The method setUserDefined(boolean) sets or removes the user-defined flag of a ecuc config-
uration element like parameters.
Note: This method must executed inside a transaction because it modifies the model state.
MIParameterValue param = ...
transaction {
param.ceState.userDefined =
true}
Listing 4.91: Set an Ecuc parameter instance to user defined
4.6.4.10 AUTOSAR Root ObjectThe getAUTOSAR() method returns the AUTOSAR root object (the root object of the MDF
model tree of AUTOSAR data).
© 2016, Vector Informatik GmbH
83 of
207
Chapter 4.AutomationInterface API ReferenceMIAUTOSAR root = AUTOSAR
Listing 4.92: Get the AUTOSAR root object
4.6.4.11 ActiveEcuCThe activeEcuc access methods provide access to the module configurations of the Ecuc model.
// Get the modules as Collection<MIModuleConfiguration>
Collection modules = activeEcuc.allModules
Listing 4.93: Get the active Ecuc and all module configurations
// Iterate over all module configurations
activeEcuc {
int count = 0
allModules.each { moduleCfg ->
count++
}
assert count > 1
}
Listing 4.94: Iterate over all module configurations
activeEcuc {
// Parameter type is IActiveEcuc
ecuc ->
def defRef = DefRef.create(EDefRefWildcard.AUTOSAR, "EcuC")
// Get the modules as Collection<MIModuleConfiguration>
Collection foundModules = ecuc.modules(defRef)
assert !foundModules.empty
}
Listing 4.95: Get module configurations by definition
4.6.4.12 DefRef based Access to Containers and ParametersThe Groovy automation interface for the MDF model provides some overloaded access methods
for
• MIModuleConfiguration.getSubContainer()
• MIContainer.getSubContainer()
• MIContainer.getParameter()
to offer convenient filtering access to the subContainer and parameter child lists.
© 2016, Vector Informatik GmbH
84 of
207
Chapter 4.AutomationInterface API ReferenceactiveEcuc {
// Parameter type is IActiveEcuc
ecuc ->
def module = ecuc.modules(EcuC.DefRef).first
// Get containers as List<MIContainer>
def containers = module.subContainer(EcucGeneral.DefRef)
// Get parameters as List<MIParameterValue>
def cpuType = containers.first.parameter(CPUType.DefRef)
assert cpuType.size() == 1
}
Listing 4.96: Get subContainers and parameters by definition
4.6.4.13 Ecuc Parameter and Reference Value AccessThe Groovy automation interface also provides special access methods for Ecuc parameter
values. These methods are implemented as extensions of the Ecuc parameter and value types
and can therefore be called directly at the parameter or reference instance.
Value Checks• hasValue(MIParameterValue)
returns true if the parameter (or reference) has a value.
• containsBoolean(MINumericalValue)
returns true if the parameter value contains a valid boolean with the same semantic as
IModelAccess.containsBoolean(MINumericalValue).
Call this method in advance
to guarantee that getAsBoolean(MINumericalValueVariationPoint) doesn’t lead to
errors.
• containsInteger(MINumericalValue)
returns true if the parameter value contains a valid integer with the same semantic as
IModelAccess.containsInteger(MINumericalValue).
Call this method in advance
to guarantee that getAsInteger(MINumericalValueVariationPoint) doesn’t lead to
errors.
• containsDouble(MINumericalValue)
returns true if the parameter value contains a valid double (AUTOSAR float) with the
same semantic as
IModelAccess.containsFloat(MINumericalValue).
Call this method in advance
to guarantee that getAsDouble(MINumericalValueVariationPoint) doesn’t lead to er-
rors.
© 2016, Vector Informatik GmbH
85 of
207
Chapter 4.AutomationInterface API Reference// MINumericalValue param = ...
if (!param.hasValue()) {
scriptLogger.warn "The parameter has no value!"
}
if (param.containsInteger()) {
int value = param.value.asInteger
}
Listing 4.97: Check parameter values
Parameters• getAsLong(MINumericalValueVariationPoint) returns the value as native long.
Throws NumberFormatException if the value string doesn’t represent an integer value.
Throws ArithmeticException if the value will not exactly fit in a long.
• getAsInteger(MINumericalValueVariationPoint) returns the value as native int.
Throws NumberFormatException if the value string doesn’t represent an integer value.
Throws ArithmeticException if the value will not exactly fit in an int.
• getAsBigInteger(MINumericalValueVariationPoint) returns the value as BigInte-
ger.
Throws NumberFormatException if the value string doesn’t represent an integer value.
• getAsDouble(MINumericalValueVariationPoint) returns the value as Double.
Throws NumberFormatException if the value string doesn’t represent a float value.
• getAsBigDecimal(MINumericalValueVariationPoint) returns the value as BigDeci-
mal.
Note: This method will possibly return MBigDecimal.POSITIVE_INFINITY, MBigDeci-
mal.NEGATIVE_INFINITY or MBigDecimal.NaN.
If it is necessary to do computations with these special numbers,
use getAsDouble(MINumericalValueVariationPoint) instead.
Throws NumberFormatException if the value string doesn’t represent a float value.
• getAsBoolean(MINumericalValueVariationPoint) returns the value as Boolean.
Throws NumberFormatException if the value string doesn’t represent a boolean value.
• asCustomEnum(MITextualValue, Class) returns the value of the enum parameter as a
custom enum literal. If the Class destClass implements the IModelEnum interface, the lit-
erals are mapped via these information form the IModelEnum interface. Read the JavaDoc
of IModelEnum for more details.
© 2016, Vector Informatik GmbH
86 of
207
Chapter 4.AutomationInterface API Reference// MINumericalValue param = ...
// MINumericalValueVariationPoint is the type of param.value
long longValue = param.value.asLong
assert longValue == 10
int intValue = param.value.asInteger
assert intValue == 10
BigInteger bigIntValue = param.value.asBigInteger
assert bigIntValue == BigInteger.valueOf(10)
Double doubleValue = param.value.asDouble
assert Math.abs(doubleValue-10.0) <= 0.0001
Listing 4.98: Get integer parameter value
References• getAsAsrPath(MIARRef) returns the reference value as AUTOSAR path.
• getAsAsrPath(MIReferenceValue) returns the reference parameters value as AUTOSAR
path.
• getRefTarget(MIReferenceValue) returns the reference parameters target object (the
object referenced by this parameter). It returns null if the target cannot be resolved or
the reference parameter doesn’t contain a value reference.
// MIReferenceValue refParam = ...
def asrPath1 = refParam.asAsrPath
def asrPath2 = refParam.value.asAsrPath
assert asrPath1 == asrPath2
String pathString = refParam.value.value
assert asrPath1.autosarPathString == pathString
def target1 = refParam.refTarget
def target2 = refParam.value.refTarget
assert target1 == target2
Listing 4.99: Get reference parameter value
4.6.5 SystemDescription AccessThe systemDescription API provides methods to retrieve system description data like the path
to the flat extract or the flat map instance.
It is grouped by the AUTOSAR version. So the getAutosar4() methods provides access to
AUTOSAR 4 model elements.
The getPaths() provides common paths to elements like:
• FlatMap path
• FlatExtract path
• FlatCompositionType path
© 2016, Vector Informatik GmbH
87 of
207
Chapter 4.AutomationInterface API ReferenceAsrPath flatExtractPath = systemDescription.paths.flatExtractPath
AsrPath flatMapPath = systemDescription.paths.flatMapPath
Listing 4.100: Get the FlatExtract and FlatMap paths by the SystemDescription API
systemDescription{
autosar4{
flatExtract.ifPresent{ theFlatExtract ->
// do something with the flatMap
}
}
}
// Or in property style
def theFlatExtractOpt = systemDescription.autosar4.flatExtract
if(theFlatExtractOpt){
def theFlatExtract = theFlatExtractOpt.get()
}
Listing 4.101: Get FlatExtract instance by the SystemDescription API
4.6.6 TransactionsModel changes must always be executed within a transaction. The automation API provides
some simple means to execute transactions.
For details about transactions read
5.1.7 on page 156.scriptTask("TaskName", DV_PROJECT){
code {
transaction{
// Your transaction code here
}
}
}
Listing 4.102: Execute a transaction
scriptTask("TaskName", DV_PROJECT){
code {
transaction("Transaction name") {
// The transactionName proptery is available inside a transaction
String name = transactionName
}
}
}
Listing 4.103: Execute a transaction with a name
The transaction name has no additional semantic. It is only be used for logging and to improve
error messages.
Nested TransactionsIf you open a transaction inside of a transaction the inner transaction is
ignored and it is as no transaction call was done. So be aware that nested transactions are no
real transaction, which leads to the fact the these nested transactions can not be undone.
© 2016, Vector Informatik GmbH
88 of
207
Chapter 4.AutomationInterface API ReferenceIf you want to know whether a transaction is already running, see the transactions API be-
low.
4.6.6.1 Transactions APIThe Transactions API with the keyword transactions provides access to running transactions
or the transaction history.
You can use method isTransactionRunning() to check if a transaction is currently running.
The method returns true, if a transaction is running in the current Thread.
scriptTask("TaskName", DV_PROJECT){
code {
// Switch to the transactions API
transactions{
//Check if a transaction is running
assert isTransactionRunning() ==
false// Open a transaction
transaction{
// Now a transaction is running
assert isTransactionRunning() ==
true}
}
// Or the short form
transactions.isTransactionRunning()
}
}
Listing 4.104: Check if a transaction is running
TransactionHistoryThe transaction history API provides some methods to handle transaction
undo and redo. This way, complex model changes can be reverted quite easily.
• The undo() method executes an undo of the last transaction. If the last transaction frame
cannot be undone or if the undo stack is empty this method returns without any changes.
• The undoAll() method executes undo until the transaction stack is empty or an undoable
transaction frame appears on the stack.
• The redo() method executes an redo of the last undone transaction. If the last undone
transaction frame cannot be redone or if the redo stack is empty this method returns
without any changes.
• The canUndo() method returns true if the undo stack is not empty and the next undo
frame can be undone. This method changes nothing but you can call it to find out if the
next undo() call would actually undo something.
• The canRedo() method returns true if the redo stack is not empty and the next redo
frame can be redone. This method changes nothing but you can call it to find out if the
next redo() call would actually redo something.
© 2016, Vector Informatik GmbH
89 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName", DV_PROJECT){
code {
transaction("TransactionName") {
// Your transaction code here
}
transactions{
assert transactionHistory.canUndo()
transactionHistory.undo()
assert !transactionHistory.canUndo()
}
}
}
Listing 4.105: Undo a transaction with the transactionHistory
scriptTask("TaskName", DV_PROJECT){
code {
transaction("TransactionName") {
// Your transaction code here
}
transactions{
transactionHistory.undo()
assert transactionHistory.canRedo()
transactionHistory.redo()
assert !transactionHistory.canRedo()
}
}
}
Listing 4.106: Redo a transaction with the transactionHistory
4.6.6.2 OperationsThe model operations implement convenient means to execute complex model changes like
AUTOSAR module activation or cloning complete model sub-trees.
• The method activateModuleConfiguration(DefRef) activates the specified module con-
figuration. This covers:
– Creation of the module including the reference in the ActiveEcuC (the ECUC-VALUE-
COLLECTION)
– Creation of mandatory containers and parameters (lower multiplicity > 0)
– Applying the recommended configuration
– Applying the pre-configuration values
• The method deactivateModuleConfiguration(MIModuleConfiguration) deletes the
specified module configuration from the model. In case of a split configuration, the re-
lated persistency location is being removed from the project settings. In XML file base
configurations, the related file is being deleted during the next project save if it doesn’t
contain configuration objects anymore.
© 2016, Vector Informatik GmbH
90 of
207
Chapter 4.AutomationInterface API ReferenceIf the module configuration is referenced from the active-ECUC this link is being removed
too.
• The method changeBswImplementation(MIModuleConfiguration, MIBswImplementa-
tion) changes the BSW-implementation of a module configuration including the definition
of all contained containers and parameters.
• The deepClone(MIObject, MIObject) operation copies (clones) a complete MDF model
sub-tree and adds it as child below the specified parent.
– The source object must have a parent. The clone will be added to the same MDF
feature below the destination parent then
– AUTOSAR UUIDs will not be cloned. The clone will contain new UUIDs to guar-
antee unambiguousness
• The method createModelObject(Class) creates a new element of the passed modelClass
(meta class). The modelObject must be added to the whole AUTOSAR model, before
finishing the transaction.
4.6.7 Post-build selectable VarianceThe variance access API is the entry point for convenient access to variant AUTOSAR model
content. It provides means to filter variant model content and access variant specific data.
For details about post-build selectable variance and model views read
5.2 on page 158.4.6.7.1 Investigate Project VarianceThe projects variance can be analyzed using the variance keyword. These methods can be
called then:
• The method hasPostBuildVariance() returns true if the active project contains post-
build variants.
• The method getInvariantValuesView() returns the invariant values view.
• The method getInvariantEcucDefView() returns the invariant Ecuc definition view.
• The method getCurrentlyActiveView() returns the currently active model view.
• The method getAllVariantViews() returns all available variant model views (one IPrede-
finedVariantView per predefined varient).
© 2016, Vector Informatik GmbH
91 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("TaskName", DV_PROJECT){
code{
def activeView1 = variance.currentlyActiveView
assert activeView1
instanceof IInvariantValuesView
// ... or with a closure
variance {
def activeView2 = currentlyActiveView
assert activeView1 == activeView2
assert activeView1 == invariantValuesView
// Get number of variants
int num = allVariantViews.size()
assert num == 4
}
}
}
Listing 4.107: The default view is the IInvariantValuesView
4.6.7.2 Variant Model ObjectsThe following model object extensions provide convenient means to investigate model object
variance in detail.
• The method activeWith(IModelView, Closure) executes code under visibility of the
specified model view.
• The method isModelInvariant(MIObject) returns true if the object and all its parents
has no variation point conditions. If this is true, this model object instance is visible in
all variant views.
• The method isValueInvariant(MIObject) returns true if the object has the same value
in all variants.
For details about invariant views see
5.2.1.4 on page 161.• The method isEcucDefInvariant(MIObject) returns true if the object is invariant ac-
cording to its EcuC definition.
See IInvariantEcucDefView for more details to the concept.
• The method isVisible(MIObject) returns true if the object is visible in the current
model view.
• The method isVisibleInModelView(MIObject, IModelView) returns true if the object
is visible in the specified model view.
• The method isNeverVisible(MIObject) returns true if the object is
invisible in all
variant views.
• The method getVisibleVariantViews(MIObject) returns all variant views the specified
object is visible in.
• The method getVisibleVariantViewsOrInvariant(MIObject) For semantic details see
IModelViewManager.getVisibleVariantViewsOrInvariant(MIObject).
• The method asViewedModelObject(MIObject) returns a new IViewedModelObject in-
stance using the currently active view.
© 2016, Vector Informatik GmbH
92 of
207
Chapter 4.AutomationInterface API Reference• The method getVariantSiblings(MIObject) returns MDF object instances representing
the same object but in all variants.
For details about the sibling semantic see
5.2.1.3 on page 160.• The method getVariantSiblingsWithoutMyself(MIObject) returns the same collection
as getVariantSiblings(MIObject) but without the specified object.
// IPredefinedVariantView viewDoorLeftFront = ...
// MIParameterValue variantParameter = ...
viewDoorLeftFront.activeWith {
assert variance.currentlyActiveView == viewDoorLeftFront
// The parameter instance is not visible in all variants ...
assert !variantParameter.isModelInvariant()
// ... but all variants have a sibling with the same value
assert variantParameter.isValueInvariant()
}
Listing 4.108: Execute code in a model view
© 2016, Vector Informatik GmbH
93 of
207
Chapter 4.AutomationInterface API Reference4.7 GenerationThe following chapter describes the module generation automation API.
The block
generation encapsulates all settings and commands which are related to this use
case.
The basic structure is the following:
generation{
settings{
// Settings like the selection of generators for execution can be done here
externalGenerationSteps{
// Settings related to externalGenerationSteps can be done here
}
}
// The execution of the generation or validation can be started here
}
Listing 4.109: Basic structure
4.7.1 SettingsThis class encapsulates all settings which belong to a generation process.
E.g.
• Select the generators to execute
• Select the target type
• Select the external generation steps
• If the module supports multiple module configurations, select the configurations which
shall be generated
The following chapters show samples for the standard use cases.
4.7.1.1 Default Project SettingsThe following snippet executes a validation with the default project settings.
scriptTask("validate_with_default_settings"){
code{
generation{
validate()
}
}
}
Listing 4.110: Validate with default project settings
To execute a generation with the standard project settings the following snippet can be used.
The validation is executed implicitly before the generation because of AUTOSAR require-
ments.
© 2016, Vector Informatik GmbH
94 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("generate_with_default_settings"){
code{
generation{
generate()
}
}
}
Listing 4.111: Generate with standard project settings
4.7.1.2 Generate One ModuleThis sample selects one specific module and starts the generation. There are two ways to open
an settings block:
•
settings– This keyword creates empty settings. E.g. no module is selected for execution.
•
settingsFromProject– This keyword takes the project settings as template. E.g. modules from the project
settings are initially activated and can optionally be refined by explicit selections.
scriptTask("generate_one_module"){
code{
generation{
settings{
// To take the project settings as template use
// settingsFromProject{
selectGeneratorsByDefRef("/MICROSAR/Aaa")
}
generate()
}
}
}
Listing 4.112: Generate one module
Instead of selecting the generator directly by its DefRef, there is also the possibility to fetch
the generator object and select this object for execution.
scriptTask("generate_one_module"){
code{
generation{
settings{
// To take the project settings as template use
// settingsFromProject{
def gens = generatorByDefRef ("/MICROSAR/Aaa")
selectGenerators(gens)
}
generate()
}
}
}
Listing 4.113: Generate one module
© 2016, Vector Informatik GmbH
95 of
207
Chapter 4.AutomationInterface API Reference4.7.1.3 Generate Multiple ModulesTo select more than one generator the following snippet can be used.
scriptTask("generate_two_modules"){
code{
generation{
settings{
selectGeneratorsByDefRef ("/MICROSAR/Aaa", "/MICROSAR/Bbb")
}
generate()
}
}
}
Listing 4.114: Generate two modules
4.7.1.4 Generate Multi Instance ModulesSome module definitions have a upper multiplicity greater than one. (E.g. [0:5] or [0:*]) This
means it is allowed to create more than one module configuration from this module definition.
If the related generator is started with the default API, all available module configurations are
selected for generation. The following API can be used to generate only a subset of all related
module configurations.
scriptTask("generate_one_module_with_two_configs"){
code{
generation{
settings{
def gen = generatorByDefRef ("/MICROSAR/MultiInstModule")
// clear default selection
gen.deselectAllModuleInstances()
// Select the module configurations to generate
gen.selectModuleInstance(AsrPath.create("/ActiveEcuC/MultiInstModule1"))
// Instead of the full qualified path, the module configuration short name can
also be used
gen.selectModuleInstance("MultiInstModule2")
}
generate()
}
}
}
Listing 4.115: Generate one module with two configurations
4.7.1.5 Generate External Generation StepBesides the internal generators, which are covered by the topics above, there are also external
generation steps which can be executed with the following API. A new block externalGener-
ationSteps within the settings block encapsulates all settings related to external generation
scripts.
© 2016, Vector Informatik GmbH
96 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("generate_ext_gen_step"){
code{
generation{
settings{
externalGenerationSteps{
// To take the project settings as template use
// externalGenerationStepsFromProject{}
selectStep("ExtGen1")
selectStep("ExtGen2")
}
}
generate()
}
}
}
Listing 4.116: Execute an external generation step
4.7.1.6 Evaluate generation or validation resultsEach validation and generation process has an overall result which states if the execution has
been successfully or not. Additionally to the overall state, the state of one specific generator can
also be of interest. To provide a possibility to access this information all methods for validate
and generate return an IGenerationResultModel.
scriptTask("generate_with_default_settings"){
code{
generation{
def result = generate()
println "Overall result : " + result.result
println "Duration : " + result.formattedDuration
// Access results of each generator or generation step
result.generationResultRoot.allGeneratorAndStepElements.each {
println "Generator name : " + it.name
println "Result : " + it.currentState
}
}
}
}
Listing 4.117: Evaluate the generation result
© 2016, Vector Informatik GmbH
97 of
207
Chapter 4.AutomationInterface API Reference4.7.2 Generation Task TypesThere are three types of IScriptTaskTypesfor the generation process:
• Generation Step: DV_GENERATION_STEP
• Custom Workflow Step: DV_CUSTOM_WORKFLOW_STEP
• Generation Process Start: DV_ON_GENERATION_START
• Generation Process End: DV_ON_GENERATION_END
The general description of the type is in chapter
4.3.1.4 on page 29. The following code samples
show the usage of these task types:
Generation StepA sample for the DV_GENERATION_STEP type:
scriptTask("GenStepTask", DV_GENERATION_STEP){
taskDescription "Task is executed as Generation Step"
def myArg = newUserDefinedArgument(
"myArgument",
String,
"Defines a user argument for the GenerationStep")
code{ phase, generationType, resultSink ->
def myArgVal = myArg.value
// The value myArgVal was passed from the generation step in the project settings editor
scriptLogger.info "MyArg is: $myArgVal"
scriptLogger.info "GenerationType is: $generationType"
if(phase.calculation){
// Execute code before / after calculation
transaction {
// Modify the Model in the calculation phase
}
}
if(phase.validation){
// Execute code before / after validation
}
if(phase.generation){
// Execute code before / after generation
}
}
}
Listing 4.118: Use a script task as generation step during generation
The
Generation Step can also report validation results into the passed resultSink. See chap-
ter
4.8.5.10 on page 109 for a sample how to create an validation-result and report it.
The generationType defines if the current generation is for the REAL or VTT platform.
© 2016, Vector Informatik GmbH
98 of
207
Chapter 4.AutomationInterface API ReferenceCustom Workflow StepA sample for the DV_CUSTOM_WORKFLOW_STEP type:
scriptTask("GenStepTask", DV_CUSTOM_WORKFLOW_STEP){
taskDescription "Task is executed as custom workflow step"
def myArg = newUserDefinedArgument(
"myArgument",
String,
"User argument for the step")
code{
def myArgVal = myArg.value
// The value myArgVal was passed from the custom workflow step in the project settings
editor
scriptLogger.info "MyArg is: $myArgVal"
}
}
Listing 4.119: Use a script task as custom workflow step
Generation Process StartA sample for the DV_ON_GENERATION_START type:
scriptTask("GenStartTask", DV_ON_GENERATION_START){
taskDescription "The task is automatically executed at generation start"
code{ phasesToExecute, generators ->
scriptLogger.info "Phases are: $phasesToExecute"
scriptLogger.info "Generators to execute are: $generators"
// Execute code before the generation will start
}
}
Listing 4.120: Hook into the GenerationProcess at the start with script task
Generation Process EndA sample for the DV_ON_GENERATION_END type:
scriptTask("GenEndTask", DV_ON_GENERATION_END){
taskDescription "The task is automatically executed at generation end"
code{ generationResult, generators ->
scriptLogger.info "Process result was: $generationResult"
scriptLogger.info "Executed Generators: $generators"
// Execute code after the generation process was finished
}
}
Listing 4.121: Hook into the GenerationProcess at the end with script task
© 2016, Vector Informatik GmbH
99 of
207

Chapter 4.AutomationInterface API Reference4.8 Validation4.8.1 IntroductionAll examples in this chapter are based on the situation of the figure
4.6. The module and the
validators are not from the real MICROSAR stack, but just for the examples. There is a module
Tp that has 3 Buffer containers and each Buffer has a Size parameter with value=3.
There is also a validator that requires the Size parameter to be a multiple of 4. For each Size
parameter that violates this constraint, a validation-result with ID Tp00012 is created.
Such a validation-result has 2 solving-actions. One that sets the Size to the next smaller valid
value, and one that sets the Size to the next bigger valid value. The letter solving-action is
marked as preferred-solving-action.
There is also a Tp00011 result that stands for any other result. The examples will not touch
it.
Figure 4.6: example situation with the GUI
4.8.2 Access Validation-ResultsA validation{} block gives access to the validation API of the consistency component. That
means accessing the validation-results which are shown in the GUI in the validation view,
and solving them by executing solving-actions which are also shown in the GUI beneath each
validation-result (with a bulb icon).
getValidationResults() waits for background-validation-idle and returns all validation-results
© 2016, Vector Informatik GmbH
100 of
207
Chapter 4.AutomationInterface API Referenceof any kind. The returned collection has no deterministic order, especially it is not the same
order as in the GUI.
scriptTask("CheckValidationResults_filterByOriginId", DV_PROJECT){
code{
validation{
// access all validation-results
def allResults = validationResults
assert allResults.size() > 3
// filter based on methods of IValidationResultUI e.g. isId()
def tp12Results = validationResults.filter{it.isId("Tp", 12)}
assert tp12Results.size() == 3
}
// alternative access to validation-results without a validation block
assert validation.validationResults.size() > 3
}
}
Listing 4.122: Access all validation-results and filter them by ID
4.8.3 Model Transaction and Validation-Result InvalidationBefore we continue in this chapter with solving validation-results, the following information is
import to know:
Relation to model transactions:Solving validation-results with solving-actions always creates a transaction implicitly. An Il-
legalStateException will be thrown if this is done within an explicitly opened transac-
tion.
Invalidation of validation-results:Any model modification may invalidate any validation-result. In that case, the responsible val-
idator creates a new validation-result if the inconsistency still exists. Whether this happens for
a particular modification/validation-result depends on the validator implementation and is not
visible to the user/client.
Trying to solve an invalidated validation-result will throw an IllegalStateException.
Therefore it is not safe to solve a particular ISolvingActionUI that was fetched before the last
transaction. Instead, please fetch a solving-action after the last transaction, or use ISolver.solve(Closure)
which is the most preferred way of solving validation-results with solving-actions. See
4.8.4.1
on the following page.4.8.4 Solve Validation-Results with Solving-ActionsA single validation-result can be solved by calling solve() on one of its solving-actions.
© 2016, Vector Informatik GmbH
101 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("SolveSingleResultWithSolvingAction", DV_PROJECT){
code{
validation{
def tp12Results = validationResults.filter{it.isId("Tp", 12)}
assert tp12Results.size() == 3
// Take first (any) validation-result and filter its solving-actions based on
methods of ISolvingActionUI
tp12Results.first.solvingActions.filter{
it.description.contains("next bigger valid value")
}.single.solve() // reduce the collection to a single ISolvingActionUI and call
solve()
assert validationResults.filter{it.isId("Tp", 12)}.size() == 2
// One Tp12 validation-result solved
}
}
}
Listing 4.123: Solve a single validation-result with a particular solving-action
4.8.4.1 Solver APIgetSolver() gives access to the ISolver API, which has advanced methods for bulk solu-
tions.
ISolver.solve(Closure) allows to solve multiple validation-results within one transaction.
You should always use this method to solve multiple validation-results at once instead of calling
ISolvingActionUI.solve() in a loop. This is very important, because solving one validation-
result, may cause invalidation of another one. And calling ISolvingActionUI.solve() of an
invalidated validation-result throws an IllegalStateException. Also, invalidated validation-
results may get recalculated and you would miss the recalculated validation-results with the
loop approach. But with ISolver.solve(Closure) you can solve invalidated->recalculated
results as well as results which didn’t exist at the time of the call (but have been caused by
solving some other validation-result).
ISolver.solve(Closure) first waits for background-validation-idle in order to have repro-
ducible results.
The closure may contain multiple
result{specify result predicate}.withAction{select solving action}
statements. All statements together will be used as a mapper from any solvable validation-
result to a particular solving-action.
The order of these statements does not affect the solving action execution order. The statement
order might only be relevant if multiple statements match on a particular result, but would
select a different solving-action. In that case, the first statement that successfully selects a
solving-action wins.
© 2016, Vector Informatik GmbH
102 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("SolveMultipleResults", DV_PROJECT){
code{
validation{
assert validationResults.size() == 4
solver.solve{
// Call result() and pass a closure that works as filter
// based on methods of IValidationResultUI.
result{
isId("Tp", 12)
}.withAction{
containsString("next bigger valid value")
}
// On the return value, call withAction() and pass a closure that
// selects a solving-action based on methods
// of IValidationResultForSolvingActionSelect
// multiple result() calls can be placed in one solve() call.
result{isId("Com", 34)}.withAction{containsString("recalculate")}
}
assert validationResults.size() == 1
// Three Tp12 and zero Com34 (didn't exist) results solved. One other left
}}}
Listing 4.124: Fast solve multiple results within one transaction
Solve all PreferredSolvingActionsISolver.solveAllWithPreferredSolvingAction() solves
all validation-results with its preferred solving- action of each validation-result (solving-action
return by IValidationResultUI.getPreferredSolvingAction()). Validation-results without
a preferred solving-action are skipped.
This method first waits for background-validation-idle in order to have reproducible results.
scriptTask("SolveAllWithPreferred", DV_PROJECT){
code{
validation{
assert validationResults.size() == 4
solver.solveAllWithPreferredSolvingAction()
assert validationResults.size() == 1
// this would do the same
transactions.transactionHistory.undo()
assert validationResults.size() == 4
solver.solve{
result{
true}.withAction{preferred}
}
assert validationResults.size() == 1
}}}
Listing 4.125: Solve all validation-results with its preferred solving-action (if available)
4.8.5 Advanced Topics© 2016, Vector Informatik GmbH
103 of
207
Chapter 4.AutomationInterface API Reference4.8.5.1 Access Validation-Results of a Model-ObjectMIObject.getValidationResults() returns the validation-results of an MIObject. These are
those results for which IValidationResultUI.matchErroneousCE(MIObject) returns true.
scriptTask("CheckValidationResultsOfObject", DV_PROJECT){
code{
// sampleDefRefs contains DefRef constants just for this example. Please use the real
DefRefs from your SIP
// a Buffer container
def buffer002 = mdfModel(AsrPath.create("/ActiveEcuC/Tp/Buffer_002"))
// the Size parameter
def sizeParam = buffer002.parameter(sampleDefRefs.tpBufferSizeDefRef).single
// the result exists for the Size parameter, not for the Buffer container
assert sizeParam.validationResults.size() == 1
assert buffer002.validationResults.size() == 0
}
}
Listing 4.126: Access all validation-results of a particular object
IViewedModelObject.getValidationResults() returns the validation-results for the element
matching the model object and the model view, like BswmdModel objects.
4.8.5.2 Access Validation-Results of a DefRefDefRef.getValidationResults() returns all validation-results which match the passed defi-
nition. So every configuration element which matches the validation-result and is an instance
of definition.
The used project for this call is the active project, see ScriptApi.getActiveProject().
scriptTask("CheckValidationResultsOfDefRef", DV_PROJECT){
code{
// sampleDefRefs contains DefRef constants just for this example. Please use the real
DefRefs from your SIP
assert sampleDefRefs.tpBufferSizeDefRef.validationResults.size() == 3
}
}
Listing 4.127: Access all validation-results of a particular DefRef
4.8.5.3 Filter Validation-Results using an ID ConstantGroovy allows you to spread list elements as method arguments using the spread operator. This
allows you to define constants for the isId(String,int) method.
© 2016, Vector Informatik GmbH
104 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("FilterResultsUsingAnIdConstant2", DV_PROJECT){
code{
validation{
def tp12Const = ["Tp",12]
assert validationResults.size() > 3
assert validationResults.filter{it.isId(*tp12Const)}.size() == 3
}
}
}
Listing 4.128: Filter validation-results using an ID constant
4.8.5.4 Identification of a Particular Solving-ActionA so called solving-action-group-ID identifies a solving-action uniquely within one validation-
result. In other words, two solving-actions, which do semantically the same, from two validation-
results of the same result-ID (origin + number), belong to the same solving-action-group. This
semantical group may have an optional solving-action-group-ID, that can be used for solving-
action identification within one validation-result.
Keep in mind that the solving-action-group-ID is only unique within one validation-result-ID,
and that the group-ID assignment is optional for a validator implementation.
In order to find out the solving-action-group-IDs, press CTRL+SHIFT+F9 with a selected validation-
result to copy detailed information about that result including solving-action-group-IDs (if as-
signed) to the clipboard.
If group-IDs are assigned, it is much safer to use these for solving-action identification than
description-text matching, because a description-text may change.
final int SA_GROUP_ID_TP12_NEXT_BIGGER_VALID_VALUE = 2
scriptTask("SolveMultipleResultsByGroupId", DV_PROJECT){
code{
validation{
assert validationResults.size() == 4
solver.solve{
result{isId("Tp", 12)}
.withAction{
byGroupId(SA_GROUP_ID_TP12_NEXT_BIGGER_VALID_VALUE)
}
// instead of .withAction{containsString("next bigger valid value")}
}
assert validationResults.size() == 1
// Three Tp12 validation-results solved.
}
}
}
Listing 4.129: Fast solve multiple validation-results within one transaction using a solving-
action-group-ID
© 2016, Vector Informatik GmbH
105 of
207
Chapter 4.AutomationInterface API Reference4.8.5.5 Validation-Result Description as MixedTextIValidationResultUI.getDescription() returns an IMixedText that describes the inconsis-
tency.
IMixedText is a construct that represents a text, whereby parts of that text can also hold the
object which they represent. This allows a consumer e.g. a GUI to make the object-parts of
the text clickable and to reformat these object-parts as wanted.
Consumers which don’t need these advanced features can just call IMixedText.toString()
which returns a default format of the text.
4.8.5.6 Further IValidationResultUI MethodsThe following listing gives an overview of other "properties" of an IValidatonResultUI.
scriptTask("IValidationResultUIApiOverview", DV_PROJECT){
code{
validation{
def r = validationResults.filter{it.isId("Tp", 12)}.first
assert r.id.origin == "Tp"
assert r.id.id == 12
assert r.description.toString().contains("must be a multiple of")
assert r.severity == EValidationSeverityType.ERROR
assert r.solvingActions.size() == 2
assert r.getSolvingActionByGroupId(2).description.contains("next bigger valid value")
// this result has a preferred-solving-action
assert r.preferredSolvingAction == r.getSolvingActionByGroupId(2)
// results with lower severity than ERROR can be acknowledged in the GUI
assert r.acknowledgement.isPresent() ==
false// if the cause was an exception, r.cause.get() returns it
assert r.cause.isPresent() ==
false// an ERROR result gets reduced to WARNING if one of its erroneous CEs is user-defined (
user-overridden)
assert r.isReducedSeverity() ==
false// on-demand results are visualized with a gear-wheel icon
assert r.isOnDemandResult() ==
false}
}
}
Listing 4.130: IValidationResultUI overview
© 2016, Vector Informatik GmbH
106 of
207
Chapter 4.AutomationInterface API Reference4.8.5.7 IValidationResultUI in a variant (Post Build Selectable) ProjectscriptTask("IValidationResultUIInAVariantProject", DV_PROJECT){
code{
validation{
def r = validationResults.filter{it.isId("Tp", 12)}.first
assert r.isGeneralVariantContext() // either it is a general result...
assert r.predefinedVariantContexts.size() == 0 // or it is assigned to one or more (
but never all) variants
// If a validator assigns a result to all variants, it will be a general result at
UI-side.
}
}
}
Listing 4.131: IValidationResultUI in a variant (post build selectable) project
4.8.5.8 Erroneous CEs of a Validation-ResultIValidationResultUI.getErroneousCEs() returns a collection of IDescriptor, each describ-
ing a CE that gets an error annotation in the GUI.
To check for a certain model element is affected by the result please use the methods, which
return true, if a model is affected by the validation-result:
• IValidationResultUI.matchErroneousCE(MIObject)
• IValidationResultUI.matchErroneousCE(IHasModelObject)
• IValidationResultUI.matchErroneousCE(MIHasDefinition, DefRef)
scriptTask("IValidationResultUIErroneousCEs", DV_PROJECT){
code{
validation{
// sampleDefRefs contains DefRef constants just for this example. Please use the
real DefRefs from your SIP
def result = validationResults.filter{it.isId("Tp", 12)}.first
// Retrieve the model element to check
def modelElement // = retrieveElement ...
// Check if the model object is affected by the validation-result
assert result.matchErroneousCE(modelElement)
}
}
}
Listing 4.132: CE is affected by (matches) an IValidationResultUI
Advanced Descriptor DetailsAn IDescriptor is a construct that can be used to "point to"
some location in the model. A descriptor can have several kinds of aspects to describe where it
points to. Aspect kinds are e.g. IMdfObjectAspect, IDefRefAspect, IMdfMetaClassAspect,
IMdfFeatureAspect.
getAspect(Class) gets a particular aspect if available, otherwise null.
© 2016, Vector Informatik GmbH
107 of
207
Chapter 4.AutomationInterface API ReferenceA descriptor has a parent descriptor. This allows to describe a hierarchy.
E.g. if you want to express that something with definition X is missing as a child of the existing
MDF object Y. In this example you have a descriptor with an IDefRefAspect containing the
definition X. This descriptor that has a parent descriptor with an IMdfObjectAspect containing
the object Y.
The term descriptor refers to a descriptor together with its parent-descriptor hierarchy.
import com.vector.cfg.model.cedescriptor.aspect.*
scriptTask("IValidationResultUIErroneousCEs", DV_PROJECT){
code{
validation{
// sampleDefRefs contains DefRef constants just for this example. Please use the
real DefRefs from your SIP
def result = validationResults.filter{it.isId("Tp", 12)}.first
def descriptor = result.erroneousCEs.single // this result in this example has only
a single erroneous-CE descriptor
def defRefAspect = descriptor.getAspect(IDefRefAspect.
class)
assert defRefAspect !=
null; // this descriptor in this example has an IDefRefAspect
assert defRefAspect.defRef.equals(sampleDefRefs.tpBufferSizeDefRef)
def objectAspect = descriptor.getAspect(IMdfObjectAspect.
class)
assert objectAspect !=
null // // this descriptor in this example has an
IMdfObjectAspect
// An IMdfObjectAspect would be unavailable for a descriptor describing that
something is missing
def parentObjectAspect = descriptor.parent.getAspect(IMdfObjectAspect.
class)
assert parentObjectAspect !=
null// Dealing with descriptors is universal, but needs more code. Using these methods
might fit your needs.
assert result.matchErroneousCE(objectAspect.getObject())
assert result.matchErroneousCE(parentObjectAspect.getObject(), sampleDefRefs.
tpBufferSizeDefRef)
}
}
}
Listing 4.133: Advanced
use
case
-
Retrieve
Erroneous
CEs
with
descriptors
of
an
IValidationResultUI
4.8.5.9 Examine Solving-Action ExecutionThe easiest and most reliable option for verifying solving-action execution is to check the pres-
ence of validation-results afterwards.
This is also the feedback strategy of the GUI. After multiple solving-actions have been solved,
the GUI does not show the execution result of each individual solving-action, but just the
remaining validation-results after the operation. Only if a single solving-action is to be solved,
and that fails, the GUI shows the message of that failure including the reason.
The following describes further options of examination:
ISolvingActionUI.solve() returns an ISolvingActionExecutionResult.
An ISolvingAc-
tionExecutionResult represents the result of one solving action execution. Use isOk() to find
out if it was successful. Call getUserMessage() to get the failure reason.
© 2016, Vector Informatik GmbH
108 of
207
Chapter 4.AutomationInterface API ReferenceISolver.solve(Closure) returns an ISolvingActionSummaryResult.
An ISolvingAc-
tionSummaryResult represents the execution of multiple results.
ISolvingActionSumma-
ryResult.isOk() returns true if getExecutionResult() is EExecutionResult.SUCCESSFUL
or EExecutionResult.WARNING, this is if at least one sub-result was ok.
Call getSubResults() to get a list of ISolvingActionExecutionResults.
import com.vector.cfg.util.activity.execresult.EExecutionResult
scriptTask("SolvingReturnValue", DV_PROJECT){
code{
validation{
assert validationResults.size() == 4
// In this example, three validation-results have a preferred solving action.
// One of the three cannot be solved because a parameter is user-defined.
def summaryResult = solver.solveAllWithPreferredSolvingAction()
assert validationResults.size() == 2 // Two have been solved, one with a preferred
solving-action is left.
assert summaryResult.executionResult == EExecutionResult.WARNING
// DemoAsserts is just for this example to show what kind of sub-results the
summaryResult contains.
DemoAsserts.summaryResultContainsASubResultWith("OK",summaryResult)
//two such sub-results for the validation-results with preferred-solving-action that
could be solved
DemoAsserts.summaryResultContainsASubResultWith(["invalid modification","not
changeable","Reason","is user-defined"],summaryResult)
// such a sub-result for the failed preferred solving action due to the user-defined
parameter
DemoAsserts.summaryResultContainsASubResultWith("Maximum solving attempts reached for
the validation-result of the following solving-action",summaryResult)
// Cfg5 takes multiple attempts to solve a result because other changes may eliminate
a blocking reason, but stops after an execution limit is reached.
}
}
}
Listing 4.134: Examine an ISolvingActionSummaryResult
4.8.5.10 Create a Validation-Result in a Script TaskThe resultCreation API provides methods to create new IValidationResults, which could
then be reported to a IValidationResultSink. This is can be used to report validation-results
similar to a validator/generator, but from within a script task.
ValidationResultSinkThe IValidationResultSink must be obtained by the context and is
not provided by the creation API. E.g. some script tasks pass an IValidationResultSink as
argument (like DV_GENERATION_STEP).
Or you have to activate the MD license option for development during script task creation by
calling the method requiresMDDevelopmentLicense(), then you could retrieve an IValida-
tionResultSink from the method getResultSink().
© 2016, Vector Informatik GmbH
109 of
207
Chapter 4.AutomationInterface API ReferenceReporting ValidationResult in Task providing a ResultSinkThis sample applies to task types
providing a ResultSink in the Task API, like DV_GENERATION_STEP.
scriptTask("ScriptTaskCreationResult" /* Insert with task type providing resultSink */ ){
code{
validation{
resultCreation{
// The ValidationResultId group multiple results
def valId = createValidationResultIdForScriptTask(
/* ID */ 1234,
/* Description */ "Summary of the ValidationResultId",
/* Severity */ EValidationSeverityType.ERROR)
// Create a new resultBuilder
def builder = newResultBuilder(valId, "Description of the Result")
// You can add multiple elements as error objects to mark them
builder.addErrorObject(sipDefRef.EcucGeneral.bswmdModel().single)
// Add more calls when needed
// Create the result from the builder
def valResult = builder.buildResult()
// You need to report the result to a resultSink
// You have to get the sink from the context, e.g. script task args
// a sample line would be
resultSinkForTask.reportValidationResult(valResult)
}
}
}}
Listing 4.135: Create a ValidationResult
Reporting ValidationResult with MD License Option for DevelopmentThis sample can be
used in every task types but you need a MD license option for development to retrieve the
ResultSink.
scriptTask("ScriptTaskCreationResult", DV_PROJECT){
// Result reporting requires an MD license for development
requiresMDDevelopmentLicense()
code{
validation{
resultCreation{
// The ValidationResultId group multiple results
def valId = createValidationResultIdForScriptTask(
/* ID */ 1234,
/* Description */ "Summary of the ValidationResultId",
/* Severity */ EValidationSeverityType.ERROR)
// Create a new resultBuilder
def builder = newResultBuilder(valId, "Description of the Result")
// Create the result from the builder
def valResult = builder.buildResult()
// When MD license is enabled you can access a resultSink
resultSink.reportValidationResult(valResult)
}}}}
Listing 4.136: Report a ValidationResult when MD license option is available
© 2016, Vector Informatik GmbH
110 of
207
Chapter 4.AutomationInterface API Reference4.9 Update WorkflowThe Update Workflow derives the initial EcuC from the input files and updates the project
accordingly. The Update Workflow API comprises modification of variants, modification of the
input files list and the execution of an update workflow.
4.9.1 Method Overview• workflow: the workflow closure is the central entry point for the Workflow API.
– update: contains all settings for the Update Workflow and executes the update after
leaving the closure block.
∗ input: supports the modification of the input files list and specific settings.
· communication: the communication closure contains settings for the com-
munication extract and communication legacy input files (like cbd, ldf or
fibex). Take a look at the JavaDoc of ICommunicationApi for all possible
settings.
4.9.2 Example: Content of Input Files has changed.In case of a changed content of input files, the update workflow can be started with the work-
flow.update(dpaProjectFilePath) method. This will start the Update Workflow, with the
input files as selected in the DaVinci Configurator GUI. The parameter dpaProjectFilePath
accepts the same types and has the same semantic as resolvePath described in
4.4.3.1 on
page 34.scriptTask("UpdateExistingProject", DV_APPLICATION) {
code {
workflow.update pathToDpaFile
}
}
Listing 4.137: Update an existing project
The update workflow is started at the end of the update-closure.
© 2016, Vector Informatik GmbH
111 of
207
Chapter 4.AutomationInterface API Reference4.9.3 Example: List of Input Files shall be changedscriptTask("ChangeListOfComExtractsAndUpdate", DV_APPLICATION) {
code {
def extractPath = paths.resolvePath(extractFile)
def diagExtractPath = paths.resolvePath(diagExtract)
workflow.update(dpaProjectFile){
input{
communication{
extract{
extractFiles{exFilePathList->
// clear the list of communication extracts
exFilePathList.clear()
// adds an communication extract
exFilePathList.add(extractPath.asPersistablePath())
}
// change the selection of the ecuInstance
// Note: this closure is deferred executed.
ecuInstanceSelection{
return availableEcuInstances[0]
}
}
}
diagnostic{
extract{
extractFiles{exFilePathList->
// clear the list of communication extracts
exFilePathList.clear()
// adds an communication extract
exFilePathList.add(diagExtractPath.asPersistablePath())
}
// change the selection of the ecuInstance
// Note: this closure is deferred executed.
ecuInstanceSelection{
return availableEcuInstances[0]
}
}
}
}}}}
Listing 4.138: Change list of communication extracts and update
Note: The code in the ecuInstanceSelection closure is deferred executed.Theaccess to variables, declared outside of this closure is not allowed.This example shows the complete replacement of the current list of communication extracts
with one extract and the selection of the first ecuInstance in the new extract. The update
workflow is executed after the update closure block is left.
4.9.4 PrerequisitesThe Update Workflow API can not be used while the Project to update is opened. E.g. in a
IProjectRef.openProject closure block or in a ScriptTask with the DV_PROJECT ScriptTask-
Type.
© 2016, Vector Informatik GmbH
112 of
207
Chapter 4.AutomationInterface API Reference4.10 DomainsThe domain APIs are specifically designed to provide high convenience support for typical
domain use cases.
The domain API is the entry point for accessing the different domain interfaces. It is available
in opened projects in the form of the IDomainApi interface.
IDomainApi provides methods for accessing the different domain-specific APIs. Each domain’s
API is available via the domain’s name.
For an example see the communication domain
API
4.10.1.getDomain() allows accessing the IDomainApi like a property.
scriptTask('taskName') {
code {
// IDomainApi is available as "domain" property
def domainApi = domain
}
}
Listing 4.139: Accessing IDomainApi as a property
domain(Closure) allows accessing the IDomainApi in a scope-like way.
scriptTask('taskName') {
code {
domain {
// IDomainApi is available inside this Closure
}
}
}
Listing 4.140: Accessing IDomainApi in a scope-like way
4.10.1 Communication DomainThe communication domain API is specifically designed to support communication related
use cases. It is available from the IDomainApi
4.10 in the form of the ICommunicationApi
interface.
getCommunication() allows accessing the ICommunicationApi like a property.
scriptTask('taskName') {
code {
// ICommunicationApi is available as "communication" property
def communication = domain.communication
}
}
Listing 4.141: Accessing ICommunicationApi as a property
communication(Closure) allows accessing the ICommunicationApi in a scope-like way.
© 2016, Vector Informatik GmbH
113 of
207
Chapter 4.AutomationInterface API ReferencescriptTask('taskName') {
code {
domain.communication {
// ICommunicationApi is available inside this Closure
}
}
}
Listing 4.142: Accessing ICommunicationApi in a scope-like way
The following use cases are supported:
Accessing Can ControllersgetCanControllers() returns a list of all ICanControllers in
the configuration
4.10.1.1 on the following page.© 2016, Vector Informatik GmbH
114 of
207
Chapter 4.AutomationInterface API Reference4.10.1.1 CanControllersAn ICanController instance represents a CanController MIContainer providing support for
use cases exceeding those supported by the model API.
scriptTask('OptimizeAcceptanceFilters', DV_APPLICATION) {
code {
// replace $dpaFile with the path to your project
def theProject = projects.openProject("$dpaFile") {
transaction {
domain.communication {
// open acceptance filters of all CanControllers
canControllers*.openAcceptanceFilters()
// open acceptance filters of first CanController
canControllers.first.openAcceptanceFilters()
canControllers[0].openAcceptanceFilters() // same as above
// open acceptance filters of second CanController
// (if there is a second CanController)
canControllers[1]?.openAcceptanceFilters()
// open acceptance filters of a dedicated CanController
canControllers.filter { it.name.contains 'CH0' }.single.openAcceptanceFilters()
// accessing a dedicated CanController
def ch0 = canControllers.filter { it.name.contains 'CH0' }.single
// assert: ch0's first CanFilterMask value is XXXXXXXXXXX
assert 'XXXXXXXXXXX' == ch0.canFilterMasks[0].filter
// set CanFilterMask value to 01111111111
ch0.canFilterMasks[0].filter = '01111111111'
assert '01111111111' == ch0.canFilterMasks[0].filter
// automatic acceptance filter optimization
ch0.optimizeFilters { fullCan =
true }
}
}
}
scriptLogger.info('Successfully optimized Can acceptance filters.')
}
}
Listing 4.143: Optimizing Can Acceptance Filters
Opening Acceptance FiltersopenAcceptanceFilters() opens all of this ICanController’s
acceptance filters.
Optimizing Acceptance FiltersoptimizeFilters(Closure) optimizes this ICanController’s
acceptance filter mask configurations. The given Closure is delegated to the IOptimizeAccep-
tanceFiltersApi interface for parameterizing the optimization.
Using setFullCan(boolean) it can be specified whether the optimization shall take full can
objects into account or not.
© 2016, Vector Informatik GmbH
115 of
207
Chapter 4.AutomationInterface API ReferenceCreating new CanFilterMaskscreateCanFilterMask() creates a new ICanFilterMask for
this ICanController.
Accessing a CanController’s CanFilterMasksgetCanFilterMasks() returns all of this ICan-
Controller’s ICanFilterMasks.
Accessing a CanController’s MIContainergetMdfObject() returns the MIContainer repre-
sented by this ICanController.
4.10.1.2 CanFilterMasksAn ICanFilterMask instance represents a CanFilterMask MIContainer providing support for
use cases exceeding those supported by the model API.
For example code see
4.10.1.1 on the previous page. The following use cases are supported:
Filter TypesECanAcceptanceFilterType lists the possible values for an ICanFilterMask’s
filter type.
STANDARD results in a standard Can acceptance filter value with length 11.
EXTENDED results in an extended Can acceptance filter value with length 29.
MIXED results in a mixed Can acceptance filter value with length 29.
Accessing a CanFilterMask’s Filter TypegetFilterType() returns this ICanFilterMask’s
filter type.
Specifying a CanFilterMask’s Filter TypeUsing setFilterType(ECanAcceptanceFilterType)
this ICanFilterMask’s filter type can be specified.
Accessing a CanFilterMask’s Filter ValuegetFilter() returns this ICanFilterMask’s filter
value. A CanFilterMask’s filter value is a String containing the characters ’0’, ’1’ and ’X’
(don’t care). For determining if a given Can ID passes the filter it is matched bit for bit against
the String’s characters. The character at index 0 is matched against the most significant bit.
The character at index length() - 1 is matched against the least significant bit. The length
of the String corresponds to the CanFilterMask’s filter type.
Specifying a CanFilterMask’s Filter ValueUsing setFilter(String) this ICanFilterMask’s
filter value can be specified.
Accessing a CanFilterMask’s MIContainergetMdfObject() returns the MIContainer rep-
resented by this ICanFilterMask.
© 2016, Vector Informatik GmbH
116 of
207
Chapter 4.AutomationInterface API Reference4.10.2 Diagnostics DomainThe diagnostics domain API is specifically designed to support diagnostics related use cases.
It is available from the IDomainApi
4.10 on page 113 in the form of the IDiagnosticsApi
interface.
getDiagnostics() allows accessing the IDiagnosticsApi like a property.
scriptTask('taskName') {
code {
// IDiagnosticsApi is available as "diagnostics" property
def diagnostics = domain.diagnostics
}
}
Listing 4.144: Accessing IDiagnosticsApi as a property
diagnostics(Closure) allows accessing the IDiagnosticsApi in a scope-like way.
scriptTask('taskName') {
code {
domain.diagnostics {
// IDiagnosticsApi is available here
}
}
}
Listing 4.145: Accessing IDiagnosticsApi in a scope-like manner
The following use cases are supported:
Dem EventsThe API provides access and creation of IDemEvents in the configuration. See
chapter
4.10.2.1 on the next page for more details.
Check for OBD IIisObd2Enabled() checks, if OBD II is available in the configuration.
Enable OBD IIsetObd2Enabled(boolean) enables or disables OBD II in the configuration.
Note, that OBD II can only be enabled, if a valid SIP license was found.
Check for WWH-OBDisWwhObdEnabled() checks, if WWH-OBD is available in the config-
uration.
Enable WWH-OBDsetWwhObdEnabled(boolean) enables or disables WWH-OBD in the
configuration. Note, that WWH-OBD can only be enabled, if a valid SIP license was found.
© 2016, Vector Informatik GmbH
117 of
207
Chapter 4.AutomationInterface API Reference4.10.2.1 DemEventsAn IDemEvent instance represents a diagnostic event and and provides usecase centric func-
tionalities to modify and query diagnostic events.
Accessing Dem EventsgetDemEvents() returns a list of all IDemEvents in the configuration.
Creating Dem EventscreateDemEvent(Closure) is used to create diagnostic events of dif-
ferent kinds.
The method can be configured to create different types of DTCs/Events:
1.
UDS Event: This is the default type of event, when only an ’eventName’ and a ’dtc’
number is specified. A new DemEventParameter container with the given shortname and
a new DemDTCClass with the given DemUdsDTC is created.
scriptTask('taskName') {
code {
transaction {
domain.diagnostics {
def udsEvent = createDemEvent {
eventName = "NewUdsEvent"
dtc = 0x30
}
}}}}
Listing 4.146: Create a new UDS DTC with event
2.
OBD II Event: If OBD II is enabled for the loaded configuration, and a ’obd2Dtc’ is
specified instead of a ’dtc’, the method will create an OBD II relevant event. The differ-
ence is, that it will set the parameter DemObdDTC instead of DemUdsDTC. It is also
possible to specify ’dtc’ as well as ’obd2dtc’, which will result in both DTC parameters
are set.
scriptTask('taskName') {
code {
transaction {
domain.diagnostics {
// OBD must be enabled and legislation must be OBD2
// Enable OBD2
obd2Enabled =
truedef obd2Event = createDemEvent {
eventName = 'NewOBD2Event'
obd2Dtc = 0x40
}
def obd2CombinedEvent = createDemEvent {
eventName = 'UDS_OBD2_Combined_Event'
dtc = 0x31
obd2Dtc = 0x41
}
}}}}
Listing 4.147: Enable OBD II and create a new OBD related DTC with event
© 2016, Vector Informatik GmbH
118 of
207
Chapter 4.AutomationInterface API Reference3.
WWH-OBD Event: If WWH-OBD is enabled for the loaded configuration, and a
’wwhObdDtcClass’ with a value other than ’NO_CLASS’ is specified, the method will
create a WWH-OBD relevant event. Note that WWH-OBD relevant events usually du
reference the so called MIL indicator, thus this reference will be set by default in the
newly created DemEventParameter.
scriptTask('taskName') {
code {
transaction {
domain.diagnostics {
// OBD must be enabled, and legislation must be WWH-OBD
// The parameter '/Dem/DemGeneral/DemMILIndicatorRef' must be set
wwhObdEnabled =
truedef wwhObdEvent = createDemEvent {
eventName = 'WWHOBD_Event'
dtc = 0x50
// wwhObdClass != NO_CLASS indicates WWH-OBD event
wwhObdDtcClass = CLASS_A
}
}}}}
Listing 4.148: Enable WWH-OBD and create a new OBD related DTC with event
4.
J1939 Event: The last type of event is a J1939 related event, which can be created when
J1939 is licensed and available for the loaded configuration. This is done in a similar way
as for UDS events, but additionally specifying ’spn’, ’fmi’ values as well as the name of
the referenced ’nodeAddress’.
scriptTask('taskName') {
code {
def nodeAddressContainer = mdfModel(AsrPath.create("/ActiveEcuC/Dem/DemConfigSet/
DemJ1939NodeAddress", MIContainer))
transaction {
domain.diagnostics {
// J1939 Event creation
// J1939 must be enabled and License must be available.
j1939Enabled =
truedef j1939Event = createDemEvent {
eventName 'J1939_Event'
dtc 0x30
spn 90
fmi 13
nodeAddress nodeAddressContainer
}
}}}}
Listing 4.149: Open a project, enable J1939 and create a new J1939 DTC with event
Important Note:
For every DTC numbers apply the rule, that if there are already DemDTCClasses with
the given number, they will be used. In such a case, no new DemDTCClass container is
created.
© 2016, Vector Informatik GmbH
119 of
207
Chapter 4.AutomationInterface API Reference4.10.3 Runtime System DomainThe runtime system domain API is specifically designed to support runtime system related
use cases.
It is available from the IDomainApi (see
4.10 on page 113) in the form of the
IRuntimeSystemApi interface.
getRuntimeSystem() allows accessing the IRuntimeSystemApi like a property.
scriptTask('taskName') {
code {
// IRuntimeSystemApi is available as "runtimeSystem" property
def runtimeSystem = domain.runtimeSystem
}
}
Listing 4.150: Accessing IRuntimeSystemApi as a property
runtimeSystem(Closure) allows accessing the IRuntimeSystemApi in a scope-like way.
scriptTask('taskName') {
code {
domain.runtimeSystem {
// IRuntimeSystemApi is available inside this Closure
}
}
}
Listing 4.151: Accessing IRuntimeSystemApi in a scope-like way
The following use cases are supported:
4.10.3.1 Mapping component portsA component port (IComponentPort) represents a port prototype and its corresponding com-
ponent prototype, and in case of a delegation port the corresponding top level composition type
(Ecu Composition).
The mapping component ports use case allows connecting different ports in a similar way the
component connection assistant does.
Selecting component ports to mapThe entry point is to select a collection of component
ports and auto-map them to the possible target component ports by applying the matching
rules of the component connection assistant.
selectComponentPorts(Closure) allows the selection of IComponentPorts using predicates.
PredicatesTo select the component ports predicates can be provided to narrow down the
component ports to be connected: this corresponds to the manual selection of certain component
ports in the component connection assistant.
Per default the predicates are combined via logical AND. To realize other combinations, use
the ’or’,’not’ and ’and’ predicates.
© 2016, Vector Informatik GmbH
120 of
207
Chapter 4.AutomationInterface API ReferenceComponent Port Predicates• unconnected() matches unconnected component ports.
• connected() matches connected component ports.
• senderReceiver() matches component ports whose port has a sender/receiver port in-
terface.
• clientServer() matches component ports whose port has a client/server port interface.
• modeSwitch() matches component ports whose port has a mode-switch port interface.
• nvData() matches component ports whose port has a NvData port interface.
• parameter() matches component ports whose port has a parameter (calibration) port
interface.
• provided() matches provided component ports (p-port).
• required() matches required component ports (r-port).
• providedRequired() matches provided-required component ports (pr-port).
• delegation() matches delegation ports (ports of the Ecu composition).
• application() matches component ports whose port interface is an application port
interface.
• service() matches component ports whose port interface is an service port interface.
• name(String) matches component ports with the given port name.
• name(Pattern) matches component ports with the given port name pattern.
• asrPath(String) matches component ports with the given port autosar path.
• asrPath(Pattern) matches component ports with the given port autosar path pattern.
• component(String) matches component ports with the given component name.
• component(Pattern) matches component ports with the given component name pattern.
• componentAsrPath(String) matches the component ports with the given component
autosar path.
• componentAsrPath(Pattern) matches component ports with the given component au-
tosar path pattern.
• portInterfaceMapping(String) matches component ports for whose port interfaces a
port interface mapping with the given port interface mapping name exists.
• portInterfaceMapping(Pattern) matches component ports for whose port interfaces a
port interface mapping with the given port interface mapping name pattern exists.
• portInterfaceMappingAsrPath(String) matches component ports for whose port in-
terfaces a port interface mapping with the given port interface mapping autosar path
exists.
• portInterfaceMappingAsrPath(Pattern) matches component ports for whose port in-
terfaces a port interface mapping with the given port interface mapping autosar path
pattern exists.
© 2016, Vector Informatik GmbH
121 of
207
Chapter 4.AutomationInterface API Reference• filterAdvanced(Closure) matches component ports for whose the given closure results
to true.
• and(Closure) combines the predicates inside the closure with a logical AND.
• or(Closure) combines the predicates inside the closure with a logical OR.
• not(Closure) negates the combination of predicates inside the closure.
ExamplesscriptTask("selectAllPorts", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def selectedPorts =
selectComponentPorts {
// no predicates: select ALL component ports
} getComponentPorts()
scriptLogger.infoFormat("Selected {0} component ports.", selectedPorts.size())
}
}
}
}
Listing 4.152: Selects all component ports
scriptTask("selectAllUnconnectedPorts", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def selectedPorts =
selectComponentPorts {
unconnected() // select all unconnected component ports
} getComponentPorts()
scriptLogger.infoFormat("Selected {0} component ports.", selectedPorts.size())
}
}
}
}
Listing 4.153: Selects all unconnected component ports
© 2016, Vector Informatik GmbH
122 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("selectAllUnconnectedSRAndConnectedModePorts", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def selectedPorts =
selectComponentPorts {
// start with logical OR
or {
and { // unconnected sender/receiver ports
unconnected()
senderReceiver()
}
and { // connected modeSwitch ports
connected()
modeSwitch()
}
}
} getComponentPorts()
scriptLogger.infoFormat("Selected {0} component ports.", selectedPorts.size())
}
}
}
}
Listing 4.154: Select all unconnected sender/receiver or connected mode-switch component
ports
Auto-MappingThe use case of auto-mapping component ports is based on the selection of
component ports: it offers the methods to auto-map.
autoMap() tries to auto-map the selection of component ports according the component con-
nection assistant default rules.
Examples for autoMap()scriptTask("automapAll", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
// no predicates: select ALL component ports
} autoMap()
scriptLogger.infoFormat("Created {0} mappings.", mappedConnectors.size())
}
}
}
}
Listing 4.155: Tries to auto-map all ports
© 2016, Vector Informatik GmbH
123 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("automapAllUnconnected", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
unconnected() // select all unconnected component ports
} autoMap()
scriptLogger.infoFormat("Created {0} mappings.", mappedConnectors.size())
}
}
}
}
Listing 4.156: Tries to auto-map all unconnected component ports
scriptTask("autoMapUnconnectedSRCS", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
// select all unconnected client/server and unconnected sender/receiver ports
unconnected()
or {
clientServer()
senderReceiver()
}
} autoMap()
scriptLogger.infoFormat("Created {0} mappings.",mappedConnectors.size())
}
}
}
}
Listing 4.157: Tries to auto-map all unconnected sender/receiver and client/server ports
import com.vector.cfg.model.sysdesc.api.port.IComponentPort
scriptTask("autoMapAdvancedfilter", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
// select component port by own custom filter predicate
filterAdvanced {IComponentPort port ->
"MyUUID".equals(port.getMdfPort().getUuid2())
}
} autoMap()
scriptLogger.infoFormat("Created {0} mappings.",mappedConnectors.size())
}
}
}
}
Listing 4.158: Tries to auto-map port determined by advanced filter
autoMapTo(Closure) tries to auto-map the selection of component ports according the compo-
nent connection assistant rules but offers more control for the auto-mapping: Inside the closure
additional predicates for narrowing down the target component ports can be defined and code
© 2016, Vector Informatik GmbH
124 of
207
Chapter 4.AutomationInterface API Referenceto evaluate and change the auto-mapper results can be provided.
Narrowing down the target component ports may be useful to gain better matches for the auto-
mapper: In case several target component ports match equally, no auto-mapping is performed.
So reducing the target component ports my improve the results of the auto-mapping.
The component port selection will produce trace, info and warning logs. To see them, activate
the ’com.vector.cfg.dom.runtimesys.groovy.api.IComponentPortSelection’ logger with
the appropriate log level.
Control the auto-mapping in autoMapTo(Closure)selectTargetPorts(Closure) allows to define predicates to narrow down the target ports for
the auto-mapping. The predicates are used to filter the possible target component ports which
were computed from the source component port selection.
scriptTask("autoMapUnconnectedToComponentPrototype", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
unconnected() // select all unconnected ports
} autoMapTo {
selectTargetPorts {
component "App1" // and auto-map them to all ports of component "App1"
}
}
scriptLogger.infoFormat("Created {0} mappings.",mappedConnectors.size())
}
}
}
}
Listing 4.159: Tries to auto map all unconnected ports to the ports of one component prototype
evaluateMatches(Closure) allows to evaluate and change the results of the auto-mapping. It
corresponds to the confirm page of the component connection assistant.
For each source component port the provided closure is called: Parameters are the source
component port, the optional matched target component port (or null), and a list of all potential
target component ports (respecting the selectTargetPorts(Closure) predicates). The return
value must be a list of target component ports.
© 2016, Vector Informatik GmbH
125 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.dom.runtimesys.api.assistant.connection.ISourceComponentPort
import com.vector.cfg.dom.runtimesys.api.assistant.connection.ITargetComponentPort
scriptTask("automapAllUnconnectedAndEvaluateMatches", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
unconnected()
} autoMapTo {
evaluateMatches {
ISourceComponentPort sourcePort,
ITargetComponentPort optionalMatchedTargetPort,
List<ITargetComponentPort> potentialTargetPorts ->
if (sourcePort.getPortName().equals("MyExceptionalPort")) {
// example for excluding a port from auto-mapping by having a close
look
// sourcePort.getMdfPort()....
return null}
// default: do not change the auto-matched port
[optionalMatchedTargetPort]
}
}
scriptLogger.infoFormat("Created {0} mappings.",mappedConnectors.size())
}
}
}
}
Listing 4.160: Tries to auto-map all unconnected ports and evaluate matches
© 2016, Vector Informatik GmbH
126 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.dom.runtimesys.api.assistant.connection.ISourceComponentPort
import com.vector.cfg.dom.runtimesys.api.assistant.connection.ITargetComponentPort
scriptTask("automap1ToN", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
// select single delegation port
delegation()
name "rDelegationSRPort1"
} autoMapTo {
selectTargetPorts {
// select a collection of target ports (names start with "rSRPort")
name ~"rSRPort.*"
}
evaluateMatches {
ISourceComponentPort sourcePort,
ITargetComponentPort optionalMatchedTargetPort,
List<ITargetComponentPort> potentialTargetPorts ->
// return all potentialTargetPorts for 1:n connections, not only the
one matched best
potentialTargetPorts
}
}
scriptLogger.infoFormat("Created {0} mappings.",mappedConnectors.size())
}
}
}
}
Listing 4.161: Auto-map a component port and realize 1:n connection by using evaluate matches
forceConnectionWhen1To1() allows to force a mapping even the usual auto-mapping rules will
not match. Precondition is that the collections of source component ports and target component
ports only contain one component port each. Otherwise no mapping is done.
© 2016, Vector Informatik GmbH
127 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("autoMapTwoNonMatchingPorts", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def mappedConnectors =
selectComponentPorts {
// select a single source component port
name "prNVPort1"
component "NvApp1"
} autoMapTo {
selectTargetPorts {
// select a single target component port
name "rSRPort2"
component "App2"
}
// force the connection even names do not match at all
forceConnectionWhen1To1()
}
scriptLogger.infoFormat("Created {0} mappings.",mappedConnectors.size())
}
}
}
}
Listing 4.162: Create mapping between two ports which names do not match.
4.10.3.2 Data MappingThe data mapping use case allows to connect signal instances and data elements/operations in
a similar way the data mapping assistant does.
Communication ElementA data element or an operations to be data-mapped is represented
by an ICommunicationElement. A data element is represented by the subtype IDataCommuni-
cationElement, an operation is represented by the subtype IOperationCommunicationEle-
ment. A communication element contains the full context information (component prototype,
port prototype, data type hierarchy) necessary for data mapping.
Signal InstanceThe system signals and system signal groups to be data-mapped are repre-
sented by a signal instance (IAbstractSignalInstance). ISignalInstance represents a sys-
tem signal, ISignalGroupInstance represents a system signal group. ’Signal instance’ means
that the system signal or system signal group is at least referenced by one ISignal or ISig-
nalGroup. System signals or system signal groups which are not referenced by an ISignal or
ISignalGroup are not represented as signal instance and so are not available for data map-
ping.
The entry point for data mapping is either to select a collection of signal instances and auto-map
them to the possible target communication elements or vice versa by applying the matching
rules of the data mapping assistant.
Mapping signal instancesselectSignalInstances(Closure) allows the selection of IAb-
stractSignalInstances using predicates.
Per default the predicates are combined via logical AND. To realize other combinations, use
the ’or’,’not’ and ’and’ predicates.
© 2016, Vector Informatik GmbH
128 of
207
Chapter 4.AutomationInterface API ReferenceSignal Instance Predicates• unmapped() matches signal instances which are not data-mapped.
• mapped() matches signal instances which are data-mapped.
• signalGroup() matches signal instances which are a signal group instance.
• groupSignal() matches signal instances which are a group signal.
• transformed() matches signal instances which are transformation signals.
• tx() matches signal instances whose direction is compatible to EDirection.Tx.
• rx() matches signal instances whose direction is compatible to EDirection.Rx.
• name(String) matches signal instances with the given name.
• name(Pattern) matches signal instances with the given name pattern.
• asrPath(String) matches signal instances with the given autosar path.
• asrPath(Pattern) matches signal instances with the given autosar path pattern.
• iSignal(String) matches signal instances which are referenced at least by one ISig-
nal/ISignalGroup with the given name.
• iSignal(Pattern) matches signal instances which are referenced at least by one ISig-
nal/ISignalGroup with the given name pattern.
• iSignalAsrPath(String) matches signal instances which are referenced at least by one
ISignal/ISignalGroup with the given autosar path.
• iSignalAsrPath(Pattern) matches signal instances which are referenced at least by one
ISignal/ISignalGroup with the given autosar path pattern.
• filterAdvanced(Closure) matches signal instances for which the given closure results
to true.
• and(Closure) combines the predicates inside the closure with a logical AND.
• or(Closure) combines the predicates inside the closure with a logical OR.
• not(Closure) negates the combination of predicates inside the closure.
ExamplesscriptTask("SelectAllUnmappedSignalInstances", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def signalInstances =
selectSignalInstances {
unmapped() // select all signal instances which are not yet data mapped
} getSignalInstances()
scriptLogger.infoFormat("Selected {0} signal instances.",signalInstances.size())
}
}
}
}
Listing 4.163: Select all unmapped signal instances
© 2016, Vector Informatik GmbH
129 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("SelectAllUnmappedRxOrTransformedSignalInstances", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def signalInstances =
selectSignalInstances {
// the signal instances should not be data-mapped yet
unmapped()
or { // and should either be a rx signal or a transformation signal
rx()
transformed()
}
} getSignalInstances()
scriptLogger.infoFormat("Selected {0} signal instances.",signalInstances.size())
}
}
}
}
Listing 4.164: Select all unmapped rx or transformed signal instances
import com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
scriptTask("SelectSignalInstancesUsingAdvancedFilter", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def signalInstances =
selectSignalInstances {
filterAdvanced { IAbstractSignalInstance signalInstance ->
// implement own custom filter
def mdfObject = signalInstance.getMdfObject()
// work on directly on autosar model level ...
// select signal instance only which has admin data
def select =
falsemdfObject.adminData {
select =
true}
select
}
} getSignalInstances()
scriptLogger.infoFormat("Selected {0} signal instances.",signalInstances.size())
}
}
}
}
Listing 4.165: Select signal instances using an advanced filter
Auto-MappingThe use case of auto-mapping signal instances is based on the selection of
signal instances: it offers the methods to auto-map.
autoMap() tries to auto-map the selection of IAbstractSignalInstances (ISignalInstance
or ISignalGroupInstance) according the data mapping assistant default rules. Therefore the
selection of possible target communication elements is computed and tried to match to the
selected signal instances.
Examples for autoMap()© 2016, Vector Informatik GmbH
130 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("autoDatamapAllUnmappedSignalInstances", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectSignalInstances {
unmapped()
} autoMap()
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.166: Auto data map all unmapped signal instances
autoMapTo(Closure) tries to auto-map the selection of signal instances according the data
mapping assistant rules but offers more control for the auto-mapping: Inside the closure ad-
ditional predicates for narrowing down the target communication elements can be defined and
code to evaluate and change the auto-mapper results can be provided.
autoMapTo(Closure) will produce trace, info and warning logs.
To see them, activate the
’com.vector.cfg.dom.runtimesys.groovy.api.ISignalInstanceSelection’ logger with the
appropriate log level.
Control the auto-mapping in autoMapTo(Closure)selectTargetCommunicationElements(Closure) allows to define predicates to narrow down
the target communciation elements for the auto-mapping. The predicates are used to filter
the possible target communication elements which were computed from the signal instance
selection.
evaluateMatches(Closure) allows to evaluate and change the results of the auto-mapping. It
corresponds to the confirm page of the data mapping assistant.
For each signal instance the provided closure is called: Parameters are the signal instance,
the optional matched target communication element (or null), and a list of all potential tar-
get communication elements (respecting the selectTargetCommunicationElements(Closure)
predicates). The return value must be a communication element or null.
© 2016, Vector Informatik GmbH
131 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
scriptTask("autoDatamapAllUnmappedSignalInstancesAndEvaluate", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectSignalInstances {
unmapped()
} autoMapTo {
selectTargetCommunicationElements {
unmapped()
}
evaluateMatches {
IAbstractSignalInstance signal,
ICommunicationElement optionalMatchedComElement,
List<ICommunicationElement> potentialComElements ->
// evaluate
optionalMatchedComElement
}
}
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.167: Auto data map all unmapped signal instances to unmapped communication
elements and evaluate
Nested Array of PrimitivesexpandNestedArraysOfPrimitive(boolean) allows to control
the expansion of nested arrays of primitive globally. Per default, arrays are fully expanded
(allowing to data map each array element). By setting the value to ’false’, all nested arrays of
primitive are not expanded and can be directly data-mapped to a signal.
© 2016, Vector Informatik GmbH
132 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
scriptTask("autoDatamapAllSignalInstancesAndDoNotExpandNestedArrayElements", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectSignalInstances {
} autoMapTo {
// do not expand nested array elements
expandNestedArraysOfPrimitive
falseevaluateMatches {
IAbstractSignalInstance signal,
ICommunicationElement optionalMatchedComElement,
List<ICommunicationElement> potentialComElements ->
// perform manual mapping to a signal group
if (signal.getName().equals("elemB_c255f5e38fd8b21d")) {
for (
final ICommunicationElement comElement :
potentialComElements) {
if (comElement.getFullyQualifiedName().equals("App2.
rSRPort1.Element_2")) {
return comElement
}
}
}
// now check: for the group signal the the record element
representing an array is not expanded
if (signal.getName().equals("fieldA_f1d3783e235e88d3")) {
// group signal
for (
final ICommunicationElement comElement :
potentialComElements) {
if (comElement.getFullyQualifiedName().equals("App2.
rSRPort1.Element_2.RecordElement")) {
// do some direct mapping here
}
}
}
optionalMatchedComElement
}
}
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.168: Auto data map all signal instances and do not expand nested array elements
expandNestedArraysOfPrimitive(String,boolean) allows to control the expansion of nested
arrays of primitive for single nested arrays. Per default, the expandNestedArraysOfPrimi-
tive(boolean) applies. For the given fully qualified communication element name, the global
setting can be overridden.
© 2016, Vector Informatik GmbH
133 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
scriptTask("autoDatamapAllSignalInstancesAndDoExpandSpecificNestedArrayElement", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectSignalInstances {
} autoMapTo {
// do not expand nested array elements
expandNestedArraysOfPrimitive
falseexpandNestedArraysOfPrimitive( "App2.rSRPort1.Element_2.RecordElement",
true)
evaluateMatches {
IAbstractSignalInstance signal,
ICommunicationElement optionalMatchedComElement,
List<ICommunicationElement> potentialComElements ->
// perform manual mapping to a signal group
if (signal.getName().equals("elemB_c255f5e38fd8b21d")) {
for (
final ICommunicationElement comElement :
potentialComElements) {
if (comElement.getFullyQualifiedName().equals("App2.
rSRPort1.Element_2")) {
return comElement
}
}
}
// now check: for the group signal the the record element
representing an array is expanded:
// the single array elements can be mapped
if (signal.getName().equals("fieldA_f1d3783e235e88d3")) {
// group signal
for (
final ICommunicationElement comElement :
potentialComElements) {
if (comElement.getFullyQualifiedName().equals("App2.
rSRPort1.Element_2.RecordElement[0]")) {
// do some direct mapping to array element here
}
}
}
optionalMatchedComElement
}
}
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.169: Auto data map all signal instances and expand specific nested array element
Mapping communication elementsselectCommunicationElements(Closure) allows the se-
lection of ICommunicationElements using predicates.
Per default the predicates are combined via logical AND. To realize other combinations, use
the ’or’,’not’ and ’and’ predicates.
Communication Element Predicates© 2016, Vector Informatik GmbH
134 of
207
Chapter 4.AutomationInterface API Reference• unconnected() matches communication elements whose component port is unconnected.
• connected() matches communication elements whose component port is connected.
• senderReceiver() matches communication elements whose port has a sender/receiver
port interface.
• clientServer() matches communication elements whose port has a client/server port
interface.
• provided() matches communication elements whose port is a provided port (p-port).
• required() matches communication elements whose port is a required port (r-port).
• delegation() matches communication elements whose port is delegation port.
• unmapped() matches communication elements whose are not data-mapped.
• mapped() matches communication elements whose are data-mapped.
• name(String) matches communication elements with the given data element or operation
name.
• name(Pattern) matches communication elements with the given data element or opera-
tion name pattern.
• asrPath(String) matches communication elements with the given data element or op-
eration autosar path.
• asrPath(Pattern) matches communication elements with the given data element or op-
eration autosar path pattern.
• component(String) matches communication elements with the given component name.
• component(Pattern) matches communication elements with the given component name
pattern.
• componentAsrPath(String) matches communication elements with the given component
name autosar path.
• componentAsrPath(Pattern) matches communication elements with the given compo-
nent name autosar path pattern.
• port(String) matches communication elements with the given component port name.
• port(Pattern) matches communication elements with the given component port name
pattern.
• portAsrPath(String) matches communication elements with the given component port
autosar path.
• portAsrPath(Pattern) matches communication elements with the given component port
autosar path pattern.
• filterAdvanced(Closure) Add a custom predicated which matches communication ele-
ments for which the given closure results to true.
• and(Closure) combines the predicates inside the closure with a logical AND.
• or(Closure) combines the predicates inside the closure with a logical OR.
• not(Closure) negates the combination of predicates inside the closure.
© 2016, Vector Informatik GmbH
135 of
207
Chapter 4.AutomationInterface API ReferenceExamplesscriptTask("SelectAllUnmappedDelPortComElements", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def comElements =
selectCommunicationElements {
// select all unmapped delegation communication elements
delegation()
unmapped()
} getCommunicationElements()
scriptLogger.infoFormat("Selected {0} communication elements.",comElements.size())
}
}
}
}
Listing 4.170: Select all unmapped delegation port communication elements
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
import com.vector.cfg.model.sysdesc.api.com.IDataCommunicationElement
scriptTask("SelectComElementsUsingAdvancedFilter", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def comElements =
selectCommunicationElements {
// advanced filter:
// only select communication elements
// which represent data elements of a specific data type
filterAdvanced { ICommunicationElement comElement ->
if (comElement
instanceof IDataCommunicationElement) {
def mdfDataElement = comElement.getDataElementOrOperationMdfObject()
// check directly on autosar model level
return mdfDataElement.type.refTarget.name.equals("myCustomDataType")
}
false}
} getCommunicationElements()
scriptLogger.infoFormat("Selected {0} communication elements.",comElements.size())
}
}
}
}
Listing 4.171: Select communication elements using an advanced filter
autoMap() tries to auto-map the selection of ICommunicationElements (IDataCommunicationElement
or IOperationCommunicationElement) according the data mapping assistant default rules.
Therefore the selection of possible target signal instances is computed and tried to match to
the selected communciation elements.
Examples for autoMap()© 2016, Vector Informatik GmbH
136 of
207
Chapter 4.AutomationInterface API ReferencescriptTask("autoDatamapAllUnmappedSRDelPortComElements", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectCommunicationElements {
// select all unmapped sender/receiver delegation ports
delegation()
unmapped()
senderReceiver();
} autoMap()
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.172: Auto data map all unmapped sender/receiver delegation port communication
elements
autoMapTo(Closure) tries to auto-map the selection of communciation elements according the
data mapping assistant rules but offers more control for the auto-mapping: Inside the closure
additional predicates for narrowing down the target signal instances can be defined and code
to evaluate and change the auto-mapper results can be provided.
autoMapTo(Closure) will produce trace, info and warning logs.
To see them, activate the
’com.vector.cfg.dom.runtimesys.groovy.api.ICommunicationElementSelection’ logger with
the appropriate log level.
Control the auto-mapping in autoMapTo(Closure)selectTargetSignalInstances(Closure) allows to define predicates to narrow down the tar-
get signal instances for the auto-mapping. The predicates are used to filter the possible target
signal instances which were computed from the communication element selection.
evaluateMatches(Closure) allows to evaluate and change the results of the auto-mapping. It
corresponds to the confirm page of the data mapping assistant.
For each communication element the provided closure is called: Parameters are the communi-
cation element, the optional matched target signal instance (or null), and a list of all potential
target signal instances (respecting the selectTargetSignalInstances(Closure) predicates).
The return value must be a signal instance or null.
© 2016, Vector Informatik GmbH
137 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
scriptTask("autoDatamapAllUnmappedComElementsAndEvaluate", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectCommunicationElements {
unmapped() // only unmapped communication elements
} autoMapTo {
selectTargetSignalInstances {
// only map to unmapped rx signal instances
unmapped()
rx()
}
evaluateMatches {
ICommunicationElement communicationElement,
IAbstractSignalInstance optionalMatchedSignalInstance,
List<IAbstractSignalInstance> potentialSignalinstances ->
// evaluate the match here
if (optionalMatchedSignalInstance !=
null) {
def mdfSystemSignal = optionalMatchedSignalInstance.getMdfObject()
;
// check more specific ...
}
optionalMatchedSignalInstance
}
}
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.173: Auto data map all unmapped communication elements to unmapped rx signal
instances and evaluate
Nested Array of PrimitivesexpandNestedArraysOfPrimitive(boolean) allows to control
the expansion of nested arrays of primitive globally. Per default, arrays are fully expanded
(allowing to data map each array element). By setting the value to ’false’, all nested arrays of
primitive are not expanded and can be directly data-mapped to a signal.
© 2016, Vector Informatik GmbH
138 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
import com.vector.cfg.model.sysdesc.api.com.ISignalGroupInstance
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
scriptTask("autoDatamapDoNotExpandNestedArrayElements", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectCommunicationElements {
} autoMapTo {
expandNestedArraysOfPrimitive
false // do not expand nested arrays of primitive
evaluateMatches {
ICommunicationElement communicationElement,
IAbstractSignalInstance optionalMatchedSignalInstance,
List<IAbstractSignalInstance> potentialSignalInstances ->
if ("App2.rSRPort1.Element_2".equals(communicationElement.
getFullyQualifiedName())) {
// manual matching: map to first signal group
for (IAbstractSignalInstance potentialSignal: potentialSignalInstances) {
if (potentialSignal
instanceof ISignalGroupInstance) {
return potentialSignal
}
}
}
if ("App2.rSRPort1.Element_2.RecordElement".equals(communicationElement.
getFullyQualifiedName())) {
// now the RecordElement which represents an array is directly offered to
map
// ....
}
optionalMatchedSignalInstance
}
}
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.174: Autodatamap and do not expand nested array elements
expandNestedArraysOfPrimitive(String,boolean) allows to control the expansion of nested
arrays of primitive for single nested arrays. Per default, the expandNestedArraysOfPrimi-
tive(boolean) applies. For the given fully qualified communication element name, the global
setting can be overridden.
The fully qualified communication element name is e.g. determinable when using the data
mapping assistant, performing an arbitrary signal group mapping of the root data element,
and using the right-mouse menu its ’Copy fully qualified name’ action on the nested array
element.
© 2016, Vector Informatik GmbH
139 of
207
Chapter 4.AutomationInterface API Referenceimport com.vector.cfg.model.sysdesc.api.com.IAbstractSignalInstance
import com.vector.cfg.model.sysdesc.api.com.ISignalGroupInstance
import com.vector.cfg.model.sysdesc.api.com.ICommunicationElement
scriptTask("autoDatamapDoExpandSpecificNestedArrayElement", DV_PROJECT){
code {
transaction {
domain.runtimeSystem {
def dataMappings =
selectCommunicationElements {
} autoMapTo {
// do not generally expand nested arrays of primitive
expandNestedArraysOfPrimitive
false// but expand the following specific record element
expandNestedArraysOfPrimitive("App2.rSRPort1.Element_2.RecordElement",
true)
evaluateMatches {
ICommunicationElement communicationElement,
IAbstractSignalInstance optionalMatchedSignalInstance,
List<IAbstractSignalInstance> potentialSignalInstances ->
if ("App2.rSRPort1.Element_2".equals(communicationElement.
getFullyQualifiedName())) {
// manual matching: map to first signal group
for (IAbstractSignalInstance potentialSignal: potentialSignalInstances
) {
if (potentialSignal
instanceof ISignalGroupInstance) {
return potentialSignal
}
}
}
if ("App2.rSRPort1.Element_2.RecordElement[0]".equals(communicationElement
.getFullyQualifiedName())) {
// the RecordElement (representing an array of primitive) is expanded
to map the single array elements
// ....
}
optionalMatchedSignalInstance
}
}
scriptLogger.infoFormat("Created {0} data mappings.",dataMappings.size())
}
}
}
}
Listing 4.175: Autodatamap and do expand a specific nested array element
© 2016, Vector Informatik GmbH
140 of
207
Chapter 4.AutomationInterface API Reference4.11 PersistencyThe persistency API provides methods which allow to import and export model data from
and to files. The files are normally in the AUTOSAR .arxml format.
4.11.1 Model ExportThe modelExporty allows to export MDF model data into .arxml files.
To access the export functionality use one of the getModelExport() or modelExport(Closure)
methods.
// You can access the API in every active project
def exportApi = persistency.modelExport
//Or you use a closure
persistency.modelExport {
}
Listing 4.176: Accessing the model export persistency API
4.11.1.1 Export ActiveEcucThe method exportActiveEcuc(Object) exports the whole ActiveEcuC configuration into a
single file of type Path.
scriptTask('taskName') {
code {
def tempExportFolder = paths.resolveTempPath(".")
def resultFile = persistency.modelExport.exportActiveEcuc(tempExportFolder)
}
}
Listing 4.177: Export the ActiveEcuc to a file
4.11.1.2 Export Post-build selectable VariantsThe method exportPostbuildVariants(Object) exports the Post-build variants info. This
will export the ActiveEcuc and miscellaneous data. The ActiveEcuC is exported into one file
(even for split DPA-projects) per variant into <project-name>.<variant-name>.ecuc.arxml.
Miscellaneous data is exported into one file per variant. The files contain all data of the project
except:
• ModuleConfigurations, ModuleDefinitions
• BswImplementations, EcuConfigurations
• Variant information like EvaluatedVariantSet
The created files are <project-name>.<variant-name>.misc.arxml.
The method returns a List<Path> of exported files.
© 2016, Vector Informatik GmbH
141 of
207
Chapter 4.AutomationInterface API ReferencescriptTask('taskName') {
code {
persistency.modelExport {
def tempExportFolder = paths.resolveTempPath(".")
def fileList = exportPostbuildVariants(tempExportFolder)
}
}
}
Listing 4.178: Export a Post-build selectable project as variant files
4.11.1.3 Advanced ExportThe advanced export use case provides access to multiple IModelExporter for special export
use cases like export the system description for the RTE.
Normally you would retrieve an IModelExporter by its ID via getExporter(String). On
this exporter you can call IModelExporter.export(Object) to export the model, or IMod-
elExporter.exportAsPostbuildVariants(Object) to export the model as variant divided
data.
You can retrieve a list of supported exporters from getAvailableExporter(). The list can
differ from data loaded in your project.
scriptTask('taskName') {
code {
def tempExportFolder = paths.resolveTempPath(".")
def fileList
//Switch to the persistency export API
persistency.modelExport{
// The getAvailableExporter() returns all exporters in the system
def exporterList = getAvailableExporter()
// Select an exporter by its ID
def exporterOpt = getExporter("activeEcuc")
exporterOpt.ifPresent { exporter ->
// Export into folder, when exporter exists
fileList = exporter.export(tempExportFolder)
}
}
}
}
Listing 4.179: Export the project with an exporter
4.11.2 Model ImportThe modelImport allows to import MDF model data from .arxml files.
To access the import functionality use one of the getModelImport() or modelImport(Closure)
methods.
Currently no import API is provided. Please inform Vector, if you need an import
API.© 2016, Vector Informatik GmbH
142 of
207
Chapter 4.AutomationInterface API Reference// You can access the API in every active project
def importApi = persistency.modelImport
//Or you use a closure
persistency.modelImport {
}
Listing 4.180: Accessing the model import persistency API
© 2016, Vector Informatik GmbH
143 of
207
Chapter 4.AutomationInterface API Reference4.12 Utilities4.12.1 ConstraintsConstraints provides general purpose constraints for checking given parameter values through-
out the automation interface. These constraints are referenced from the AutomationInterface
documentation wherever they apply. The AutomationInterface takes a fail fast approach ver-
ifying provided parameter values as early as possible and throwing appropriate exceptions if
values violate the corresponding constraints.
The following constraints are provided:
IS_NOT_NULLEnsures that the given Object is not null.
IS_NON_EMPTY_STRINGEnsures that the given String is not empty.
IS_VALID_FILE_NAMEEnsures that the given String can be used as a file name.
IS_VALID_PROJECT_NAMEEnsures that the given String can be used as a name for a
project. A valid project name starts with a letter [a-zA-Z] contains otherwise only characters
matching [a-zA-Z0-9_] and is at most 128 characters long.
IS_NON_EMPTY_ITERABLEEnsures that the given Iterable is not empty.
IS_VALID_FILE_NAMEEnsures that the given String can be used as a file name.
IS_VALID_AUTOSAR_SHORT_NAMEEnsures that the given String conforms to the
syntactical requirements for AUTOSAR short names.
IS_VALID_AUTOSAR_SHORT_NAME_PATHEnsures that the given String conforms
to the syntactical requirements for AUTOSAR short name paths.
IS_WRITABLEEnsures that the file or folder represented by the given Path exists and can
be written to.
IS_READABLEEnsures that the file or folder represented by the given Path exists and can
be read.
IS_EXISTING_FOLDEREnsures that the given Path points to an existing folder.
IS_EXISTING_FILEEnsures that the given Path points to an existing file.
© 2016, Vector Informatik GmbH
144 of
207
Chapter 4.AutomationInterface API ReferenceIS_CREATABLE_FOLDEREnsures that the given Path either points to an existing folder
which can be written to or points to a location at which a corresponding folder could be
created.
IS_DCF_FILEEnsures that the given Path points to a DaVinci Developer workspace file
(.dcf file).
IS_DPA_FILEEnsures that the given Path points to a DaVinci project file (.dpa file).
IS_ARXML_FILEEnsures that the given Path points to an .arxml file.
IS_SYSTEM_DESCRIPTION_FILEEnsures that the given Path points to a system de-
scription input file (.arxml, .dbc, .ldf, .xml or .vsde file).
IS_COMPATIBLE_DA_VINCI_DEV_EXECUTABLEEnsures that the given Path points
to a compatible DaVinci Developer executable (DaVinciDEV.exe).
4.12.2 ConvertersGeneral purpose converters (java.util.Functions) for performing value conversions through-
out the automation interface are provided. These converters are referenced from the Automa-
tionInterface documentation wherever they apply. The AutomationInterface is typed strongly.
In some cases, however, e.g. when specifying file locations, it is desirable to allow for a range
of possibly parameter types. This is achieved by accepting parameters of type Object and
converting the given parameters to the desired type.
The following converters are provided:
ScriptConverters.TO_PATHAttempts to convert arbitrary Objects to Paths using
IAutomationPathsApi.resolvePath(Object)
4.4.3.2 on page 34.ScriptConverters.TO_SCRIPT_PATHAttempts to convert arbitrary Objects to Paths us-
ing IAutomationPathsApi.resolveScriptPath(Object)
4.4.3.3 on page 35.ScriptConverters.TO_VERSIONAttempts to convert arbitrary Objects to IVersions. The
following conversions are implemented:
• For null or IVersion arguments the given argument is returned. No conversion is applied.
• Strings are converted using Version.valueOf(String).
• Numbers are converted by converting the int obtained from Number.intValue() using
Version.valueOf(int).
• All other Objects are converted by converting the String obtained from Object.toString().
For thrown Exceptions see the used functions described above.
© 2016, Vector Informatik GmbH
145 of
207
Chapter 4.AutomationInterface API ReferenceModelConverters.TO_MDFAttempts to convert arbitrary Objects to MDFObjects.
The
following conversions are implemented:
• For null or MDFObject arguments the given argument is returned. No conversion is
applied.
• IHasModelObjects are converted using their getMdfModelElement() method.
• IViewedModelObjects are converted using their getMdfObject() method.
• For all other Objects ClassCastExceptions are thrown.
For thrown Exceptions see the used functions described above.
© 2016, Vector Informatik GmbH
146 of
207
Chapter 4.AutomationInterface API Reference4.13 Advanced TopicsThis chapter contains advanced use cases and classes for special tasks. For a normal script these
items are not relevant.
4.13.1 Java DevelopmentIt is also possible to write automation scripts in plain Java code, but this is not recommended.
There are some items in the API, which need a different usage in Java code.
This chapter describes the differences in the Automation API when used from Java code.
4.13.1.1 Script Task Creation in Java CodeJava code could not use the Groovy syntax to provide script tasks. So another way is needed
for this. The IScriptFactory interface provides the entry point that Java code could provide
script tasks. The createScript(IScriptCreationApi) method is called when the script is
loaded.
This interface is
not necessary for Groovy clients.
public class MyScriptFactoryAsJavaCode
implements IScriptFactory {
@Override
public void createScript(IScriptCreationApi creation) {
creation.scriptTask("TaskFromFactory", IScriptTaskTypeApi.DV_APPLICATION,
(taskBuilder) -> {
taskBuilder.code(
(scriptExecutionContext, taskArgs) -> {
// Your script task code here
return null;
});
});
creation.scriptTask("Task2", IScriptTaskTypeApi.DV_PROJECT,
(taskBuilder) -> {
taskBuilder.code(
(scriptExecutionContext, taskArgs) -> {
// Your script task code for Task2 here
return null;
});
});
}
}
Listing 4.181: Java code usage of the IScriptFactory to contribute script tasks
You should try to use Groovy when possible, because it is more concise than the Java code,
without any difference at script task creation and execution.
4.13.1.2 Java Code accessing Groovy APIMost of the Automation API is usable from both languages Java and Groovy, but some methods
are written for Groovy clients. To use it from Java you have to write some glue code.
Differences are:
© 2016, Vector Informatik GmbH
147 of
207
Chapter 4.AutomationInterface API Reference• Accessing Properties
• Using API entry points.
• Creating Closures
Accessing PropertiesProperties are not supported by Java so you have to use the getter/setter
methods instead.
API Entry PointsMost of the Automation API is added to the object by so called Dy-
namicObjects.
This is not available in Java, so you have to call IScriptExecutionCon-
text.getInstance(Class) instead.
So if you want to access The IWorkflowApi you have
to write:
//Java code:
IScriptExecutionContext scriptCtx = ...;
IWorkflowApi workflow = scriptCtx.getInstance(IWorkflowApiEntryPoint.
class).getWorkflow()
//Instead of Groovy code:
workflow{
}
Listing 4.182: Accessing WorkflowAPI in Java code
Creating Closure instances from Java lambdasThe class Closures provides API to create
Closure instances from Java FunctionalInterfaces.
The from() methods could be used to call Groovy API from Java classes, which only accepts
Closure instances.
Sample:
Closure<?> c = Closures.from((param) -> {
// Java lambda
});
Listing 4.183: Java Closure creation sample
Creating Closure Instances from Java MethodsYou could also create arbitrary Closures
from any Java method with the class MethodClosure. This is describe in:
http://melix.github.io/blog/2010/04/19/coding_a_groovy_closure_in.html14.13.1.3 Java Code in dvgroovy ScriptsIt is not possible to write Java classes when using the .dvgroovy script file. You have to create
an automation script project, see chapter
7 on page 186.1Last accessed 2016-05-24
© 2016, Vector Informatik GmbH
148 of
207
Chapter 4.AutomationInterface API Reference4.13.2 Unit testing APIThe Automation Interface provides an connector to execute unit tests as script task. This is
helpful, if you want to write tests for:
• Generators
• Validations
• Workflow rules
• ...
Normally a script task executes it’s code block, but the unit test task will execute all contained
unit tests instead.
4.13.2.1 JUnit4 IntegrationThe AutomationInterface can execute JUnit 4 test cases and test suites.
Execution of JUnit Test ClassesA simple unit test class will look like:
import org.junit.Test;
public class ScriptJUnitTest {
@Test
public void testYourLogic() {
// Write your test code here
}
Listing 4.184: Run all JUnit tests from one class
You can access the Automation API with the ScriptApi class. See chapter
4.4.8 on page 43
for details.
Execution of multiple Tests with JUnit SuiteTo execute multiple tests you have to group
the tests into a test suite.
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.
class)
@SuiteClasses({
// Two test classes
ScriptJUnitTest.
class,
ScriptSpockTest.
class,
// Another JUnit suite
InnerSuiteScriptJUnitTests.
class,
})
public class AllMyScriptJUnitTests {
Listing 4.185: Run all JUnit tests using a Suite
You can also group test suites in test suites and so on.
© 2016, Vector Informatik GmbH
149 of
207
Chapter 4.AutomationInterface API Reference4.13.2.2 Execution of Spock TestsThe AutomationInterface can also execute Spock tests. See:
• Homepage:
https://github.com/spockframework/spock2• Documentation:
http://spockframework.github.io/spock/docs/1.0/index.html3It is also possible to group multiple Spock test into a JUnit Test Suite.
Usage sample:
import spock.lang.Specification
class ScriptSpockTest
extends Specification {
def "Simple Spock test"(){
when:
//Add your test logic here
def myExpectedString = "Expected"
then:
myExpectedString == "Expected"
}
}
Listing 4.186: Run unit test with the Spock framework
You can access the Automation API with the ScriptApi class. See chapter
4.4.8 on page 43
for details.
You have to add a Spock dependency in your build.gradle file:
dependencies {
compileDvCfg "org.spockframework:spock-core:1.0-groovy-2.4"
}
Note: after the change you have to call Gradle to update the IntelliJ IDEA project.
gradlew idea
4.13.2.3 Registration of Unit Tests in ScriptsA test or the root suite class has to be registered in a script to be executable. The first argument
is the taskName for the UnitTests the second is the class of the tests.
// You can add a unit test inside a script
unitTestTask("MyUnitTest", AllMyScriptJUnitTests.
class)
Listing 4.187: Add a UnitTest task with name MyUnitTest
It is also possible to reference the test/suite class directly as a script inside of a script project.
So you don’t have to create a script as a wrapper.
2Last accessed 2016-05-24
3Last accessed 2016-05-24
© 2016, Vector Informatik GmbH
150 of
207
Chapter 4.AutomationInterface API Referenceproject.ext.automationClasses = [
"sample.MyScript",
"sample.MyUnitTestSuite", // This is a test suite
// Add here your test or suite class with full qualified name
]
Listing 4.188: The projectConfig.gradle file content for unit tests
© 2016, Vector Informatik GmbH
151 of
207
5 Data models in detailThis chapter describes several details and concepts of the involved data models. Be aware that
the information here is focused on the Java API. In most cases it is more convenient using the
Groovy APIs described in
4.6 on page 62. So, whenever possible use the Groovy API and read
this chapter only to get background information when required.
5.1 MDF model - the raw AUTOSAR dataThe MDF model is being used to store the AUTOSAR model loaded from several ARXML
files. It consists of Java interfaces and classes which are generated from the AUTOSAR meta-
model.
5.1.1 NamingThe MDF interfaces have the prefix MI followed by the AUTOSAR meta-model name of the class
they represent. For example, the MDF interface related to the meta-model class ARPackage
(AUTOSAR package in the top-level structure of the meta-model) is MIARPackage.
5.1.2 The models inheritance hiearchyThe MDF model therefore implements (nearly) the same inheritance hierarchy and associations
as defined by the AUTOSAR model. These interfaces provide access to the data stored in the
model.
See figure
5.1 on the next page shows the (simplified) inheritance hierarchy of the ECUC
container type MIContainer. What we can see in this example:
• A container is an MIIdentifiable which again is a MIReferrable. The MIReferrable
is the type which holds the shortname (getName()). All types which inherit from the
MIReferrable have a shortname (MIARPackage, MIModuleConfiguration, ...)
• A container is also a MIHasContainer. This is an artificial base class (not part of the
AUTOSAR meta-model) which provides all features of types which have sub-containers.
The MIModuleConfiguration therefore has the same base type
• A container also inherits from MIHasDefinition. This is an artificial base class (not
part of the AUTOSAR meta-model) which provides all features of types which have an
AUTOSAR definition. The MIModuleConfiguration and MIParameterValue therefore
has the same base type
• All MIIdentifiables can hold ADMIN-DATA and ANNOTATIONs
• All MDF objects in the AUTOSAR model tree inherit from MIObject which is again an
MIObject
5.1.2.1 MIObject and MDFObjectThe MIObject is the base interface for all AUTOSAR model objects in the DaVinci Configurator
data model. It extends MDFObject which is the base interface of all model objects. Your
© 2016, Vector Informatik GmbH
152 of
207

Chapter 5.Data models in detailFigure 5.1: ECUC container type inheritance
client code shall always use MIObject, when AUTOSAR model objects are used, instead of
MDFObject.
The figure
5.2 on the following page describes the class hierarchy of the MIObject.
5.1.3 The models containment treeThe root node of the AUTOSAR model is MIAUTOSAR. Starting at this object the complete model
tree can be traversed. MIAUTOSAR.getSubPackage() for example returns a list of MIARPackage
objects which again have child objects and so on.
Figure
5.3 on the next page shows a simple example of an MDF object containment hierarchy.
This example contains two AUTOSAR packages with module configurations below.
© 2016, Vector Informatik GmbH
153 of
207


Chapter 5.Data models in detailFigure 5.2: MIObject class hierarchy and base interfaces
Figure 5.3: Autosar package containment
© 2016, Vector Informatik GmbH
154 of
207
Chapter 5.Data models in detailIn general, objects which have child objects provide methods to retrieve them.
• MIAUTOSAR.getSubPackage() for example returns a list of child packages
• MIContainer.getSubContainer() returns the list of sub-containers and
MIContainer.getParameter() all parameter-values and reference-values of a container
5.1.4 The ECUC modelThe interfaces and classes which represent the ECUC model don’t exactly follow the AUTOSAR
meta-model naming. because they are designed to store AUTOSAR 3 and AUTOSAR 4 models
as well.
Affected interfaces are:
• MIModuleConfiguration and its child objects (containers, parameters, . . . )
• MIModuleDef and its child objects (containers definitions, parameter definitions, . . . )
The ECUC model also unifies the handling of parameter- and reference-values. Both, parameter-
values and reference-values of a container, are represented as MIParameterValue in the MDF
model.
5.1.5 Order of child objectsChild object lists in the MDF model have the same order as the data specified in the ARXML
files. So, loading model objects from AXRML doesn’t change the order.
5.1.6 AUTOSAR referencesAll AUTOSAR reference objects in the MDF model have the base interface MIARRef.
Figure
5.4 on the following page shows this type hierarchy for the definition reference of an
ECUC container.
In ARXML, such a reference can be specified as:
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">
/MIRCOSAR/Com/ComGeneral
</DEFINITION-REF>
• MIARRef.getValue() returns the AUTOSAR path of the object, the reference points to
(as specified in the ARXML file). In the example above "/MIRCOSAR/Com/ComGeneral"
would be this value
• MIContainerDefARRef.getRefTarget() on the other hand returns the referenced MDF
object if it exists. This method is located in a specific, typesafe (according to the type it
points to) reference interface which extends MIARRef. So, if an object with the AUTOSAR
path "/MIRCOSAR/Com/ComGeneral" exists in the model, this method will return it
© 2016, Vector Informatik GmbH
155 of
207

Chapter 5.Data models in detailFigure 5.4: The ECUC container definition reference
5.1.7 Model changes5.1.7.1 TransactionsThe MDF model provides model change transactions for grouping several model changes into
one atomic change.
A solving action, for example, is being executed within a transaction for being able to change
model content. Validation and generator developers don’t need to care for transactions. The
tools framework mechanisms guarantee that their code is being executed in a transaction were
required.
The tool guarantees that model changes cannot be executed outside of transactions. So, for
example, during validation of model content the model cannot be changed. A model change
here would lead to a runtime exception.
5.1.7.2 Undo/redoOn basis of model change transactions, MDF provides means to undo and redo all changes
made within one transaction. The tools GUI allows the user to execute undo/redo on this
granularity.
5.1.7.3 Event handlingMDF also supports model change events. All changes made in the model are reported by this
asynchronous event mechanism. Validations, for example, detect this way which areas of the
model need to be re-validated. The GUI listens to events to update its editors and views when
model content changes.
© 2016, Vector Informatik GmbH
156 of
207
Chapter 5.Data models in detail5.1.7.4 Deleting model objectsModel objects must be deleted by a special service API. In Java code that’s:
IModelOperationsPublished.deleteFromModel(MDFObject).
Deleting an object means:
• All associations of the object are deleted. The connection to its parent object, for example,
is being deleted which means that the object is not a member of the model tree anymore
• The object itself is being deleted. In fact, it is not really deleted (and garbage collected)
as a Java object but only marked as removed. Undo of the transaction, which deleted this
object, removes this marker and restores the deleted associations
5.1.7.5 Access to deleted objectsAll subsequent access to content of deleted objects throws a runtime exception. Reading the
shortname of an MIContainer, for example.
5.1.7.6 Set-methodsModel interfaces provide get-methods to read model content. MDF also offers set-methods for
fields and child objects with multiplicity 0..1 or 1..1.
These set-methods can be used to change model content.
• MIARRef.getValue() for example returns a references AUTOSAR path
• MIARRef.setValue(String newValue) sets a new path
5.1.7.7 Changing child list contentMDF doesn’t offer set-methods for fields and child objects with multiplicity 0..* or 1..*.
MIContainer.getSubContainer(), for example, returns the list of sub-containers but there is
no MIContainer.setSubContainer() method to change the sub-containers.
Changing child lists means changing the list itself.
• To add a new object to a child list, client code must use the lists add() method. MI-
Container.getSubContainer().add(container), for example, adds a container as ad-
ditional sub-container. This added object is being appended at the end of the list
• Removing child list objects is a side-effect of deleting this object. The delete operation
removes it from the list automatically
5.1.7.8 Change restrictionsThe tools transaction handling implements some model consistency checks to avoid model
changes which shall be avoided. Such changes are, for example:
• Creating duplicate shortnames below one parent object (e.g. two sub-containers with the
same shortname)
• Changing or deleting pre-configured parameters
© 2016, Vector Informatik GmbH
157 of
207
Chapter 5.Data models in detailWhen client code tries to change the model this way, the related model change transaction is
being canceled and the model changes are reverted (unconditional undo of the transaction). A
special case here are solving actions. When a solving action inconsistently changes the model,
only the changes made by this solving action are reverted (partial transaction undo of one
solving action execution).
5.2 Post-build selectable5.2.1 Model views5.2.1.1 What model views areAfter project load, the MDF model contains all objects found in the ARXML files. Variation
points are just data structures in the model without any special meaning in MDF.
If you want to deal with variants you must use model views. A model view filters access to the
MDF model based on the variant definition and the variation points.
There is one model view per variant. If you use this variants model view, the MDF model
filters exactly what this variant contains.
All other objects become invisible.
When your
retrieve parameters of a container for example, you’ll see only parameters contained in your
selected variant.
final boolean isVisible = ModelAccessUtil.isVisible(t.paramVariantA);
Listing 5.1: Check object visibility
5.2.1.2 The IModelViewManager project serviceThe IModelViewManager handles model visibility in general. It provides the following means:
• Get all available variants
• Execute code with visibility of a specific predefined variant only. This means your code
sees all objects contained in the specified variant. All objects which are not contained in
this variant will be invisible
• Execute code with visibility of invariant data only (see IInvariantView).
• Execute code with unfiltered model visibility. This means that your code sees all objects
unconditionally. If the project contains variant data, you see all variants together
It additionally provides detailed visibility information for single model objects:
• Get all variants, a specific object is visible in
• Find out if an object is visible in a specific variant
final List<IPredefinedVariantView> variants = viewMgr.getAllVariantViews();
Listing 5.2: Get all available variants
try (
final IModelViewExecutionContext context = viewMgr.executeWithModelView(t.variantViewA)) {
assertIsVisible(t.paramInvariant);
assertIsVisible(t.paramVariantA);
assertNotVisible(t.paramVariantB);
}
© 2016, Vector Informatik GmbH
158 of
207
Chapter 5.Data models in detailtry (
final IModelViewExecutionContext context = viewMgr.executeWithModelView(t.variantViewB)) {
assertIsVisible(t.paramInvariant);
assertNotVisible(t.paramVariantA);
assertIsVisible(t.paramVariantB);
}
try (
final IModelViewExecutionContext context = viewMgr.executeUnfiltered()) {
assertIsVisible(t.paramInvariant);
assertIsVisible(t.paramVariantA);
assertIsVisible(t.paramVariantB);
}
Listing 5.3: Execute code with variant visibility
Important remark:It is essential that the execute...() methods are used exactly as imple-
mented in the listing above. The try (...)
{...} construct is a new Java 7 feature which
guarantees that resources are closed whenever (and how ever) the try block is being left. For
details read:
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html© 2016, Vector Informatik GmbH
159 of
207
Chapter 5.Data models in detailCollection<IPredefinedVariantView> visibleVariants = viewMgr.getVisibleVariantViews(t.
paramInvariant);
assertThat(visibleVariants.size(), equalTo(2));
assertThat(visibleVariants, containsInAnyOrder(t.variantViewA, t.variantViewB));
visibleVariants = viewMgr.getVisibleVariantViews(t.paramVariantA);
assertThat(visibleVariants.size(), equalTo(1));
assertThat(visibleVariants, containsInAnyOrder(t.variantViewA));
Listing 5.4: Get all variants, a specific object is visible in
5.2.1.3 Variant siblingsVariant siblings of an MDF object are MDF object instances which represent the same object
but in other variants.
The method IModelVarianceAccessPublished.getVariantSiblings() provides access to these
sibling objects:
This method returns MDF object instances representing the same object but in all variants. The
collection returned contains the object itself including all siblings from other variants.
The calculation of siblings depends on the object-type as follows:
•
Ecuc Module Configuration:Since module configurations are never variant, this method always returns a collection
which contains the specified object only
•
Ecuc Container:For siblings of a container all of the following conditions apply:
– They have the same AUTOSAR path
– They have the same definition path (containers with the same AUTOSAR path but
different definitions may occur in variant models - but they are not variant siblings
because they differ in type)
•
Ecuc Parameter:For siblings of a parameter all of the following conditions apply:
– The parent containers have the same AUTOSAR path
– The parameter siblings have the same definition path
The parameter values are
not relevant so parameter siblings may have different values.
Multi-instance parameters are special. In this case the method returns all multi-instance
siblings of all variants.
•
System description object:For siblings of MIReferrables all of the following conditions apply:
– They have the same meta-class
– They have the same AUTOSAR path
For siblings of non-MIReferrables all of the following conditions apply:
– Their nearest MIReferrable-parents are either the same object or variant siblings
– Their containment feature paths below these nearest MIReferrable-parents is equal
© 2016, Vector Informatik GmbH
160 of
207

Chapter 5.Data models in detailSpecial use cases: When the specified object is not a member of the model tree (the object
itself or one of its parents has no parent), it also has no siblings. In this case this method
returns a collection containing the specified object only.
Remark concerning visibility: This method returns all siblings independent of the currently
visible objects. This means that the returned collection probably contains objects which are
not visible by the caller! It also means that the specified object itself doesn’t need to be visible
for the caller.
5.2.1.4 The Invariant model viewsThere are use cases which require to see the invariant model content only. One example are
generators for modules which don’t support variance at all.
There are two different invariant views currently defined:
•
Value based invariance (values
are equal in all variants):
The IInvariantValuesView contains objects were all variant siblings have the same value
and exist in all variants. One of the siblings is contained
•
Definition based invariance (values which
shall be equal in all variants):
The IInvariantEcucDefView contains objects which are not allowed to be variant ac-
cording to the BSWMD rules. One of the siblings is contained
All Invariant views derive from the same interface IInvariantView, so if you want to use an
invariant view and not specifying the exact view, you could use the IInvariantView interface.
The figure
5.5 describes the hierarchy.
Figure 5.5: Invariant views hierarchy
The InvariantValues model viewThe IInvariantValuesView contains only elements which
have
one of the following properties:
• The element and no parent has any MIVariationPoint with a post-build condition
• All variant siblings have the same value and exist in all variants. Then one of the siblings
is contained in the IInvariantValuesView
© 2016, Vector Informatik GmbH
161 of
207

Chapter 5.Data models in detailSo the semantic of the InvariantValues model view is that all values are equal in all vari-
ants.
You could retrieve an instance of IInvariantValuesView by calling IModelViewManager.
getInvariantValuesView().
IModelViewManager viewMgr =...;
IInvariantValuesView invariantView = viewMgr.getInvariantValuesView();
// Use the invariantView like any other model view
Listing 5.5: Retrieving an InvariantValues model view
ExampleThe figure
5.6 describes an example for a module with containers and the visibility
in the IInvariantValuesView.
• Container A is invisible because it is contained in variant 1 only
• Container B and C are visible because they are contained in all variants
• Parameter a is visible because it is contained in all variants with the same value
• Parameter b is invisible: It is contained in all variants but with different values
• Parameter c is invisible because it is contained in variant 3 only
Figure 5.6: Example of a model structure and the visibility of the IInvariantValuesView
SpecificationSee also the
specification for details of the IInvariantValuesView.
The Invariant EcuC definition model viewThe IInvariantEcucDefView contains the same
objects as the invariant values view but additionally excludes all objects which, by (EcuC /
BSWMD) definition, support variance. Using this view you can avoid dealing with objects which
are accidentally equal by value (in your test configurations) but potentially can be different
because they support variance.
More exact the IInvariantEcucDefView will additionally exclude elements which have the
following properties:
• If the parent module configuration specifies VARIANT-POST-BUILD-SELECTABLE as
implementation configuration variant
– All objects ( MIContainer, MINumericalValue, ...) are
excluded, which
supportvariance according to their EcuC definition. (potentially variant objects)
© 2016, Vector Informatik GmbH
162 of
207
Chapter 5.Data models in detail• If the parent module configuration doesn’t specify VARIANT-POST-BUILD-SELECTABLE
as implementation configuration variant. All contained objects
do not support variance,
so the view actually shows the same objects as the IInvariantValuesView.
The implementation configuration variant in fact overwrites the objects definition for elements
in the ModuleConfiguration.
Reasons to Use the viewThe EcucDef view guarantees that you don’t access potentially
variant data without using variant specific model views. So it allows you to improve code
quality in your generator.
When your test configuration for example contains equal values for a parameter which is po-
tentially variant you will see this parameter in the invariant values view but not in the EcucDef
view. Consequences if you access data in other module configurations: When the BSWMD file
of this other module is being changed, e.g. a parameter now supports variance, objects can
become invisible due to this change. You are forced to adapt your code then.
UsageYou could retrieve an instance of IInvariantEcucDefView by calling IModelViewMan-
ager.getInvariantEcucDefView(). And then use is as any other IModelView.
IModelViewManager viewMgr =...;
IInvariantEcucDefView invariantView = viewMgr.getInvariantEcucDefView();
// Use the invariantView like any other model view
Listing 5.6: Retrieving an InvariantEcucDefView model view
SpecificationSee also the
specification for details of the IInvariantEcucDefView.
5.2.1.5 Accessing invisible objectsWhen you switch to a model view, objects which are not contained in the related variant become
invisible. This means that access to their content leads to an InvisibleVariantObjectFea-
tureException.
To simplify handling of invisible objects, some model services provide model access even for
invisible objects in variant projects. The affected classes and interfaces are:
• ModelUtil
• ModelAccessUtil
• IReferrableAccess
• IModelAccess
• IModelCompareService
• DefRef
• AsrPath
• IEcucDefinitionAccess (all methods which deal with configuration side objects)
Only a subset of the methods in these services work with invisible objects (read the methods
JavaDoc for details). The general policy to select exactly these methods was:
© 2016, Vector Informatik GmbH
163 of
207
Chapter 5.Data models in detail• Support access to type and object identity of MDF objects (definition and AUTOSAR
path)
• Parameter value or other content related information must still be retrieved in a context
the object is visible in
• Also not contained are methods which change model content. E.g. deleting invisible
objects, set parameter values, ...
5.2.1.6 IViewedModelObjectThe IViewedModelObject is a container for one MIObject and an IModelView that was used
when viewing the MIObject.
The interface provides getter for the MIObject, and the IModelView which was active dur-
ing creation of the IViewedModelObject. So the IViewedModelObject represents a tuple of
MIObject and IModelView.
This could be used to preserve the state/tuple of a MIObject and IModelView, for later re-
trieval.
Examples:
• BswmdModel objects
• Elements for validation results, retrieved in a certain view
• Model Query API like ModelTraverser, to preserve IModelView information
Notes:
A IViewedModelObject is immutable and will not update any state. Especially not when the
visibility of the getMdfObject(), is changed after the construction of the IViewedModelOb-
ject.
It is not guaranteed, that the MIObject is visible in the creation IModelView, after the model is
changed. It is also possible to create an IViewedModelObject of a MIObject and a IModelView,
where the MIObject is invisible.
The method getCreationModelView() returns the IModelView of the IViewedModelObject,
which was active when the model object was viewed IViewedModelObject.
5.2.2 Variant specific model changesThe CFG5 data model provides an execution context which guarantees that only the selected
variant is being modified. Objects which are visible in more than one variant are cloned auto-
matically. The clones and the object which is being modified (or their parents) automatically
get a variation point with the required post-build conditions.
The following picture shows how this execution context works:
See figure
5.7 on the next page.• Before modifying the parameter, this instance is invariant. The same MDF instance is
visible in all variants
• When the client code changes the parameter value, the model automatically clones the
parameter first
© 2016, Vector Informatik GmbH
164 of
207

Chapter 5.Data models in detailFigure 5.7: Variant specific change of a parameter value
• Only the parameter instance which is visible in the currently active view is being modified.
The content of other variants stays untouched
Remark: This change mode is implicitly turned off when executing code in the IInvari-
antView or in an unfiltered context.
try (
final IModelViewExecutionContext viewContext = viewMgr.executeWithModelView(variantView))
{
try (
final IModelViewExecutionContext modeContext = viewMgr.
executeWithVariantSpecificModelChanges()) {
ma.setAsString(parameter, "Vector-Informatik");
}
}
Listing 5.7: Execute code with variant specific changes
5.2.3 Variant common model changesThe CFG5 data model provides an execution context which guarantees that model objects are
modified in all variants.
The behavior of this mode depends on the mode flag parameter as follows:
•
mode == ALL : All parameters and containers are affected
•
mode == DEFINITION_BASED : Only those parameters and containers are af-
fected which do not support variance (according to their definition in the BSWMD file
and the implementation configuration variant of their module configuration)
•
mode == OFF : Doesn’t turn on this change mode (this value is used internally only)
Remark: This method doesn’t allow to reduce the scope of this change mode. So if ALL is
already set, this method doesn’t permit to use DEFINITION_BASED (or OFF) to reduce the
effective amount of objects. ALL will be still active then.
The following picture shows how this execution context works:
See figure
5.8 on the following page.• We start with a variant model which contains one parameter in two instances - one per
variant - with the values 3 and 7
• When the client code sets the parameter value in variant 1 to 4, the model automatically
modifies the variant sibling in variant 2
• As a result, the parameter has the same value in all variants
This change mode works with parameters and containers. The following operations are sup-
ported:
© 2016, Vector Informatik GmbH
165 of
207

Chapter 5.Data models in detailFigure 5.8: Variant common change of a parameter value
•
Container/parameter creation: The created object afterwards exists in all variants
the related parent exists in. Already existing objects are not modified. Missing objects
are created
•
Container/parameter deletion: The deleted object afterwards is being removed from
all variants the related parent exists in. So actually all variant siblings are deleted
•
Parameter value change: The parameter exists and has the same value in all variants
the parent container exists in. If a parameter instance is missing in a variant, it is being
created
Special behavior for multi-instance parameters:
• This mode guarantees that a set of multi-instance parameters is equal in all variants
• Only the values of multi-instance parameters are relevant. Their order can be different in
different variants
• Beside the values, this change mode guarantees that all variants contain the same number
of parameter instances. So, when a multi-instance set is being modified in a variant view,
this change mode creates or deletes objects in other variants to guarantee an equal number
of instances in all variant sibling sets
Remark: This change mode is implicitly turned on with the mode flag ALL when code is
being executed in the IInvariantView. It is being ignored implicitly when executing code in
an unfiltered context.
5.3 BswmdModel details5.3.1 BswmdModel - DefinitionModelThe BswmdModel provides a type safe and easy access to data of BSW modules (Ecu configu-
ration elements).
Example:• Access a single parameter /MICROSAR/ComM/ComMGeneral/ComMUseRte
You can to write: comM.getComMGeneral().getComMUseRte()
© 2016, Vector Informatik GmbH
166 of
207

Chapter 5.Data models in detail• Access containers[0:*] /MICROSAR/ComM/ComMChannel
You can to write:
for (ComMChannel channel : comM.getComMChannel()){
int value = channel.getComMChannelId().getValue();
}
The DaVinci Configurator internal Model (MDF model) has 1:1 relationship to your Bswmd-
Model. The BswmdModel will retrieve all data from the underlying MDF model.
Figure 5.9: The relationship between the MDF model and the BswmdModel
DefinitionModelThe DefinitionModel is the base implementation of every BswmdModel. Ev-
ery BswmdModel class is a subclass of the DefinitionModel where the classes begin with GI,
like GIContainer.
5.3.1.1 Types of DefinitionModelsThere are two types of DefinitionModels:
1.
BswmdModel (formally known as DefinitionTyped BswmdModel)
2.
DefRef API (formally known as Untyped BswmdModel)
The
BswmdModel consists of generated classes for the module definition elements like Mod-
uleDefinitions, Containers, Parameters in bswmd files. The generated class contains get-
ter methods for each child element. So you can access every child by the corresponding getter
method with compile time safety of the sub type.
The
BswmdModel derives from the
DefinitionModel DefRef API, so the
BswmdModel
contains all functionalities of the
DefRef API.
The
DefRef API of the DefinitionModel provides an generic access to the Ecu configuration
structure via DefRefs. There are
NO generated classes for the Definition structure. The
DefRef API uses the base classes of the DefinitionModel to provide this DefRef based access.
Every interface in the DefinitionModel starts with an GI. The Ecu Configuration elements have
corresponding base interfaces for each element:
© 2016, Vector Informatik GmbH
167 of
207
Chapter 5.Data models in detail• ModuleConfiguration - GIModuleConfiguration
• Container - GIContainer
• ChoiceContainer - GIChoiceContainer
• Parameter - GIParameter<?>
– Integer Parameter - GIParameter<BigInteger>
– Boolean Parameter - GIParameter<Boolean>
– Float Parameter - GIParameter<BigDecimal>
– String Parameter - GIParameter<String>
• Reference - GIReference<?>
– Container Reference - GIReferenceToContainer
– Foreign Reference- GIReference<Class>
So there are different classes for the different model types, e.g. all MDF classes start with MI,
the Untyped start with GI and DefinitionTyped classes are generated. The table
5.1 contrasts
the different model types and their corresonding classes.
AUTOSAR typeMDFModel“Untyped” BswmdModel“DefinitionTyped”ModuleConfiguration
MIModuleConfiguration
GIModuleConfiguration
CanIf
(generated)
Container
MIContainer
GIContainer
CanIfPrivateCfg
(generated)
String Parameter
MITextualValue
GIParameter<String>
GString
Integer Parameter
MINumericalValue
GIParameter<BigInteger>
GInteger
Reference to Container
MIReferenceValue
GIReferenceToContainer
CanIfCtrlDrvInitHohConfigRef
(generated)
Enum Parameter
MITextualValue
GIParameter<String>
CanIfDispatchBusOffUL
(generated)
Table 5.1: Different Class types in different models
Note: The GString in the table is not the Groovy GString class.
It is com.vector.cfg.gen.core.bswmdmodel.param.GString.
5.3.1.2 DefRef Getter methods of Untyped ModelThe DefRef API classes have no getter methods for the specific child types, but the children
could be retrieve via the generic getter methods like:
• GIContainer.getSubContainers()
• GIContainer.getParameters()
• GIContainer.getParameters(TypedDefRef)
• GIContainer.getParameter(TypedDefRef)
• GIContainer.getReferencesToContainer(TypedDefRef)
• GIModuleConfiguration.getSubContainer(TypedDefRef)
• GIParameter.getValueMdf()
Additionally there are methods to retrieve other referenced elements, like parent of reference
reverse lookup:
© 2016, Vector Informatik GmbH
168 of
207
Chapter 5.Data models in detail• GIContainer.getParent()
• GIContainer.getParent(DefRef)
• GIContainer.getReferencesPointingToMe()
• GIContainer.getReferencesPointingToMe(DefRef)
The following listing describe the usage of the untyped bswmd method in both models:
// Get the container from external method getCanIfInitConfigBswmd() ...
final GIContainer canIfInit = getCanIfInitConfigBswmd();
// Gets all subcontainers from a container CanIfRxPduConfig from the canIfInit instance
final List<GIContainer> subContainers = canIfInit.getSubContainers(CanIfRxPduConfig.DEFREF.
castToTypedDefRef());
if (subContainers.isEmpty()) {
// ERROR Handling
}
final GIContainer cont = subContainers.get(0);
// Gets exactly one CanIfCanRxPduHrhRef reference from the cont instance
final GIReference<MIContainer> child = cont.getReference(CanIfCanRxPduHrhRef.DEFREF.
castToTypedDefRef());
Listing 5.8: Sample code to access element in an Untyped model with DefRefs
final GIReferenceToContainer ref = getCanIfCanRxPduHrhRefBswmd();
final GIContainer target = ref.getRefTarget();
Listing 5.9: Resolves a Refference traget of an Reference Parameter
final GIParameter<BigInteger> param = getCanIfInitConfigBswmd().getParameter(
CanIfInitConfiguration.CANIF_NUMBER_OF_CAN_TXPDU_IDS_DEFREF);
final BigInteger value = param.getValueMdf();
Listing 5.10: The value of a GIParameter
The figure
5.10 on the following page shows the available DefRef navigation methods for the
Untyped model. There are more methods to navigate with the DefRef API through the a
DefinitionModel, please look into the Javadoc documentation of the GI... classes for more
functionality.
© 2016, Vector Informatik GmbH
169 of
207

Chapter 5.Data models in detailFigure 5.10: SubContainer DefRef navigation methods
5.3.1.3 ReferencesAll references in the BswmdModel are subtypes of GIReference. The generated model contains
generated DefintionTyped classes for references to container, for the other references their are
only Untyped classes like GInstanceReference.
A GIReference has the method getRefTargetMdf(), this will always return the target in the
MDF model as MIReferrable. For non GIReferenceToContainer this is the normal way to
resolve references, but for reference to container you should always try to use the method
getRefTarget(), which will not leave the BswmdModel.
Note: Try to use getRefTarget() as much as possible.
References to containerThe following references are references to container (References
pointing to container) and are subtypes of the GIReferenceToContainer.
• Normal Reference
© 2016, Vector Informatik GmbH
170 of
207

Chapter 5.Data models in detail• SymbolicNameReference
• ChoiceReference
References have the method getRefTarget(), which returns the target as BswmdModel object,
if the type is known at model generation time, the type will be the generated type. Otherwise
the return type is GIContainer.
Note: It is always allowed to call getRefTarget(), also for references pointing to external
types.
Figure 5.11: Untyped reference interfaces in the BswmdModel
SymbolicNameReferencesSymbolicNameReferences have the same methods as GIRefer-
enceToContainer and the additional methods getRefTargetParameterMdf(), which returns
the target parameter as MIObject The method getRefTargetParameter() return a Bswmd-
Model object, if the type is known at model generation time, the type will be the generated
type. Otherwise the return type is GIParameter.
Note: It is always allowed to call getRefTargetParameter(), also for references pointing to
external types.
5.3.1.4 Post-build selectable with BswmdModelThe BswmdModel supports the Post-build selectable use case, in respect that you do not have
to switch nor cache the corresponding IModelView. The BswmdModel objects cache the so
called Creation ModelView and switch transparently to that view when accessing the Model.
So you don’t have to switch to the correct view on access. See figure
5.12 on the next page.
You only have to ensure, that the requested IModelView is active or passed as parameter, when
you create an instance at the GIModelFactory. Note: A lazy created object will inherit the
view of the existing element.
© 2016, Vector Informatik GmbH
171 of
207

Chapter 5.Data models in detailFigure 5.12: Creating a BswmdModel in the Post-build selectable use case
5.3.1.5 Creation ModelView of the BswmdModelEvery GIModelObject (BswmdModel object) has a creation IModelView. This is the IMod-
elView, which was active or passed during creation of the BswmdModel. At every method call
to the BswmdModel, the model will switch to this view.
Using the creation ModelView of the BswmdModelThe method getCreationModelView()
returns the IModelView of this GIModelObject, which was active during the creation of this
BswmdModel.
The method executeWithCreationModelView() executes the code under visibility of the getCre-
ationModelView() of this GIModelObject.
The returned IModelViewExecutionContext must be used within a Java "try-with-
resources" feature.It makes sure, that the old view is restored when the try is com-
pleted.
GIModelObject myModelObject = ...;
try (
final IModelViewExecutionContext context = myModelObject.executeWithCreationModelView()) {
// do some operations
...
}
Listing 5.11: Java: Execute code with creation IModelView of BswmdModel object
The method executeWithCreationModelView(Runnable) executes the Runnable code under
visibility of the getCreationModelView() of this GIModelObject.
GIModelObject myModelObject = ...;
myModelObject.executeWithCreationModelView(()->{
// do some operations
});
Listing 5.12: Java: Execute code with creation IModelView of BswmdModel object via runnable
© 2016, Vector Informatik GmbH
172 of
207
Chapter 5.Data models in detailThe method executeWithCreationModelView() executes the Supplier code under visibility
of the getCreationModelView() of this GIModelObject. You could use this method, if you
want to return an object from this operation.
GIModelObject myModelObject = ...;
ReturnType returnVal = myModelObject.executeWithCreationModelView(()->{
// do some operations
return theValue;
});
Listing 5.13: Java: Execute code with creation IModelView of BswmdModel object
5.3.1.6 Lazy InstantiatingThe BswmdModel is instantiated lazily; this means when you create a ModuleConfiguration
object only one object for the module configuration is created.
When you call a getXXX() method on the configuration it will create the requested sub element,
if it exists. So you can start at any point in the model (e.g. a Subcontainer) and the model is
build successively, by your calls.
It is also allowed to call a getParent() on a Subcontainer, if the parent was not created yet.
The technique could be used in validations, when the creation of the full BswmdModel is too
expensive. Then you can create only the needed container; by an MDF model object.
5.3.1.7 Optional ElementsAll elements (Container, Parameter . . . ) are considered as optional if they have a multiplicity
of 0:1. The BswmdModel provide a special handling of optional elements. This shall support
you to recognize optional element during development (in the most cases some kind of special
handling is needed). An optional Element has other access methods as a required Element: The
method getXXX() will not return the element, it will return a GIOptional<Element> object
instead. You can ask the GIOptional object if the element exists (optElement.exists()).
Then you can call optElement.get() to retrieve the real object.
You also have the choice to use the method existsXXX().
This method is equivalent to
getXXX().exists(). The difference is that you get a compile error, if you try to use the optional
element without any check. When you are sure that the element must exist you can directly call
getXXXUnsafe(). Note: If you use any of the get methods (optElement.get() or getXXXUn-
safe()) and the element does not exist the normal BswmdModelException is thrown.
5.3.1.8 Class and Interface Structure of the BswmdModelThe upper part of the figure
5.13 on the following page shows the Untyped API (GI. . . interfaces).
The bottom left part is an example of DefinitionTyped (generated) class for the CanIf module.
The bottom right part are the classes used by the DefinitionTyped model, but are not visible
in the Untyped model.
© 2016, Vector Informatik GmbH
173 of
207

Chapter 5.Data models in detailFigure 5.13: Class and Interface Structure of the BswmdModel
5.3.1.9 BswmdModel write accessThe BswmdModel supports a write access for ecu configuration elements. This means new
elements can be created and existing elements can be modified and deleted by the Bswmd-
Model.
NOTE: The model is in read-only state by default, so no objects could be created. For this reason
all calls to an API which creates or deletes elements has to be executed within a transaction.
See
ModelDocumentation chapter "Model changes" for more details.
Optional and required Elements (0:1/1:1 Multiplicity)For optional or required elements,
the following additional methods are generated, if BswmdModelWriteAccess is enabled:
• get...OrNull(): Returns the requested element or null if it is missing.
• get...OrCreate(): Returns the existing requested element or implicitly creates a new
one if it is missing.
E.g. EcucGeneral:
© 2016, Vector Informatik GmbH
174 of
207
Chapter 5.Data models in detailEcuc ecuc = getEcucModuleConfig();
//Gets the EcucGeneral container or null if it is missing.
EcucGeneral ecucGeneralOrNull = ecuc.getEcucGeneralOrNull();
//Gets the existing EcucGeneral container or creates a new one if it is missing.
EcucGeneral ecucGeneralOrCreate = ecuc.getEcucGeneralOrCreate();
Listing 5.14: Additional write API methods for EcucGeneral
Multiple elements (Upper Multiplicity > 1)For each multiple element, the return type
for these elements is changed from List<> to GIPList<> for parameter and GICList<> for
container, if BswmdModelWriteAccess is enabled. These new interfaces provide methods which
allow creating and adding new children for the corresponding elements:
• createAndAdd(): Creates a new child element, appends it to the list and returns the new
element.
• createAndAdd(int index): Creates a new child element, inserts it to the list at the
specified index position and returns the new element.
• For GICList<> only:
– createAndAdd(String shortName): Creates a new child element with the specified
shortName, appends it to the list and returns the new element.
– createAndAdd(String shortName, int index): Creates a new child element with
the specified shortName, inserts it to the list at the specified index position and
returns the new element.
– byName(String shortName): Gets the container by specified shortName or throws
an exception if it is missing.
– byNameOrNull(String shortName): Gets the container by specified shortName or
null if it is missing.
– byNameOrCreate(String shortName): Gets the container by specified shortName
or implicitly creates a new one if it is missing.
– exists(String shortname): Returns true if the container exists, otherwise false.
E.g. EcucCoreDefinition:
© 2016, Vector Informatik GmbH
175 of
207
Chapter 5.Data models in detailEcuc ecuc = getEcucModuleConfig();
//Gets the EcucCoreDefinition list (create EcucHardware container if it is missing)
GICList<EcucCoreDefinition> ecucCores = ecuc.getEcucHardwareOrCreate().getEcucCoreDefinition
();
//Adds two EcucCores
EcucCoreDefinition core0 = ecucCores.createAndAdd("EcucCore0");
EcucCoreDefinition core1 = ecucCores.createAndAdd("EcucCore1");
if(ecucCores.exists("EcucCore0")) {
//Sets EcucCoreId from EcucCore0 to 0
ecucCores.byName("EcucCore0").getEcucCoreId().setValue(0);
}
//Creates a new EcucCore by method byNameOrCreate
EcucCoreDefinition core2 = ecucCores.byNameOrCreate("EcucCore2");
...
Listing 5.15: EcucCoreDefinition as GICList<EcucCoreDefinition>
Other write API•
Deleting model objects: It is also possible to delete objects from the model.
– moRemove: Deletes the specified object from the model.
– moIsRemoved: Returns true, if the object was removed from repository, or is invisible
in the current active IModelView.
//Deletes the container 'EcucGeneral' from the model.
ecucGeneral.moRemove();
//Deletes the parameter 'EcuCSafeBswChecks' from the model.
ecucGeneral.getEcuCSafeBswChecks.moRemove();
//Deletes the child container 'EcucCoreDefinition' with shortname 'EcucCore0' from the model.
ecucCores.byName("EcucCore0").moRemove();
// Checks if the container 'EcucGeneral' was removed from repository, or is invisible in the
current active `IModelView`.
if(ecucGeneral.moIsRemoved()) {
...
}
Listing 5.16: Deleting model objects
•
Duplication of containers: The method duplicate() copies a container with all its
children and appends it to the same parent.
//Duplicates the container 'EcucGeneral'
EcucGeneral duplicatedEcucGeneral = ecucGeneral.duplicate();
//Duplicates the child container 'EcucCoreDefinition' with shortname 'EcucCore0'
EcucCoreDefinition duplicatedEcucCore0 = ecucCores.byName("EcucCore0").duplicate();
Listing 5.17: Duplication of containers
•
Parameter values: The method setValue(VALUE) sets the value of a parameter. This
method checks if the specified parameters configuration object is available and sets the
© 2016, Vector Informatik GmbH
176 of
207
Chapter 5.Data models in detailnew value. If the parameter object is missing it is implicitly created in the model.
//Sets the value of the parameter 'EcuCSafeBswChecks' to 'true'
ecucGeneral.getEcuCSafeBswChecks.setValue(
true);
Listing 5.18: Set parameter values with the BswmdModel Write API
•
Reference targets: The method setRefTarget(REF_TARGET) sets the target of a ref-
erence. This method sets the specified target object as reference target of the specified
reference parameter. If the reference parameter object is missing it is implicitly created
in the model.
//Gets the container 'OsCounter' with shortname 'SystemTimer'
OsCounter osCounterTarget = os.getOsCounters.byName("SystemTimer");
//Sets the reference target of the parameter 'CanCounterRef'
can.getCanGeneral().getCanCounterRef().setRefTarget(osCounterTarget);
Listing 5.19: Set reference targets with the BswmdModel Write API
5.4 Model utility classes5.4.1 AsrPathThe AsrPath class represents an AUTOSAR path without a connection to any model.
AsrPaths are constant; their values cannot be changed after they are created. This class is
immutable!
5.4.2 AsrObjectLinkThis class implements an immutable identifier for AUTOSAR objects.
An AsrObjectLink can be created for each object in the MDF AUTOSAR model tree. The
main use case of object links is to identify an object unambiguously at a specific point in time for
logging reasons. Additionally and under specific conditions it is also possible to find the releated
MDF object using its AsrObjectLink instance. But this search-by-link cannot be guaranteed
for each object type and after model changes (details and restrictions below).
5.4.2.1 Object links depend on the MDF object type•
ReferrablesThe object link is actually identical with the AUTOSAR path
•
Ecuc objects with a definition (module, container and parameter)
The object link additionally stores the DefRef
•
Ecuc parametersThe object link additionally stores the parameters index. This is the index of all param-
eters with the same definition below the same parent container instance in the unfiltered
model view
© 2016, Vector Informatik GmbH
177 of
207
Chapter 5.Data models in detail5.4.2.2 Restrictions of object links• They are immutable and will therefore become invalid when the model changes
• So they don’t guarantee that the related MDF object can be retrieved after the model
has been changed. Search-by-link may even find another object or throw an exception in
this case
5.4.2.3 Examples for object link stringsThe method getObjectLinkString() returns for example the following strings:
• For a container or module configuration object, the AUTOSAR path is returned: "/Ac-
tiveEcuC/Can/CanGeneral"
• For a parameter, the parents AUTOSAR path, the last shortname of its definition and a
positional index in the list of parameters with the same definition is used: "/ActiveEcuC/-
Can/CanGeneral[2:SomeDefName]"
• In case of variant objects, all variants, this object is visible in, are added: /ActiveEcuC/-
Can/CanConfigSet/CanHardwareObject[0:CanControllerRef]{VariantA, VariantB}
5.4.3 DefRefsThe DefRef class represents an AUTOSAR definition reference (e.g. /MICROSAR/CanIf) with-
out a connection to any model. A DefRef replaces the String which represents a definition
reference. You shall always use a DefRef instance, when you want to reference something by
it’s definition.
The class abstracts the behavior of definition references in the AUTOSAR model (e.g. AU-
TOSAR 3 and AUTOSAR 4 handling).
DefRefs are constant; their values can not be changed after they are created. All DefRef classes
are immutable.
A DefRef represents the definition reference as two parts:
• Package part - e.g. /MICROSAR
• Definition without the package part - e.g. CanIf/CanIfGeneral
This is used to navigate through the AUTOSAR model with refinements and wildcards. So you
have to create a DefRef with the two parts separated.
The figure
5.14 on the next page shows the structure of the DefRef class and its sub classes.
CreationYou can create a DefRef object with following public static methods (partial):
• DefRef.create(DefRef, String) - Parent DefRef, Child name
• DefRef.create(IDefRefWildcard, String) - Wildcard, Definition without package
• DefRef.create(MIHasDefinition) - Model object
• DefRef.create(MIHasDefinition, String) - Parent object, Child name
• DefRef.create(MIParamConfMultiplicity) - Definition object
© 2016, Vector Informatik GmbH
178 of
207

Chapter 5.Data models in detailFigure 5.14: DefRef class structure
• DefRef.create(String, String) - Package part, Definition without package
WildcardsDefRef instances can also have a wildcard instead of a package String (IDefRefWildcard).
The wildcard is used to match on multiple packages. See chapter
5.4.3.2 on the following page
for details.
Useful MethodsThis section describes some useful methods (Please look at the javadoc of
the DefRef class for a full documentation):
• defRef.isDefinitionOf(MIHasDefinition) - Checks the definition of the configuration
element and returns true if the element has the definition. The "defRef" object is e.g.
from the Constants class.
– Note: The method isDefinitionOf() returns false, if the element is removed or
invisible.
• defRef.asDefinitionOf(MIHasDefinition, Class<>) - Checks the definition of the
configuration element and returns the element casted to the configuration subtype, or
null.
– Note: The method asDefinitionOf() returns null, if the element is removed or
invisible.
© 2016, Vector Informatik GmbH
179 of
207
Chapter 5.Data models in detailMIObject yourObject = ...;
DefRef yourDefRef = ...;
if(yourDefRef.isDefinitionOf(yourObject){
//It is the correct instance
//Do something
}
//Or with an integrated cast in the TypedDefRef case
final MIContainer container = yourDefRef.asDefinitionOf(yourObject);
if(container !=
null){
//Do something
}
Listing 5.20: DefRef isDefinitionOf methods
5.4.3.1 TypedDefRefsThe TypedDefRef class represents an AUTOSAR definition reference with the type of the
AUTOSAR (MDF) model. So every TypedDefRef knows which Definition, Configuration and
Value element is correct for the Definition path.
The DEF_TYPE, CONFIG_TYPE and VALUE_TYPE are Java generics and are used many APIs to
return the specific type of a request.
In addition the most TypedDefRefs also provide additional TypeInfo data, like the Multiplicity
of the element. See TypeInfo javadoc for more details.
5.4.3.2 DefRef WildcardsThe DefRef class supports so called wildcards, which could be used to match on multiple
packages at once, like the /[MICROSAR] wildcard matches on any DefRef package starting with
/MICROSAR. E.g. /MICROSAR, /MICROSAR/S12x, ....
Every wildcard is of type IDefRefWildcard. An IDefRefWildcard instance could be passed
to the DefRef.create(IDefRefWildcard, String) method to create a DefRef with wildcard
information.
Predefined DefRef WildcardsThe class EDefRefWildcard contains the predefined IDefRe-
fWildcards for the DefRef class. These IDefRefWildcards could be used to create DefRefs,
without creating your own wildcard for the standard use cases
The DefRef.create(String, String) method will parse the first String to find a wildcard
matching the EDefRefWildcards.
Predefined wildcards:The class EDefRefWildcard defines the following wildcards, with the
specified semantic:
• EDefRefWildcard.ANY /[ANY]: Matches on any package path. It is equal to any package
and any packages refines from ANY wildcard.
• EDefRefWildcard.AUTOSAR /[AUTOSAR]: Matches on the AUTOSAR3 and AUTOSAR4
packages (see DefRef class). It is equal to the AUTOSAR packages, but not to refined
© 2016, Vector Informatik GmbH
180 of
207
Chapter 5.Data models in detailpackages e.g. /MICROSAR. Any packages which refined from AUTOSAR also refines
from AUTOSAR wildcard.
• EDefRefWildcard.NOT_AUTOSAR_STMD /[!AUTOSAR_STMD]: Matches on any package ex-
cept the AUTOSAR packages. It is equal to any package, except AUTOSAR packages.
Any package refines from NOT_AUTOSAR_STMD wildcard, except AUTOSAR packages.
• EDefRefWildcard.MICROSAR /[MICROSAR]: Matches on any package stating with /MI-
CROSAR (also /MICROSAR/S12x). It is equal to any package stating with /MICROSAR.
Any package starting with /MICROSAR refines from MICROSAR wildcard.
• EDefRefWildcard.NOT_MICROSAR /[!MICROSAR]: Matches on any package path not start-
ing with /MICROSAR. It is equal to any package not starting with /MICROSAR. Any
package, which does not start with /MICROSAR, refines from NOT_MICROSAR wildcard.
Also the AUTOSAR packages refine from NOT_MICROSAR wildcard.
Creation of the DefRef with WildcardThe elements of EDefRefWildcard could be passed
to the DefRef constructor:
DefRef myDefRef = DefRef.create(EDefRefWildcard.MICROSAR, "CanIf");
Listing 5.21: Creation of DefRef with wildcard from EDefRefWildcard
Custom DefRef WildcardsYou could create your own wildcard by implementing the interface
IDefRefWildcard. Please choose a good name for your wildcard, because this could be displayed
to the user, e.g. in Validation results. The matches(DefRef) method shall return true, if the
passed DefRef matches the wildcard constraints.
Every wildcard string shall have the notation /[NameOfWildcard].
E.g.
/[MICROSAR], /[!MICROSAR].
5.4.4 CeStateThe CeState is an object which allows to retrieve different states of a configuration entity
(typically containers or parameters).
The most important APIs for generator and script code are:
• IParameterStatePublished
• IContainerStatePublished
5.4.4.1 Getting a CeState objectThe BSWMD models implement methods to get the CeState for a specific CE as the following
listing shows (the types GIParameter and GIContainer are interface base types in the BSWMD
models):
© 2016, Vector Informatik GmbH
181 of
207

Chapter 5.Data models in detailGIParameter parameter = ...;
IParameterStatePublished parameterState = parameter.getCeState();
GIContainer container = ...;
IContainerStatePublished containerState = container.getCeState();
Listing 5.22: Getting CeState objects using the BSWMD model
5.4.4.2 IParameterStatePublishedThe IParameterStatePublished specifies a type-safe published API for parameter states. It
mainly covers the following state information
• Does this parameter have a pre-configuration value?
What is this value?
The same
information is being provided for recommended and initial (derived) values
• Is this parameter user-defined?
• Is value change or deletion allowed in the current configuration phase (post-build loadable
use case)?
• What is the configuration class of this parameter
The figure
5.15 shows the inheritance hierarchy of the IParameterStatePublished class and
its sub classes.
Figure 5.15: IParameterStatePublished class structure
Parameters have different types of state information:
•
Simple state retrievalExample: The method isUserDefined() returns true when the parameter has a user-
defined flag.
•
States and values (pre-configuration, recommended configuration and inital (derived)
values)
Example: The method hasPreConfigurationValue() returns true when the parameter
has a pre-configured value. getPreConfigurationValue() returns this value.
© 2016, Vector Informatik GmbH
182 of
207

Chapter 5.Data models in detail•
States and reasonsExample: The method isDeletionAllowedAccordingToCurrentConfigurationPhase()
returns true if the parameter can be deleted in the current configuration phase (post-
build loadable projects only). getNotDeletionAllowedAccordingToCurrentConfigura-
tionPhaseReasons() returns the reasons if deletion is not allowed.
5.4.4.3 IContainerStatePublishedThe IContainerStatePublished specifies a type-safe published API for container states. It
mainly covers the following state information
• Does this container have a pre-configuration container (includes access to this container)?
The same information is being provided for recommended and initial (derived) values
• Is change or deletion allowed in the current configuration phase (post-build loadable use
case)?
• In which configuration phase has this container been created in (post-build loadable use
case)?
• What is the configuration class of this container
The figure
5.16 shows the inheritence hierarchy of the IContainerStatePublished class and
its sub classes.
Figure 5.16: IContainerStatePublished class structure
This API provides state information similar to IParameterStatePublished. Some of the states
are container-specific, of course. getCreationPhase(), for example, which returns the phase a
container in a post-build loadable configuration has been created in.
© 2016, Vector Informatik GmbH
183 of
207
6 AutomationInterface Content6.1 IntroductionThis chapter describes the content of the DaVinci Configurator AutomationInterface.
6.2 Folder StructureThe AutomationInterface consists of the following files and folders:
•
BswmdModel: contains the generated BswmdModel that is automatically created by
the DaVinci Configurator during startup
•
Core– AutomationInterface∗
_doc (find more details to its content in chapter
6.3)·
DVCfg_AutomationInterfaceDocumentation.pdf: this document
·
javadoc: Javadoc HTML pages
·
templates: script file and script project templates for a simple start of
script development
∗
buildLibs: AutomationInterface Gradle Plugin to provide the build logic to
build script projects, see also
7.7 on page 190∗
libs: compile bindings to Groovy and to the DaVinci Configurator Automation-
Interface, used by IntelliJ IDEA and Gradle
∗
licenses: the licenses of the used open source libraries
6.3 Script Development HelpThe help for the AutomationInterface script development is distributed among the following
sources:
• DVCfg_AutomationInterfaceDocumentation.pdf (this document)
• Javadoc HTML Pages
• Script Templates
6.3.1 DVCfg_AutomationInterfaceDocumentation.pdfYou find this document as described in chapter
6.2. It provides a good overview of architecture,
available APIs and gives an introduction of how to get started in script development. The focus
of the document is to provide an overview and not to be complete in API description. To get
a complete and detailed description of APIs and methods use the Javadoc HTML Pages as
described in
6.3.2 on the following page.© 2016, Vector Informatik GmbH
184 of
207
Chapter 6.AutomationInterface Content6.3.2 Javadoc HTML PagesYou find this documentation as described in chapter
6.2 on the previous page. Open the file
index.html to access the complete DaVinci Configurator AutomationInterface API reference. It
contains descriptions of all classes and methods that are part of the AutomationInterface.
The Javadoc is also accessible at your source code in the IDE for script development.
6.3.3 Script TemplatesYou find the Script Templates as described in chapter
6.2 on the preceding page. You may copy
them for a quick startup in script development.
6.4 Libs and BuildLibsThe AutomationInterface contains libraries to build projects, see
buildLibs in
6.2 on the pre-
vious page . And it contains other libraries which are described in
libs in
6.2 on the preceding
page.© 2016, Vector Informatik GmbH
185 of
207
7 Automation Script Project7.1 IntroductionAn automation script project is a normal Java/Groovy development project, where the built
artifact is a single jar file. The jar file is created by the build system, see chapter
7.7 on
page 190.It is the recommended way to develop scripts, containing more tasks or multiple classes.
The project provides IDE support for:
• Code completion
• Syntax highlighting
• API Documentation
• Debug support
• Build support
The recommended IDE is IntelliJ IDEA.
7.2 Automation Script Project CreationTo create a new script project please follow the instructions in chapter
2.4 on page 11.7.3 Project File ContentAn automation project will at least contain the following files and folders:
• Folders
– .gradle - Gradle temp folder -
DO NOT commit it into a version control system
– build - Gradle build folder -
DO NOT commit it into a version control system
– gradle - Gradle bootstrap folder - Please commit it into your version control system
– src - Source folder containing your Groovy, Java sources and resource files
• Files
– Gradle files - see
7.7.2 on page 190 for details
∗ gradlew.bat
∗ build.gradle
∗ settings.gradle
∗ projectConfig.gradle
∗ dvCfgAutomationBootstrap.gradle
– IntelliJ Project files (optional)
© 2016, Vector Informatik GmbH
186 of
207



Chapter 7.Automation Script Project∗ ProjectName.iws
∗ ProjectName.iml
∗ ProjectName.ipr
7.4 IntelliJ IDEA Usage7.4.1 Supported versionsThe supported IntelliJ IDEA versions are:
• 2016.1 (.0-3)
• 2016.2
Please use one of the versions above. With other versions, there could be problems with the
editing, code completion and so on.
7.4.2 Building ProjectsProject BuildThe standard way to build projects is to choose the option
<ProjectName>[build] in the Run Menu in the toolbar and to press the Run Button beneath that menu.
Figure 7.1: Project Build
Project Continuous BuildA further option is provided for the case you prefer an automatic
project building each time you save your implementation.
If you choose the menu option
<ProjectName> continuous [build] in the toolbar the Run Button has to be pressed only
one time to start the continuous building. Hence forward each saving of your implementation
triggers an automatic building of the script project.
But be aware that the continuous build option is available for .java and .groovy
files only. In case of changes in e.g. .gradle files you still have to press the Run Button in
order to build the project.
Figure 7.2: Project Continuous Build
The Continuous Build process can be stopped with the Stop Button in the Run View.
Figure 7.3: Stop Continuous Build
If you want to exit the IntelliJ IDEA while the Continuous Build process is still running, you
will be asked to disconnect from it. Having disconnected you are allowed to exit the IDE.
© 2016, Vector Informatik GmbH
187 of
207



Chapter 7.Automation Script ProjectFigure 7.4: Disconnect from Continuous Build Process
7.4.3 Debugging with IntelliJBe aware that only script projects and not script files are debuggable.To enable debugging you must start DaVinci Configurator application with the enableDebugger
option as described in
7.6 on page 190.In the IntelliJ IDEA choose the option
<ProjectName> [debug] in the Run Menu located
in the toolbar. Pressing the Debug Button starts a debug session.
Figure 7.5: Project Debug
Set your breakpoints in IntelliJ IDEA and execute the task. To stop the debug session press
the Stop Button in the Debugger View.
Figure 7.6: Stop Debug Session
If you want to exit the IntelliJ IDEA while the Debug process is still running, you will be asked
to disconnect from it. Having disconnected you are allowed to exit the IDE.
© 2016, Vector Informatik GmbH
188 of
207

Chapter 7.Automation Script ProjectFigure 7.7: Disconnect from Debug Process
7.4.4 TroubleshootingCode completion, CompilationIf the code completion or compilation does not work, please
verify that the Java JDK settings in the IntelliJ IDEA are correct. You have to set the Project
JDK and the Gradle JDK setting. See
2.4.3 on page 14.Gradle build, build buttonIf the Gradle build does nothing after start or the build button is
grayed, please verify that the Java JDK settings in the IntelliJ IDEA are correct. You have to
set the Gradle JDK setting. See
2.4.3 on page 14.If the build button is marked with an error, please make sure that the Gradle plugin inside of
IntelliJ IDEA is installed. Open File->Settings...->Plugins and select the Gradle plugin.
IntelliJ BuildYou shall not use the IntelliJ menu "Build" or the context menu entries "Make
Project", "Make Module", "Rebuild Project" or "Compile". The project shall be build with
Gradle not with IntelliJ IDEA. So you have to select one of the Run Configuration (Run menu)
to build the project as described in chapter
7.4 on page 187.Groovy SDK not configuredIf you get the message ’Groovy SDK is not configured for ...’ in
IntelliJ IDEA you probably have to migrate your project as described in chapter
7.5.Debugging - DaVinci Configurator does not startIf the DaVinciCfg.exe does not start when
the enableDebugger option is passed, please check if the default port (8000) is free, or choose
another free port by appending the port number to the enableDebugger option.
7.5 Project Migration to newer DaVinci Configurator VersionIf you update your DaVinci Configurator version in your SIP, it could be necessary to execute
the IntelliJ IDEA task of Gradle to update your compile dependencies.
Steps to execute:
1. Close IntelliJ IDEA.
2. Update the DaVinci Configurator in your SIP
3. Open a command shell (cmd.exe) at your project folder
• Folder containing the gradlew.bat
4. Type gradlew idea and press enter
5. Wait until the task has finished
© 2016, Vector Informatik GmbH
189 of
207
Chapter 7.Automation Script Project6. Open IntelliJ IDEA
This will update the compile time dependencies of your Automation Script Project according
to the new DaVinci Configurator version.
After this, please read the Changes (see chapter
8 on page 193) in the new release and update
your script, if something of interest has changed.
7.6 Debugging Script ProjectBe aware that only script projects and not script files are debuggable.To debug a script project, any java debugger could be used. Simply add the enableDebugger
parameter to the commandline of the DaVinci Configurator and attach your debugger.
DVCfgCmd -s MyApplScriptTask --enableDebugger
You could attach a debugger at port 8000 (default). If the DaVinci Configurator does not start
with the option, please see
7.4.4 on the preceding page.Different Debug PortDVCfgCmd -s MyApplScriptTask --enableDebugger <YOUR-PORT> --waitForDebugger
Example:
DVCfgCmd -s MyApplScriptTask --enableDebugger 12345 --waitForDebugger
You could attach a debugger at port 12345 (select any free port) and the DVCfgCmd process will
wait until the debugger is attached. You could also use these commandline parameters with
the DaVinciCFG.exe to debug a script project with the DaVinci Configurator UI.
7.7 Build SystemThe build system uses
Gradle1 to build a single Jar file. It also setups the dependencies to the
DaVinci Configurator and create the IntelliJ IDEA project.
To setup the Gradle installation, see chapter
2.4.4 on page 14.7.7.1 Jar Creation and Output LocationThe call to gradlew build in the root directory of your automation script project will create
the jar file. The jar file is then located in:
• <ProjectRoot>\build\libs\<ProjectName>-<ProjectVersion>.jar
7.7.2 Gradle File StructureThe default automation project contains the following Gradle build files:
• gradlew.bat
1http://gradle.org/ [2016-05-25]
© 2016, Vector Informatik GmbH
190 of
207
Chapter 7.Automation Script Project– Gradle batch file to start Gradle (Gradle Wrapp
er2)• build.gradle
– General build file - You can modify it to adapt the build to your needs
• settings.gradle
– General build project settings - See Gradle documen
tation3• projectConfig.gradle
– Contains automation project specific settings - You can modify it to adapt the build
to your needs
• dvCfgAutomationBootstrap.gradle
– This is the internal bootstrap file.
DO NOT change the file content.
7.7.2.1 projectConfig.gradle File settingsThe file contains two essential parts of the build:
• Names of the scripts to load (automationClasses)
• The path to the DaVinci Configurator installation (dvCfgInstallation)
automationClassesYou
have to add your classes to the list of automationClasses to
make them loadable.
The syntax of automationClasses is a list of Strings, of all classes as full qualified Class
names.
Syntax: "javaPkg.subPkg.ClassName"
// The property project.ext.automationClasses defines the classes to load
project.ext.automationClasses = [
"sample.MyScript",
"otherPkg.MyOtherScript",
"javapkg.ClassName"
]
Listing 7.1: The automationClasses list in projectConfig.gradle
dvCfgInstallationThe dvCfgInstallation defines the path to the DaVinci Configurator in-
stallation in your SIP. The installation is needed to retrieve the build dependencies and the
generated model.
You
can change the path to any location containing the correct version of the DaVinci Config-
urator.
You could also evaluate SystemEnv variables, other project properties or Gradle settings to
define the path dependent of the development machine, instead of encoding an absolute path.
This will help, when the project is committed to a version control system. But this is project
dependent and out of scope of the provided template project.
2https://docs.gradle.org/current/userguide/gradle_wrapper.html [2016-05-25]
3https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html [2016-05-25]
© 2016, Vector Informatik GmbH
191 of
207
Chapter 7.Automation Script Project7.7.3 Advanced Build Topics7.7.3.1 Gradle dvCfgAutomation API ReferenceThe DaVinci Configurator build system provides a Gradle DSL API to set properties of the
build. The entry point is the keyword dvCfgAutomation
dvCfgAutomation {
classes project.ext.automationClasses
}
Listing 7.2: DaVinci Configurator build Gradle DSL API
The following methods are defined inside of the dvCfgAutomation block:
• classes (Type List<String>) - Defines the automation classes to load
• useBswmdModel (Type boolean) - Enables or disables the usage of the BswmdModel inside
of the script project.
• useJarSignerDaemon (Type boolean) - Enables or disables the usage of the Jar Signer
Daemon process.
useBswmdModelThe useBswmdModel enables or disables the usage of the BswmdModel in-
side of the project.
This is helpful, if you want to create a project, which shall run with
different SIPs. This prevent the inclusion of the BswmdModel. The default is true (Use the
BswmdModel) if nothing is specified.
dvCfgAutomation {
useBswmdModel
false}
Listing 7.3: DaVinci Configurator build Gradle DSL API - useBswmdModel
useJarSignerDaemonThe useJarSignerDaemon enables or disables the usage of the usage of
the Jar Signer Daemon process. The process is spawned when a jar file shall be signed. This
will speedup the build process especially when thr project is built often. The daemon is closed
automatically, when not used in a certain time span.
The default of useJarSignerDaemon is true.
The Gradle task stopJarSignerDaemon will stop any running Signer daemon.
dvCfgAutomation {
useJarSignerDaemon
true}
Listing 7.4: DaVinci Configurator build Gradle DSL API - useJarSignerDaemon
© 2016, Vector Informatik GmbH
192 of
207
8 AutomationInterface Changes betweenVersionsThis chapter describes all API changes between different MICROSAR releases.
8.1 Changes in MICROSAR AR4-R17 - Cfg5.148.1.1 GeneralThis is the
first stable version of the DaVinci Configurator AutomationInterface.
8.1.2 Script Execution8.1.2.1 Stateful Script TasksA new API was added to support cache and retrieve data over multiple script task executions.
See
4.4.10 on page 47 for more details.
8.1.3 Automation Script ProjectYou have to migrate your project to the new compile bindings. Please execute the instructions
in chapter
7.5 on page 189.8.1.3.1 GroovyThe used Groovy version was updated from 2.4.5 to 2.4.7, please see Groovy website for de-
tails.
8.1.3.2 Supported IntelliJ IDEA VersionThe IntelliJ IDEA version 2016.2 was added to the supported versions. See
7.4.1 on page 187
for details.
8.1.3.3 BuildSystemGradleThe used default Gradle version was updated from 2.13 to 3.0, please see Gradle
website for details.
useJarSignDaemonThe useJarSignDaemon Gradle build setting added. See
7.7.3.1 on theprevious page for details.
© 2016, Vector Informatik GmbH
193 of
207
Chapter 8.AutomationInterface Changes between Versions8.1.4 Converter RefactoringThe converters previously provided by com.vector.cfg.automation.api.Converters have
been moved to the new com.vector.cfg.automation.scripting.api.ScriptConverters and
com.vector.cfg.model.groovy.api.ModelConverters.
8.1.5 UserInteractionUserInteraction API added to show messages to the user, see
4.4.5.1 on page 38.8.1.6 Project Load8.1.6.1 AUTOSAR Arxml FilesNew API added to open AUTOSAR arxml files as a temporary project. See chapter
4.5.6 on
page 60 for details.
8.1.7 ModelScript Tasks TypesThe existing script task type DV_MODULE_ACTIVATION renamed to the new
name DV_ON_MODULE_ACTIVATION.
A new DV_ON_MODULE_DEACTIVATION task type added, which is execution when a module con-
figuration is deleted.
8.1.7.1 TransactionsA new ITransactionsApi added which provide access to the transactionHistory and API to re-
trieve information of running transactions. A new method transactions.isTransactionRunning()
added.
The ITransactionHistoryApiwas moved to the new ITransactionsApi. The access to the
history is now transactions.transactionHistory{}.
OperationsThe new operations added:
• deactivateModuleConfiguration() to delete a module configuration
• activateModuleConfiguration(DefRef, String shortName) to activate a module con-
figuration with the specified short name
• createModelObject(Class<T>) to create arbitrary MDF model objects
• parameter.setUserDefined(boolean) method added to set and reset the user defined
flag
© 2016, Vector Informatik GmbH
194 of
207
Chapter 8.AutomationInterface Changes between Versions8.1.7.2 MDF Model Read and WriteThe whole MDF model API was changed from the old mdfRead() and mdfWrite() to one
method mdfModel() with explicit write/create methods. You have to change all your mdfRead()
and mdfWrite() calls to mdfModel(). And every mdfWrite() closure the implicit creation to
explicit create calls.
This was necessary due to the fact that the old implicit API leads to surprising results, when
methods are called, which use the read API, but called in a write context. So the method would
yield different results, when called in different contexts.
The new MDF model API will never create any elements implicitly. Now there are explicit
create methods, like in the BswmdModel:
• For 0:1 elements: get<Element>OrCreate() method
• For 0:* elements: list.createAndAdd() and byNameOrCreate() methods
The write context is not needed anymore, but you have to open a transaction() before calling
any write API.
See the chapter
4.6.4.1 on page 74 for the read API and
4.6.4.2 on page 76 for the write
API.
8.1.7.3 SystemDescription AccessThe SystemDescription Access API added to retrieve paths to elements like flat map, flat extract
and the corresponding model elements. See chapter
4.6.5 on page 87 for details.
8.1.7.4 ActiveEcucThe class IActiveEcuc was renamed to IActiveEcucApi to reflect that it is not the active ecuc
element, but the API of the active ecuc.
8.1.8 PersistencyNew Persistency API added to import and export model data. See chapter
4.11 on page 141
for details.
8.1.9 GenerationThe generation script tasks DV_GENERATION_ON_START and DV_GENERATION_ON_END renamed
to DV_ON_GENERATION_START and DV_ON_GENERATION_END.
The new script task type DV_CUSTOM_WORKFLOW_STEP added to execute tasks in the custom
workflow. See
4.3.1.4 on page 29 for details.
The return type of validation and generation methods has changed to IGenerationResult-
Model. This type provides more detailed information about the executed steps.
© 2016, Vector Informatik GmbH
195 of
207
Chapter 8.AutomationInterface Changes between Versions8.1.10 BswmdModel8.1.10.1 Writing with BswmdModelThe BswmdModel supports now a write access for ecuc configuration elements. This means new
elements can be created and existing elements can be modified and deleted by the BswmdModel.
See
5.3.1.9 on page 174 for more details.
8.1.11 BswmdModel GroovybswmdModelReadThe BswmdModel access was changed from the old bswmdModelRead() to
the new bswmdModel() method. This was done to support the new write access.
Domain Object NavigationThe BswmdModel API now support the navigation from domain
model to the BswmdModel. See
4.6.3.6 on page 73.8.1.12 Domain DiagnosticsIntroduced new API which allows creation and querying of diagnostic events. Also OBD and
J1939 state of the configuration can be queried.
8.1.13 Domain CommunicationCommunication Domain API moved from
com.vector.cfg.dom.com.model.groovy into
com.vector.cfg.dom.com.groovy.api.
Can Controller classes moved from
com.vector.cfg.dom.com.model.groovy.can into
com.vector.cfg.dom.com.groovy.can.
8.1.14 Domain Runtime SystemRuntime System API IRuntimeSystemApi now provides functionality to map ports and system
signals.
Entry points are the selectComponentPorts, selectSignalInstances and selectCommuni-
cationElements methods.
© 2016, Vector Informatik GmbH
196 of
207
Chapter 8.AutomationInterface Changes between Versions8.2 Changes in MICROSAR AR4-R16 - Cfg5.138.2.1 GeneralThis is the
first version of the DaVinci Configurator AutomationInterface.
8.2.2 API StabilityThe API is not stable yet and could still be changed in later releases. So it could be necessary
to migrate your code when you update to later versions of the DaVinci Configurator.
8.2.3 Beta StatusSome features of the AutomationInterface are have beta status. This will change for later
versions of the AutomationInterface. Which means that some features:
• Are not fully tested
• Missing documentation
• Missing functionality
© 2016, Vector Informatik GmbH
197 of
207
9 Appendix© 2016, Vector Informatik GmbH
198 of
207
Chapter 9.AppendixNomenclatureAIAutomation Interface
AU T OSAR AUTomotive Open System ARchitecture
CEConfiguration Entity (typically a container or parameter)
Cf gDaVinci Configurator
Cf g5 DaVinci Configurator
DVDaVinci
IDEIntegrated Development Environment
J ARJava Archive
J DK Java Development Kit
J REJava Runtime Environment
M DF Meta-Data-Framework
M SN ModuleShortName
© 2016, Vector Informatik GmbH
199 of
207
FiguresFigures2.1Script Samples location. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.2Script Locations View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.3Script Tasks View. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.4Create New Script Project... Button . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.5Project Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
2.6Project Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.7Project SDK Setting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.8Gradle JVM Setting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
3.1DaVinci Configurator components and interaction with scripts. . . . . . . . . .
15
3.2Structure of scripts and script tasks. . . . . . . . . . . . . . . . . . . . . . . . .
17
4.1The API overview and containment structure . . . . . . . . . . . . . . . . . . . .
22
4.2IScriptTaskType interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.3Script Task Execution Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
4.4ScriptingException and sub types . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
4.5Search for active project in getActiveProject() . . . . . . . . . . . . . . . . . . . .
50
4.6example situation with the GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.1ECUC container type inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
5.2MIObject class hierarchy and base interfaces. . . . . . . . . . . . . . . . . . . . 154
5.3Autosar package containment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
5.4The ECUC container definition reference . . . . . . . . . . . . . . . . . . . . . . . 156
5.5Invariant views hierarchy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
5.6Example of a model structure and the visibility of the IInvariantValuesView . . . 162
5.7Variant specific change of a parameter value . . . . . . . . . . . . . . . . . . . . . 165
5.8Variant common change of a parameter value . . . . . . . . . . . . . . . . . . . . 166
5.9The relationship between the MDF model and the BswmdModel . . . . . . . . . 167
5.10 SubContainer DefRef navigation methods . . . . . . . . . . . . . . . . . . . . . . 170
5.11 Untyped reference interfaces in the BswmdModel . . . . . . . . . . . . . . . . . . 171
5.12 Creating a BswmdModel in the Post-build selectable use case . . . . . . . . . . . 172
5.13 Class and Interface Structure of the BswmdModel. . . . . . . . . . . . . . . . . 174
5.14 DefRef class structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
5.15 IParameterStatePublished class structure. . . . . . . . . . . . . . . . . . . . . . 182
5.16 IContainerStatePublished class structure . . . . . . . . . . . . . . . . . . . . . . . 183
7.1Project Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.2Project Continuous Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.3Stop Continuous Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.4Disconnect from Continuous Build Process . . . . . . . . . . . . . . . . . . . . . . 188
7.5Project Debug. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.6Stop Debug Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.7Disconnect from Debug Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
© 2016, Vector Informatik GmbH
200 of
207
TablesTables5.1Different Class types in different models . . . . . . . . . . . . . . . . . . . . . . . 168
© 2016, Vector Informatik GmbH
201 of
207
Listings3.1Static field memory leak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
3.2Memory leak with closure variable . . . . . . . . . . . . . . . . . . . . . . . . . .
21
4.1Task creation with default type . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
4.2Task creation with TaskType Application . . . . . . . . . . . . . . . . . . . . . .
24
4.3Task creation with TaskType Project . . . . . . . . . . . . . . . . . . . . . . . . .
24
4.4Define two tasks is one script . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
4.5Script creation with IDE support . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
4.6Task with isExecutableIf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.7Script with description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.8Task with description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
4.9Task with description and help text. . . . . . . . . . . . . . . . . . . . . . . . .
26
4.10 Access automation API in Groovy clients by the IScriptExecutionContext . . . .
31
4.11 Access to automation API in Java clients by the IScriptExecutionContext . . . .
32
4.12 Script task code block arguments . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
4.13 Resolves a path with the resolvePath() method . . . . . . . . . . . . . . . . . . .
34
4.14 Resolves a path with the resolvePath() method . . . . . . . . . . . . . . . . . . .
35
4.15 Resolves a path with the resolveScriptPath() method . . . . . . . . . . . . . . . .
35
4.16 Resolves a path with the resolveProjectPath() method . . . . . . . . . . . . . . .
36
4.17 Resolves a path with the resolveSipPath() method . . . . . . . . . . . . . . . . .
36
4.18 Resolves a path with the resolveTempPath() method . . . . . . . . . . . . . . . .
36
4.19 Get the project output folder path . . . . . . . . . . . . . . . . . . . . . . . . . .
37
4.20 Get the SIP folder path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
4.21 Usage of the script logger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
4.22 Usage of the script logger with message formatting . . . . . . . . . . . . . . . . .
38
4.23 Usage of the script logger with Groovy GString message formatting . . . . . . . .
38
4.24 UserInteraction from a script . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
4.25 Stop script task execution by throwing an ScriptClientExecutionException . . . .
40
4.26 Changing the return code of the console application by throwing an ScriptClien-tExecutionException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
4.27 Using your own defined method . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
4.28 Using your own defined class. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
4.29 Using your own defined method with a daVinci block . . . . . . . . . . . . . . . .
42
4.30 ScriptApi.scriptCode{} usage in own method . . . . . . . . . . . . . . . . . . . .
43
4.31 ScriptApi.scriptCode() usage in own method. . . . . . . . . . . . . . . . . . . .
43
4.32 ScriptApi.activeProject{} usage in own method . . . . . . . . . . . . . . . . . . .
44
4.33 ScriptApi.activeProject() usage in own method . . . . . . . . . . . . . . . . . . .
44
4.34 Define and use script task user defined arguments from commandline . . . . . . .
45
4.35 Script task UserDefined argument with no value. . . . . . . . . . . . . . . . . .
45
4.36 Script task UserDefined argument with default value . . . . . . . . . . . . . . . .
45
4.37 Script task UserDefined argument with multiple values . . . . . . . . . . . . . . .
46
4.38 executionData - Cache and retrieve data during one script task execution . . . .
47
4.39 sessionData - Cache and retrieve data over multiple script task executions . . . .
47
4.40 sessionData and executionData syntax samples . . . . . . . . . . . . . . . . . . .
48
4.41 Accessing IProjectHandlingApi as a property . . . . . . . . . . . . . . . . . . . .
49
4.42 Accessing IProjectHandlingApi in a scope-like way . . . . . . . . . . . . . . . . .
49
4.43 Switch the active project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50
4.44 Accessing the active IProject. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
© 2016, Vector Informatik GmbH
202 of
207
Listings4.45 Creating a new project (mandatory parameters only) . . . . . . . . . . . . . . . .
51
4.46 Creating a new project (with some optional parameters) . . . . . . . . . . . . . .
52
4.47 Opening a project from .dpa file. . . . . . . . . . . . . . . . . . . . . . . . . . .
58
4.48 Parameterizing the project open procedure. . . . . . . . . . . . . . . . . . . . .
58
4.49 Opening, modifying and saving a project . . . . . . . . . . . . . . . . . . . . . . .
59
4.50 Opening Arxml files as project. . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4.51 Read with BswmdModel objects starting with a module DefRef (no type decla-ration) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63
4.52 Read with BswmdModel objects starting with a module DefRef (strong typing) .
63
4.53 Read with BswmdModel objects with closure argument. . . . . . . . . . . . . .
64
4.54 Read with BswmdModel object for an MDF model object . . . . . . . . . . . . .
64
4.55 Write with BswmdModel required/optional objects . . . . . . . . . . . . . . . . .
65
4.56 Write with BswmdModel multiple objects . . . . . . . . . . . . . . . . . . . . . .
65
4.57 Write with BswmdModel - Duplicate a container . . . . . . . . . . . . . . . . . .
66
4.58 Write with BswmdModel - Delete elements. . . . . . . . . . . . . . . . . . . . .
66
4.59 Read system description starting with an AUTOSAR path in closure . . . . . . .
67
4.60 Read system description starting with an AUTOSAR path in property style . . .
67
4.61 Changing a simple property of an MIVariableDataPrototype . . . . . . . . . . . .
68
4.62 Creating non-existing member by navigating into its content with OrCreate() . .
68
4.63 Creating new members of child lists with createAndAdd() by type . . . . . . . .
68
4.64 Updating existing members of child lists with byNameOrCreate() by type . . . .
69
4.65 BswmdModel usage with import . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
4.66 Read with BswmdModel the EcuC module configuration . . . . . . . . . . . . . .
71
4.67 Write with BswmdModel the EcucGeneral container . . . . . . . . . . . . . . . .
71
4.68 Usage of the sipDefRef API to retrieve DefRefs in script files. . . . . . . . . . .
72
4.69 Usage of generated DefRefs form the bswmd model . . . . . . . . . . . . . . . . .
73
4.70 Switch from a domain model object to the corresponding BswmdModel object . .
73
4.71 Navigate into an MDF object starting with an AUTOSAR path . . . . . . . . . .
74
4.72 Find an MDF object and retrieve some content data . . . . . . . . . . . . . . . .
75
4.73 Navigating deeply into an MDF object with nested closures . . . . . . . . . . . .
75
4.74 Ignoring non-existing member closures . . . . . . . . . . . . . . . . . . . . . . . .
75
4.75 Get a MIReferrable child object by name. . . . . . . . . . . . . . . . . . . . . .
76
4.76 Retrieve child from list with byName() . . . . . . . . . . . . . . . . . . . . . . . .
76
4.77 Changing a simple property of an MIVariableDataPrototype . . . . . . . . . . . .
77
4.78 Creating non-existing member by navigating into its content with OrCreate() . .
77
4.79 Creating child member by navigating into its content with OrCreate() with type78
4.80 Creating new members of child lists with createAndAdd() by type . . . . . . . .
78
4.81 Updating existing members of child lists with byNameOrCreate() by type . . . .
80
4.82 Delete a parameter instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81
4.83 Check is a model instance is deleted . . . . . . . . . . . . . . . . . . . . . . . . .
81
4.84 Duplicates a container under the same parent . . . . . . . . . . . . . . . . . . . .
82
4.85 Get the AsrPath of an MIReferrable instance . . . . . . . . . . . . . . . . . . . .
82
4.86 Get the AsrObjectLink of an AUTOSAR model instance . . . . . . . . . . . . . .
82
4.87 Get the DefRef of an Ecuc model instance . . . . . . . . . . . . . . . . . . . . . .
82
4.88 Set the DefRef of an Ecuc model instance . . . . . . . . . . . . . . . . . . . . . .
83
4.89 Get the CeState of an Ecuc parameter instance . . . . . . . . . . . . . . . . . . .
83
4.90 Retrieve the user-defined flag of an Ecuc parameter in Groovy . . . . . . . . . . .
83
4.91 Set an Ecuc parameter instance to user defined . . . . . . . . . . . . . . . . . . .
83
4.92 Get the AUTOSAR root object . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
4.93 Get the active Ecuc and all module configurations. . . . . . . . . . . . . . . . .
84
4.94 Iterate over all module configurations. . . . . . . . . . . . . . . . . . . . . . . .
84
© 2016, Vector Informatik GmbH
203 of
207
Listings4.95 Get module configurations by definition . . . . . . . . . . . . . . . . . . . . . . .
84
4.96 Get subContainers and parameters by definition. . . . . . . . . . . . . . . . . .
85
4.97 Check parameter values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
4.98 Get integer parameter value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
4.99 Get reference parameter value . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
4.100Get the FlatExtract and FlatMap paths by the SystemDescription API. . . . .
88
4.101Get FlatExtract instance by the SystemDescription API . . . . . . . . . . . . . .
88
4.102Execute a transaction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
4.103Execute a transaction with a name . . . . . . . . . . . . . . . . . . . . . . . . . .
88
4.104Check if a transaction is running . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
4.105Undo a transaction with the transactionHistory . . . . . . . . . . . . . . . . . . .
90
4.106Redo a transaction with the transactionHistory . . . . . . . . . . . . . . . . . . .
90
4.107The default view is the IInvariantValuesView . . . . . . . . . . . . . . . . . . . .
92
4.108Execute code in a model view . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
4.109Basic structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
4.110Validate with default project settings . . . . . . . . . . . . . . . . . . . . . . . . .
94
4.111Generate with standard project settings . . . . . . . . . . . . . . . . . . . . . . .
95
4.112Generate one module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
4.113Generate one module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
4.114Generate two modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
96
4.115Generate one module with two configurations . . . . . . . . . . . . . . . . . . . .
96
4.116Execute an external generation step. . . . . . . . . . . . . . . . . . . . . . . . .
97
4.117Evaluate the generation result . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
4.118Use a script task as generation step during generation . . . . . . . . . . . . . . .
98
4.119Use a script task as custom workflow step . . . . . . . . . . . . . . . . . . . . . .
99
4.120Hook into the GenerationProcess at the start with script task . . . . . . . . . . .
99
4.121Hook into the GenerationProcess at the end with script task. . . . . . . . . . .
99
4.122Access all validation-results and filter them by ID . . . . . . . . . . . . . . . . . . 101
4.123Solve a single validation-result with a particular solving-action. . . . . . . . . . 102
4.124Fast solve multiple results within one transaction . . . . . . . . . . . . . . . . . . 103
4.125Solve all validation-results with its preferred solving-action (if available) . . . . . 103
4.126Access all validation-results of a particular object . . . . . . . . . . . . . . . . . . 104
4.127Access all validation-results of a particular DefRef. . . . . . . . . . . . . . . . . 104
4.128Filter validation-results using an ID constant . . . . . . . . . . . . . . . . . . . . 105
4.129Fast solve multiple validation-results within one transaction using a solving-action-group-ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
4.130IValidationResultUI overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
4.131IValidationResultUI in a variant (post build selectable) project . . . . . . . . . . 107
4.132CE is affected by (matches) an IValidationResultUI . . . . . . . . . . . . . . . . . 107
4.133Advanced use case - Retrieve Erroneous CEs with descriptors of an IValidation-ResultUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
4.134Examine an ISolvingActionSummaryResult . . . . . . . . . . . . . . . . . . . . . 109
4.135Create a ValidationResult . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
4.136Report a ValidationResult when MD license option is available . . . . . . . . . . 110
4.137Update an existing project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.138Change list of communication extracts and update . . . . . . . . . . . . . . . . . 112
4.139Accessing IDomainApi as a property . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.140Accessing IDomainApi in a scope-like way . . . . . . . . . . . . . . . . . . . . . . 113
4.141Accessing ICommunicationApi as a property . . . . . . . . . . . . . . . . . . . . . 113
4.142Accessing ICommunicationApi in a scope-like way. . . . . . . . . . . . . . . . . 114
4.143Optimizing Can Acceptance Filters . . . . . . . . . . . . . . . . . . . . . . . . . . 115
© 2016, Vector Informatik GmbH
204 of
207
Listings4.144Accessing IDiagnosticsApi as a property . . . . . . . . . . . . . . . . . . . . . . . 117
4.145Accessing IDiagnosticsApi in a scope-like manner . . . . . . . . . . . . . . . . . . 117
4.146Create a new UDS DTC with event . . . . . . . . . . . . . . . . . . . . . . . . . . 118
4.147Enable OBD II and create a new OBD related DTC with event . . . . . . . . . . 118
4.148Enable WWH-OBD and create a new OBD related DTC with event . . . . . . . 119
4.149Open a project, enable J1939 and create a new J1939 DTC with event . . . . . . 119
4.150Accessing IRuntimeSystemApi as a property . . . . . . . . . . . . . . . . . . . . . 120
4.151Accessing IRuntimeSystemApi in a scope-like way. . . . . . . . . . . . . . . . . 120
4.152Selects all component ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
4.153Selects all unconnected component ports . . . . . . . . . . . . . . . . . . . . . . . 122
4.154Select all unconnected sender/receiver or connected mode-switch component ports123
4.155Tries to auto-map all ports. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
4.156Tries to auto-map all unconnected component ports. . . . . . . . . . . . . . . . 124
4.157Tries to auto-map all unconnected sender/receiver and client/server ports . . . . 124
4.158Tries to auto-map port determined by advanced filter. . . . . . . . . . . . . . . 124
4.159Tries to auto map all unconnected ports to the ports of one component prototype 125
4.160Tries to auto-map all unconnected ports and evaluate matches. . . . . . . . . . 126
4.161Auto-map a component port and realize 1:n connection by using evaluate matches127
4.162Create mapping between two ports which names do not match. . . . . . . . . . . 128
4.163Select all unmapped signal instances . . . . . . . . . . . . . . . . . . . . . . . . . 129
4.164Select all unmapped rx or transformed signal instances . . . . . . . . . . . . . . . 130
4.165Select signal instances using an advanced filter. . . . . . . . . . . . . . . . . . . 130
4.166Auto data map all unmapped signal instances . . . . . . . . . . . . . . . . . . . . 131
4.167Auto data map all unmapped signal instances to unmapped communication ele-ments and evaluate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
4.168Auto data map all signal instances and do not expand nested array elements. . 133
4.169Auto data map all signal instances and expand specific nested array element . . . 134
4.170Select all unmapped delegation port communication elements . . . . . . . . . . . 136
4.171Select communication elements using an advanced filter . . . . . . . . . . . . . . 136
4.172Auto data map all unmapped sender/receiver delegation port communicationelements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.173Auto data map all unmapped communication elements to unmapped rx signalinstances and evaluate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
4.174Autodatamap and do not expand nested array elements . . . . . . . . . . . . . . 139
4.175Autodatamap and do expand a specific nested array element. . . . . . . . . . . 140
4.176Accessing the model export persistency API . . . . . . . . . . . . . . . . . . . . . 141
4.177Export the ActiveEcuc to a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
4.178Export a Post-build selectable project as variant files . . . . . . . . . . . . . . . . 142
4.179Export the project with an exporter . . . . . . . . . . . . . . . . . . . . . . . . . 142
4.180Accessing the model import persistency API . . . . . . . . . . . . . . . . . . . . . 143
4.181Java code usage of the IScriptFactory to contribute script tasks . . . . . . . . . . 147
4.182Accessing WorkflowAPI in Java code . . . . . . . . . . . . . . . . . . . . . . . . . 148
4.183Java Closure creation sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
4.184Run all JUnit tests from one class. . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.185Run all JUnit tests using a Suite . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.186Run unit test with the Spock framework . . . . . . . . . . . . . . . . . . . . . . . 150
4.187Add a UnitTest task with name MyUnitTest. . . . . . . . . . . . . . . . . . . . 150
4.188The projectConfig.gradle file content for unit tests . . . . . . . . . . . . . . . . . 151
5.1Check object visibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
5.2Get all available variants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
5.3Execute code with variant visibility . . . . . . . . . . . . . . . . . . . . . . . . . . 158
© 2016, Vector Informatik GmbH
205 of
207
Listings5.4Get all variants, a specific object is visible in. . . . . . . . . . . . . . . . . . . . 160
5.5Retrieving an InvariantValues model view . . . . . . . . . . . . . . . . . . . . . . 162
5.6Retrieving an InvariantEcucDefView model view . . . . . . . . . . . . . . . . . . 163
5.7Execute code with variant specific changes . . . . . . . . . . . . . . . . . . . . . . 165
5.8Sample code to access element in an Untyped model with DefRefs. . . . . . . . 169
5.9Resolves a Refference traget of an Reference Parameter. . . . . . . . . . . . . . 169
5.10 The value of a GIParameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
5.11 Java: Execute code with creation IModelView of BswmdModel object . . . . . . 172
5.12 Java: Execute code with creation IModelView of BswmdModel object via runnable172
5.13 Java: Execute code with creation IModelView of BswmdModel object . . . . . . 173
5.14 Additional write API methods for EcucGeneral . . . . . . . . . . . . . . . . . . . 175
5.15 EcucCoreDefinition as GICList<EcucCoreDefinition> . . . . . . . . . . . . . . . 176
5.16 Deleting model objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
5.17 Duplication of containers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
5.18 Set parameter values with the BswmdModel Write API. . . . . . . . . . . . . . 177
5.19 Set reference targets with the BswmdModel Write API . . . . . . . . . . . . . . . 177
5.20 DefRef isDefinitionOf methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
5.21 Creation of DefRef with wildcard from EDefRefWildcard. . . . . . . . . . . . . 181
5.22 Getting CeState objects using the BSWMD model . . . . . . . . . . . . . . . . . 182
7.1The automationClasses list in projectConfig.gradle . . . . . . . . . . . . . . . . . 191
7.2DaVinci Configurator build Gradle DSL API . . . . . . . . . . . . . . . . . . . . 192
7.3DaVinci Configurator build Gradle DSL API - useBswmdModel . . . . . . . . . . 192
7.4DaVinci Configurator build Gradle DSL API - useJarSignerDaemon . . . . . . . 192
© 2016, Vector Informatik GmbH
206 of
207
ListingsTodo list© 2016, Vector Informatik GmbH
207 of
207
Document Outline