diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities-toc.xml b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities-toc.xml index 3a47b2eb..e10b1631 100644 --- a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities-toc.xml +++ b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities-toc.xml @@ -1,8 +1,7 @@ - - + @@ -11,7 +10,16 @@ + + + + + + + + + diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.html b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.html index ab40ed56..03186ec4 100644 --- a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.html +++ b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.html @@ -7,256 +7,567 @@

Functionalities

Once the Textual Scenario Add-On is installed, you will be able to edit scenarios in textual mode.

-

Textual Scenario View

-

When creating a new scenario diagram (OES, OAS, IS, FS, ES), the scenario editor is displayed as a separate view. The user shall be able to edit a scenario in the embedded Textual Scenario Editor. If the user has multiple Capella Scenario Diagrams opened, when switching tabs to another Scenario Diagram, the text editor will update with the content from the new diagram and the editor will be linked to the new diagram.

-

Consistency of the data

-

In order to maintain consistency between diagram and text, two buttons are available:

- -

- +

Textual Editor View

+

When creating a new scenario diagram (OES, OAS, IS, FS, ES), the editor is displayed as a separate view. The user shall be able to edit a scenario in the embedded Textual Editor. + If the user has multiple Capella Scenario Diagrams opened, when switching tabs to another Scenario Diagram, the text editor will update with the content from the new diagram and the editor will be linked to the new diagram. + +
+ The embedded Textual Editor can also be opened from the View menu bar: + +

-

Syntax for the Textual Scenario Editor

+

Syntax for the Textual Editor

The syntax supported in the textual editor for IS, FS, ES Capella Scenarios is presented in the following paragraphs.

Participants

-

Depending on the type of scenario (OES, OAS, IS, FS, ES) and the architecture level on which our diagram is located, we can insert instance roles specifying a keyword (actor, component, function etc) and the name of the instance role (currently the parts associated need to already exist).

-

Keywords

- +

Depending on the type of scenario (OES, OAS, IS, FS, ES) and the architectural level, instance roles can be inserted by specifying the keyword (actor, component, configuration_item, entity, role, function, activity) and the name of the instance role. If the represented part for the inserted instance role does not exist, an error is displayed.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Keyword + + Details +
+ actor + It will create an instance role representing an actor; this keyword is available for the IS, ES diagrams at Operational, System, Logical an Physical Level.
+ component + It will create an instance role representing a component; this keyword is available for the IS, ES diagrams at System, Logical and Physical Level.
+ configuration_item + It will create an instance role representing a configuration item. This keyword is available for the IS diagrams at EPBS Level.
+ entity + It will create an instance role representing an entity. This keyword is available for the OES diagrams at Operational Level.
+ role + It will create an instance role representing a role. This keyword is available for the OES diagrams at Operational Level.
+ function + It will create an instance role representing a function. This keyword is available for the FS diagrams.
+ activity + It will create an instance role representing an activity. This keyword is available for the OAS diagrams.

Examples

- +

Messages

-

The user can insert messages between participants assuming the fact that the exchange already exists between the selected source and target participant.

- +

The user can insert messages between defined participants assuming the fact that the exchange already exists between the selected source and the target participant. The following elements and keywords can be used in the textual editor:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Element + + Syntax + + Details + + Examples +
+ sequence message + "source" + -> "target" : "exchange" + Insert a sequence messages between the source and the target instance roles already defined in the text editor. A + sequence message can be declared with + withExecution and + withReturn keywords. + "SA 2" + -> "SA 3" : "msg1" +
+ lost message + "source" + ->o : "exchange" + Insert a lost sequence messages starting on the given source."SA 2" + ->o : "msgLost" +
+ found message + + o-> "target" : "exchange" + Insert a found sequence messages having the given target. This type of message can be use with the + withExecution keyword. + + o-> "SA 3" : "msgFound" +
+ arm timer + + ->> "timeline" : "message" + Add an arm timer on the given timeline. This type of message can be use with the + withExecution keyword. + + ->> "SA 3" : "Arm Timer" +
+ create message + "source" + ->+ "target" : "exchange" + Insert a create messages between the source and the target instance roles already defined in the text editor."SA 2" + ->+ "SA 3" : "cmsg" +
+ delete message + "source" + ->x "target" : "exchange" + Insert a delete messages between the source and the target instance roles already defined in the text editor."SA 2" + ->x "SA 3" : "dmsg" +
+ activate execution + + withExecution + The + withExecution keyword is used to mark that the execution of a message is not immediately ended. The execution will end where the + deactivation message is found. The + withExecution keyword can be used in the same time with the + withReturn keyword. + "SA 2" + -> "SA 3" + withExecution: "msg1" +
+ deactivate execution + + deactivate "target" + The + deactivate keyword is used to mark where a message execution is ending. The + deactivate keyword mandatory if we have a sequence message whose execution is not immediately ended. We must also add the + withExecution keyword on the sequence message if the message requires deactivation. + "SA 2" + -> "SA 3" + withExecution : "msg1" +
+ deactivate "SA 3" +
+ return branch + + withReturn + The + withReturn keyword is used to mark that a message has a return. The + withReturn keyword can be used in the same time with the + withExecution keyword. + "SA 2" + -> "SA 3" + withReturn : "msg1" +
+

Note

+

In Capella, we always activate an execution immediately after each sequence message. In case of a simple message, whose execution ends immediately, the + withExecution and + deactivation keywords are not required. However if we type the + withExecution keyword, we must specify the + deactivation point, otherwise a validation error is displayed in the text editor. +

Examples

- - -
+
- - - -
- -
- - - -
- -

Combined Fragments

-

The user can define a combined fragment from the text using the syntax below:

+

The user can define a combined fragment in text using the syntax below:

+ + + + + + + + + + + + + + + + + + + + + +
+ Element + + Syntax + + Description +
+ ALT + + alt "condition A" + over "timeline1", "timeline2",… { +
+
+
+
[something]
+
+
+
+

} + else "condition B" { +

+
+
+
+
[something_else]
+
+
+
+

} + else "condition C" { +

+
+
+
+
[something_else]
+
+
+
+

}

+
It will insert an ALT type of combined fragment over the given timelines.
+ PAR + + par "condition A" + over "timeline1", "timeline2",… { +
+
+
+
[something]
+
+
+
+

} "condition B" {

+
+
+
+
[something_else]
+
+
+
+

} "condition C" {

+
+
+
+
[something_else]
+
+
+
+

}

+
It will insert a PAR type of combined fragment over the given timelines.
+ OTHER + + LOOP, ASSERT, CONSIDER, CRITICAL, IGNORE, NEG, OPT, SEQ, STRICT, UNSET' + It will insert the given type of combined fragment over the given timelines.
+

Note

-

Examples

+

Example

- +

State. Modes. Allocated Functions

-

The following syntax can be used in order to define state, modes and allocated functions in the textual mode:

+

The use can insert states, modes and allocated functions in the textual editor using the syntax below:

+ + + + + + + + + + + + + + + + + + + + + +
+ Element + + Syntax + + Description +
+ state + + on "Timeline" + state "State_name" + It will insert a state on a given timeline.
+ mode + + on "Timeline" + mode "Mode_name" + It will insert a mode on a given timeline.
+ function + + on "Timeline" + mode "Function_name" + It will insert an allocated function on a given timeline.
+

Example

+

+ + +
+

+

References

+

The following syntax can be used in order to define references in the textual editor:

+ + + + + + + + + + + +
+ Element + + Syntax + + Description +
+ reference + + ref "ref_scenario" + over "timeline1", "timeline2" + It will insert a reference to a scenario over the given timelines.
+

Example

+

+ + +
+

+

Features and limitations of the Textual Editor

+

Consistency of the data

+

In order to maintain consistency between diagram and text, two buttons are available:

-

Examples

- - -
+ +

+

Validation of the data

+

Textual validations are added in the editor, to prevent the user from doing invalid operations.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Validation + + Description +
'Represented part does not exist!' Checks that a represented part exists for the instance role used in the text editor.
'Function does not exist!' Checks that the function exists.
'<keyword> can not be used in this diagram!'Check that the participant keyword can be used in the type of scenario diagram. <keyword> can be any participant: actor, component, entity, function, activiy, role, configuration_item. Ex: actor cannot be used in the FS diagrams.
'Duplicated participant!'Checks that only a timeline of the same instance role is used.
'Timeline not defined in text editor!'Checks that the given timeline involved in message, state fragments, combined fragments is defined in the text editor as participant.
'Exchange does not exist between <source> and <target>!'Checks that an exchange exists between the given source and target in a sequence message.
'Exchange does not exist from <source>!'Checks that an exchange exists starting on the given source in a lost message.
'Exchange does not exist to <target>!'Checks that an exchange exists to the given target in a lost found.
'Exchange type can not be used, expected <type>'Checks that a type of exchange (Component Exchange or Functional Exchange) is used in a ES diagram. <type> can be CE or FE, if one of them is used, then the user can only add a type of exchange.
'Deactivation keyword expected for a withExecution message!'Checks that a withExecution message is closed by a deacitvation on the given target timeline.
'Deactivation keyword not expected!'Checks that the activation keyword is put after a withExecution message and that the deactivated target is the one specified in the withExecution message.
'Create or delete message can not be used in this diagram!'Checks that a create or a delete message are used only in the allowed diagrams.
'Arm Timer can not be used in this diagram!'Checks that an arm timer message is used only in the allowed diagrams.
'Lost message can not be used in this diagram!'Checks that a lost message is used only in the allowed diagrams.
'Found message can not be used in this diagram!'Checks that a found message is used only in the allowed diagrams.
'Invalid element! Source and target must be different!'Checks that the source and target involved in a sequence message are different.
'Element <timeline> can not be used at this point! A delete message was already defined on this timeline.'Checks that a delete message on the given timeline was not encountered before using it in the current point. Cannot use the timeline after a delete occured on the timeline.
'Target <target> can not be used in a create message at this point! Other operations were already defined on this timeline.'Checks that a create message is the first event occuring on a timeline.
'This <state_fragment> does not exist or is not available for <timeline>'Checks that a state, mode, allocated function, can be used on the given timeline.
'Expected else keyword!'Checks that the 'else' keyword is present for the 'alt' combined fragment.
'Unexpected keyword!'Shows an error if the keyword is not expected before expression of an operand in a combined fragment. Ex: 'else' keyword not expected for other that 'alt'.
'Timelines covered by this <combined_fragment_type> must be a subset of the parent covered timelines'Checks that the covered timelines in an inner combined fragment is a subset of the covered timelines in the parent combined fragment.
'Timeline not covered by this <combined_fragment_type>!'Checks that the timelines involved in a message that belongs to a combine fragment are covered by the combined fragment.
'Duplicated timeline!'Checks that a timeline is not duplicated when using it over a reference.
'Referenced scenario does not exist!'Checks that a referenced scenario exists.
'Timelines covered by this reference must be a subset of the parent covered timelines'Checks that the timelines in a reference are a subset of the parent container covered timelines.
+

Autocompletion

+

The user can use + Ctrl+Space to see suggestions of the allowed keywords in the editor or proposals of the elements that can be used.

+

Limitations

+

Multiple lifelines of the same instance role is not enabled.

\ No newline at end of file diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.mediawiki b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.mediawiki index 92729e37..8b73f560 100644 --- a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.mediawiki +++ b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Functionalities.mediawiki @@ -15,110 +15,302 @@ Once the Textual Scenario Add-On is installed, you will be able to edit scenarios in textual mode. -==Textual Scenario View== +==Textual Editor View== -When creating a new scenario diagram (OES, OAS, IS, FS, ES), the scenario editor is displayed as a separate view. The user shall be able to edit a scenario in the embedded Textual Scenario Editor. If the user has multiple Capella Scenario Diagrams opened, when switching tabs to another Scenario Diagram, the text editor will update with the content from the new diagram and the editor will be linked to the new diagram. - -===Consistency of the data=== -In order to maintain consistency between diagram and text, two buttons are available: -* ''' refresh button ''': on pressing the refresh button, the text editor is updated with the data from the diagram -* ''' save button ''': on pressing the save button, the diagram is updated with the content described by the textual scenario associated to the current diagram -[[Image:Images/IS_System_SyncButtons.png|center|760px]] +When creating a new scenario diagram (OES, OAS, IS, FS, ES), the editor is displayed as a separate view. The user shall be able to edit a scenario in the embedded Textual Editor. +If the user has multiple Capella Scenario Diagrams opened, when switching tabs to another Scenario Diagram, the text editor will update with the content from the new diagram and the editor will be linked to the new diagram. +
+The embedded Textual Editor can also be opened from the View menu bar: +[[Image:Images/View_TextualEditor.png]] -==Syntax for the Textual Scenario Editor== +==Syntax for the Textual Editor== The syntax supported in the textual editor for IS, FS, ES Capella Scenarios is presented in the following paragraphs. ===Participants=== -Depending on the type of scenario (OES, OAS, IS, FS, ES) and the architecture level on which our diagram is located, we can insert instance roles specifying a keyword (actor, component, function etc) and the name of the instance role (currently the parts associated need to already exist). +Depending on the type of scenario (OES, OAS, IS, FS, ES) and the architectural level, instance roles can be inserted by specifying the keyword (actor, component, configuration_item, entity, role, function, activity) and the name of the instance role. If the represented part for the inserted instance role does not exist, an error is displayed. -====Keywords==== -* ''' actor ''': it will create an instance role representing an actor; this keyword is available for IS, ES diagrams at Operational, System, Logical and Physical Level. -* ''' component ''': it will create an instance role representing a component; this keyword is available for IS, ES diagrams at System, Logical and Physical Level. -* ''' configuration_item ''': it will create an instance role representing a configuration item; this keyword is available for IS diagrams at EPBS Level. -* ''' entity ''': it will create an instance role representing an entity; this keyword is available for OES diagrams at Operational Level. -* ''' role ''': it will create an instance role representing a role; this keyword is available for OES diagrams at Operational Level. -* ''' function ''': it will create an instance role representing a function; this keyword is available for FS diagrams. -* ''' activity ''': it will create an instance role representing an activity; this keyword is available for OAS diagrams. +{| border="1" +|- +| ''' Keyword ''' +| ''' Details ''' +|- +| ''' actor ''' +| It will create an instance role representing an actor; this keyword is available for the IS, ES diagrams at Operational, System, Logical an Physical Level. +|- +| ''' component ''' +| It will create an instance role representing a component; this keyword is available for the IS, ES diagrams at System, Logical and Physical Level. +|- +| ''' configuration_item ''' +| It will create an instance role representing a configuration item. This keyword is available for the IS diagrams at EPBS Level. +|- +| ''' entity ''' +| It will create an instance role representing an entity. This keyword is available for the OES diagrams at Operational Level. +|- +| ''' role ''' +| It will create an instance role representing a role. This keyword is available for the OES diagrams at Operational Level. +|- +| ''' function ''' +| It will create an instance role representing a function. This keyword is available for the FS diagrams. +|- +| ''' activity ''' +| It will create an instance role representing an activity. This keyword is available for the OAS diagrams. +|} ====Examples==== -[[Image:Images/Keywords_Participants_Examples.png|center]] +[[Image:Images/Keywords_Participants_Examples.png]] ===Messages=== -The user can insert messages between participants assuming the fact that the exchange already exists between the selected source and target participant. - -* ''' sequence messages ''': it will add a sequence messages between the source and the target instance roles which shall already exist, otherwise a validation error is displayed. -** ''' source_ir" -> "target_ir" : "msg" ''' -** example: -::: "A 1" -> "A 2" : "exec" -* ''' activate execution ''': in Capella, we always activate an execution after each sequence message '''' -> ''''; each sequence message implies an activation -* ''' deactivate execution ''': the '''' deactivate '''' keyword is used to deactivate a message; if we have a simple sequence message which ends immediately, the deactivation keyword is not required; if we have a sequence messages that ends later, we shall add the '''' withExecution '''' keyword and it is mandatory to deactivate the message when needed. -** example: -::: "A 1" -> "A 2" ''' withExecution ''' : "exec" -::: "A 2" -> "A 3" -::: '''deactivate''' "A 2" -* ''' return branch ''': to mark that a message has a return, the '''withReturn''' keyword can be used; if the message does not return immediately and other events occur on its execution, then the '''withExecution''' keyword can be used in the same time with the '''withReturn''' keyword to mark that the current message is a complex message and has a return. -* ''' create messages ''': it will add a create message between the source and the target instance roles which shall already exist, otherwise a validation error is displayed. -** ''' "source_ir" ->+ "target_ir" : "msg" ''' -** example: -::: "A 1" ->+ "A 2" : "msg" -* ''' delete messages ''': it will add a delete messages between the source and the target instance roles which shall already exist, otherwise a validation error is displayed. -** ''' "source_ir" ->x "target_ir" : "msg" ''' -** example: -:::"A 1" ->x "A 2" : "msg" -* ''' arm timer ''': it will add an arm timer on the given timeline. -** ''' ->> "timeline" : "msg" ''' -** example: -::: ->> "A 1" : "arm_timer" +The user can insert messages between defined participants assuming the fact that the exchange already exists between the selected source and the target participant. The following elements and keywords can be used in the textual editor: + +{| border="1" +|- +| style="width:140px;" | ''' Element ''' +| style="width:220px;" | ''' Syntax ''' +| ''' Details ''' +| style="width:170px;" | ''' Examples ''' +|- +| ''' sequence message ''' +| "source" '''->''' "target" : "exchange" +| Insert a sequence messages between the source and the target instance roles already defined in the text editor. A '''sequence message''' can be declared with '''withExecution''' and '''withReturn''' keywords. +| "SA 2" '''->''' "SA 3" : "msg1" +|- +| ''' lost message ''' +| "source" '''->o''' : "exchange" +| Insert a lost sequence messages starting on the given source. +| "SA 2" '''->o''' : "msgLost" +|- +| ''' found message ''' +| '''o->''' "target" : "exchange" +| Insert a found sequence messages having the given target. This type of message can be use with the '''withExecution''' keyword. +| '''o->''' "SA 3" : "msgFound" +|- +| ''' arm timer ''' +| '''->>''' "timeline" : "message" +| Add an arm timer on the given timeline. This type of message can be use with the '''withExecution''' keyword. +| '''->>''' "SA 3" : "Arm Timer" +|- +| ''' create message ''' +| "source" '''->+''' "target" : "exchange" +| Insert a create messages between the source and the target instance roles already defined in the text editor. +| "SA 2" '''->+''' "SA 3" : "cmsg" +|- +| ''' delete message ''' +| "source" '''->x''' "target" : "exchange" +| Insert a delete messages between the source and the target instance roles already defined in the text editor. +| "SA 2" '''->x''' "SA 3" : "dmsg" +|- +| ''' activate execution ''' +| ''' withExecution ''' +| The '''withExecution''' keyword is used to mark that the execution of a message is not immediately ended. The execution will end where the '''deactivation''' message is found. The '''withExecution''' keyword can be used in the same time with the '''withReturn''' keyword. +| "SA 2" '''->''' "SA 3" '''withExecution''': "msg1" +|- +| ''' deactivate execution ''' +| ''' deactivate ''' "target" +| The '''deactivate''' keyword is used to mark where a message execution is ending. The '''deactivate''' keyword mandatory if we have a sequence message whose execution is not immediately ended. We must also add the '''withExecution''' keyword on the sequence message if the message requires deactivation. +| "SA 2" '''->''' "SA 3" '''withExecution''' : "msg1"
'''deactivate''' "SA 3" +|- +| ''' return branch ''' +| ''' withReturn ''' +| The '''withReturn''' keyword is used to mark that a message has a return. The '''withReturn''' keyword can be used in the same time with the '''withExecution''' keyword. +| "SA 2" '''->''' "SA 3" '''withReturn''' : "msg1" +|} + +==== Note ==== +In Capella, we always activate an execution immediately after each sequence message. In case of a simple message, whose execution ends immediately, the '''withExecution''' and '''deactivation''' keywords are not required. However if we type the '''withExecution''' keyword, we must specify the '''deactivation''' point, otherwise a validation error is displayed in the text editor. + ==== Examples ==== -[[Image:Images/IS_System_SeqMessages.png|center]] -
-
-[[Image:Images/IS_System_SeqMessages_FE.png|center]] -
+[[Image:Images/ES_FS_Logical_Messages.png]]
-[[Image:Images/OAS_OA_SeqMessages_Interaction.png|center]] -
-[[Image:Images/FS_WithReturn_WithExecution.png|center]] ===Combined Fragments=== -The user can define a combined fragment from the text using the syntax below: -* for '''ALT''': -::: '''alt''' condition A '''over''' timeline1, timeline2, { -::::[something] -:::} '''else''' condition B { -::::[something_else] -:::} '''else''' condition C { -::::[something_else] -:::} -* for the other combined fragments: '''PAR, LOOP, ASSERT, CONSIDER, CRITICAL, IGNORE, NEG, OPT, SEQ, STRICT, UNSET'''': -::: '''par''' condition A '''over''' timeline1, timeline2, { -::::[something] -:::} condition B { -::::[something_else] -:::} condition C { -::::[something_else] -:::} +The user can define a combined fragment in text using the syntax below: +{| border="1" +|- +| ''' Element ''' +| ''' Syntax ''' +| ''' Description ''' +|- +| ''' ALT ''' +| '''alt''' "condition A" '''over''' "timeline1", "timeline2", { +::[something] +} '''else''' "condition B" { +::[something_else] +} '''else''' "condition C" { +::[something_else] +} +| It will insert an ALT type of combined fragment over the given timelines. +|- +| ''' PAR ''' +| '''par''' "condition A" '''over''' "timeline1", "timeline2", { +::[something] +} "condition B" { +::[something_else] +} "condition C" { +::[something_else] +} +| It will insert a PAR type of combined fragment over the given timelines. +|- +| ''' OTHER ''' +| '''LOOP, ASSERT, CONSIDER, CRITICAL, IGNORE, NEG, OPT, SEQ, STRICT, UNSET'''' +| It will insert the given type of combined fragment over the given timelines. +|} -==== Examples ==== +==== Note ==== +* For the other combined fragments: '''LOOP, ASSERT, CONSIDER, CRITICAL, IGNORE, NEG, OPT, SEQ, STRICT, UNSET''' the syntax is similar to '''PAR''' +* The condition is optional. -[[Image:Images/ES_Combined_Fragments.png|center]] +==== Example ==== + +[[Image:Images/ES_Combined_Fragments.png]]
===State. Modes. Allocated Functions=== -The following syntax can be used in order to define state, modes and allocated functions in the textual mode: -* state -**'''on''' Timeline '''state''' State_name -* mode -**'''on''' Timeline '''mode''' Mode_name -* allocated functions -**'''on''' Timeline '''function''' Function_name +The use can insert states, modes and allocated functions in the textual editor using the syntax below: +{| border="1" +|- +| ''' Element ''' +| ''' Syntax ''' +| ''' Description ''' +|- +| ''' state ''' +| '''on''' "Timeline" '''state''' "State_name" +| It will insert a state on a given timeline. +|- +| ''' mode ''' +| '''on''' "Timeline" '''mode''' "Mode_name" +| It will insert a mode on a given timeline. +|- +| ''' function ''' +| '''on''' "Timeline" '''mode''' "Function_name" +| It will insert an allocated function on a given timeline. +|} -==== Examples ==== +==== Example ==== -[[Image:Images/ES_FS_States_Modes_AllocFunctions.png|center]] +[[Image:Images/ES_FS_States_Modes_AllocFunctions.png]]
+===References=== +The following syntax can be used in order to define references in the textual editor: +{| border="1" +|- +| ''' Element ''' +| ''' Syntax ''' +| ''' Description ''' +|- +| ''' reference ''' +| '''ref''' "ref_scenario" '''over''' "timeline1", "timeline2" +| It will insert a reference to a scenario over the given timelines. +|} + +==== Example ==== + +[[Image:Images/ES_References.png]] +
+ +== Features and limitations of the Textual Editor == + +===Consistency of the data=== +In order to maintain consistency between diagram and text, two buttons are available: +* ''' refresh button ''': on pressing the refresh button, the text editor is updated with the data from the diagram +* ''' save button ''': on pressing the save button, the diagram is updated with the content described by the textual scenario associated to the current diagram +[[Image:Images/IS_System_SyncButtons.png]] + +===Validation of the data=== +Textual validations are added in the editor, to prevent the user from doing invalid operations. + +{| border="1" +|- +| ''' Validation ''' +| ''' Description ''' +|- +| 'Represented part does not exist!' +| Checks that a represented part exists for the instance role used in the text editor. +|- +| 'Function does not exist!' +| Checks that the function exists. +|- +| ' can not be used in this diagram!' +| Check that the participant keyword can be used in the type of scenario diagram. can be any participant: actor, component, entity, function, activiy, role, configuration_item. Ex: actor cannot be used in the FS diagrams. +|- +| 'Duplicated participant!' +| Checks that only a timeline of the same instance role is used. +|- +| 'Timeline not defined in text editor!' +| Checks that the given timeline involved in message, state fragments, combined fragments is defined in the text editor as participant. +|- +| 'Exchange does not exist between and !' +| Checks that an exchange exists between the given source and target in a sequence message. +|- +| 'Exchange does not exist from !' +| Checks that an exchange exists starting on the given source in a lost message. +|- +| 'Exchange does not exist to !' +| Checks that an exchange exists to the given target in a lost found. +|- +| 'Exchange type can not be used, expected ' +| Checks that a type of exchange (Component Exchange or Functional Exchange) is used in a ES diagram. can be CE or FE, if one of them is used, then the user can only add a type of exchange. +|- +| 'Deactivation keyword expected for a withExecution message!' +| Checks that a withExecution message is closed by a deacitvation on the given target timeline. +|- +| 'Deactivation keyword not expected!' +| Checks that the activation keyword is put after a withExecution message and that the deactivated target is the one specified in the withExecution message. +|- +| 'Create or delete message can not be used in this diagram!' +| Checks that a create or a delete message are used only in the allowed diagrams. +|- +| 'Arm Timer can not be used in this diagram!' +| Checks that an arm timer message is used only in the allowed diagrams. +|- +| 'Lost message can not be used in this diagram!' +| Checks that a lost message is used only in the allowed diagrams. +|- +| 'Found message can not be used in this diagram!' +| Checks that a found message is used only in the allowed diagrams. +|- +| 'Invalid element! Source and target must be different!' +| Checks that the source and target involved in a sequence message are different. +|- +| 'Element can not be used at this point! A delete message was already defined on this timeline.' +| Checks that a delete message on the given timeline was not encountered before using it in the current point. Cannot use the timeline after a delete occured on the timeline. +|- +| 'Target can not be used in a create message at this point! Other operations were already defined on this timeline.' +| Checks that a create message is the first event occuring on a timeline. +|- +| 'This does not exist or is not available for ' +| Checks that a state, mode, allocated function, can be used on the given timeline. +|- +| 'Expected else keyword!' +| Checks that the 'else' keyword is present for the 'alt' combined fragment. +|- +| 'Unexpected keyword!' +| Shows an error if the keyword is not expected before expression of an operand in a combined fragment. Ex: 'else' keyword not expected for other that 'alt'. +|- +| 'Timelines covered by this must be a subset of the parent covered timelines' +| Checks that the covered timelines in an inner combined fragment is a subset of the covered timelines in the parent combined fragment. +|- +| 'Timeline not covered by this !' +| Checks that the timelines involved in a message that belongs to a combine fragment are covered by the combined fragment. +|- +| 'Duplicated timeline!' +| Checks that a timeline is not duplicated when using it over a reference. +|- +| 'Referenced scenario does not exist!' +| Checks that a referenced scenario exists. +|- +| 'Timelines covered by this reference must be a subset of the parent covered timelines' +| Checks that the timelines in a reference are a subset of the parent container covered timelines. +|} + +===Autocompletion=== + +The user can use '''Ctrl+Space''' to see suggestions of the allowed keywords in the editor or proposals of the elements that can be used. + +===Limitations=== + +Multiple lifelines of the same instance role is not enabled. \ No newline at end of file diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_Combined_Fragments.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_Combined_Fragments.png index 09019fd1..7a9248a1 100644 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_Combined_Fragments.png and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_Combined_Fragments.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_Logical_Messages.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_Logical_Messages.png new file mode 100644 index 00000000..2551de10 Binary files /dev/null and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_Logical_Messages.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_States_Modes_AllocFunctions.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_States_Modes_AllocFunctions.png index a61dee7b..9d9776c4 100644 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_States_Modes_AllocFunctions.png and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_FS_States_Modes_AllocFunctions.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_References.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_References.png new file mode 100644 index 00000000..8f6b6cd9 Binary files /dev/null and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/ES_References.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/FS_WithReturn_WithExecution.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/FS_WithReturn_WithExecution.png deleted file mode 100644 index 640d4708..00000000 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/FS_WithReturn_WithExecution.png and /dev/null differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages.png index c8d9bfbe..1b3d6eb1 100644 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages.png and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages_FE.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages_FE.png deleted file mode 100644 index 6f770491..00000000 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SeqMessages_FE.png and /dev/null differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SyncButtons.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SyncButtons.png index 510d3d9b..b8eab620 100644 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SyncButtons.png and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/IS_System_SyncButtons.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/Keywords_Participants_Examples.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/Keywords_Participants_Examples.png index 11e501f7..920a26d4 100644 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/Keywords_Participants_Examples.png and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/Keywords_Participants_Examples.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/OAS_OA_SeqMessages_Interaction.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/OAS_OA_SeqMessages_Interaction.png index 24a4d340..f83050ab 100644 Binary files a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/OAS_OA_SeqMessages_Interaction.png and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/OAS_OA_SeqMessages_Interaction.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/View_TextualEditor.png b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/View_TextualEditor.png new file mode 100644 index 00000000..83b86598 Binary files /dev/null and b/plugins/org.polarsys.capella.scenario.editor.doc/html/TextualEditor/Images/View_TextualEditor.png differ diff --git a/plugins/org.polarsys.capella.scenario.editor.dsl.ui/src/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.xtend b/plugins/org.polarsys.capella.scenario.editor.dsl.ui/src/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.xtend index 5938a4e2..665de27d 100644 --- a/plugins/org.polarsys.capella.scenario.editor.dsl.ui/src/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.xtend +++ b/plugins/org.polarsys.capella.scenario.editor.dsl.ui/src/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.xtend @@ -43,6 +43,9 @@ import org.polarsys.capella.scenario.editor.dsl.textualScenario.Reference import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostMessage import org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage import org.polarsys.capella.core.data.fa.FunctionalExchange +import java.util.List +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Element +import java.util.ArrayList /** * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist @@ -126,19 +129,6 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } } - /* - * propose a list with the timelines (for adding states, modes or allocated functions) - */ - def getExistingTimelines(String keyword, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - for (el : EmbeddedEditorInstanceHelper.getAvailableElements(keyword)) { - var elementName = CapellaElementExt.getName(el) - - var proposal = createCompletionProposal("\"" + elementName + "\"", elementName, null, - context) as ConfigurableCompletionProposal - acceptor.accept(proposal); - } - } - /* * check if a participant is already used in the text */ @@ -191,7 +181,7 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro // if the type of exchange is allowed, propose it var exchangeType = TextualScenarioHelper.getExchangeType(element) if (scenarioExchangesType === null || scenarioExchangesType.equals(exchangeType)) { - var message = "\"" + elementName + "\"" + var message = elementName if (EmbeddedEditorInstanceHelper.isESScenario() && element instanceof FunctionalExchange) { message = message + " : FE [ " + EmbeddedEditorInstanceHelper.getSourceFunctionNameOfExchange(element as FunctionalExchange) + @@ -258,7 +248,7 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro override completeParticipantDeactivation_Name(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { var modelContainer = TextualScenarioHelper.getModelContainer(model as ParticipantDeactivation) var timelinesToPropose = new HashMap - createTimelinesHashMapToProposeForDeactivation(model as ParticipantDeactivation, modelContainer as Model, timelinesToPropose) + createTimelinesHashMapToProposeForDeactivation(model as ParticipantDeactivation, TextualScenarioHelper.getAllElements(modelContainer, new ArrayList), timelinesToPropose) for (String timelineToPropose : timelinesToPropose.keySet) { if (timelinesToPropose.get(timelineToPropose) >= 1) { @@ -269,8 +259,8 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } } - def createTimelinesHashMapToProposeForDeactivation(ParticipantDeactivation participantDeactivation, EObject modelContainer, HashMap timelinesToPropose) { - var elements = TextualScenarioHelper.getElements(modelContainer) + def createTimelinesHashMapToProposeForDeactivation(ParticipantDeactivation participantDeactivation, + List elements, HashMap timelinesToPropose) { for (var i = 0; i < elements.size; i++) { if (elements.get(i).equals(participantDeactivation)) { for (var j = 0; j <= i; j++) { @@ -278,13 +268,6 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } return timelinesToPropose } - if (elements.get(i) instanceof CombinedFragment) { - createTimelinesHashMapToProposeForDeactivation(participantDeactivation, elements.get(i) as CombinedFragment, timelinesToPropose) - } - - if (elements.get(i) instanceof Operand) { - createTimelinesHashMapToProposeForDeactivation(participantDeactivation, elements.get(i) as Operand, timelinesToPropose) - } } return timelinesToPropose } @@ -296,12 +279,21 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro if (element instanceof ArmTimerMessage) { updateHashMapWithArmTimerMessage(timelinesToPropose, element as ArmTimerMessage) } + + if (element instanceof FoundMessage) { + updateHashMapWithFoundMessage(timelinesToPropose, element as FoundMessage) + } if (element instanceof ParticipantDeactivation) { updateHashMapWithParticipantDeactivation(timelinesToPropose, element as ParticipantDeactivation) } } + /* + * Update HashMap with the target of Sequence Message + * If the hashMap already contains the target (as key), increment with 1 the actual value + * If the hashMap doesn't contain the target, add the target as key and set its value to 1 + */ def updateHashMapWithSequenceMessage(HashMap timelinesToPropose, SequenceMessage sequenceMessage) { if (sequenceMessage.execution !== null) { if (timelinesToPropose.containsKey(sequenceMessage.target)) { @@ -313,6 +305,11 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } } + /* + * Update HashMap with the participant of ArmTimer Message + * If the hashMap already contains the participant (as key), increment with 1 the actual value + * If the hashMap doesn't contain the participant, add the participant as key and set its value to 1 + */ def updateHashMapWithArmTimerMessage(HashMap timelinesToPropose, ArmTimerMessage armTimer) { if (armTimer.execution !== null) { if (timelinesToPropose.containsKey(armTimer.participant)) { @@ -324,6 +321,26 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } } + /* + * Update HashMap with the target of Found Message + * If the hashMap already contains the target (as key), increment with 1 the actual value + * If the hashMap doesn't contain the target, add the target as key and set its value to 1 + */ + def updateHashMapWithFoundMessage(HashMap timelinesToPropose, FoundMessage foundMessage) { + if (foundMessage.execution !== null) { + if (timelinesToPropose.containsKey(foundMessage.target)) { + var value = timelinesToPropose.get(foundMessage.target) + value = (value as Integer) + 1 + } else { + timelinesToPropose.put(foundMessage.target, 1) + } + } + } + + /* + * Update HashMap with the deactivation + * Decrement with 1 the actual value of the deactivation name (timeline) + */ def updateHashMapWithParticipantDeactivation(HashMap timelinesToPropose, ParticipantDeactivation participantDeactivation) { if (timelinesToPropose.containsKey(participantDeactivation.name)) { var value = timelinesToPropose.get(participantDeactivation.name) @@ -389,12 +406,10 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro override completeStateFragment_Timeline(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - var keywords = #[DslConstants.ACTOR, DslConstants.ACTIVITY, DslConstants.FUNCTION, DslConstants.ROLE, - DslConstants.ENTITY, DslConstants.ROLE, DslConstants.COMPONENT, DslConstants.CONFIGURATION_ITEM] - for (String keyword : keywords) { - if (EmbeddedEditorInstanceHelper.checkValidKeyword(keyword)) { - getExistingTimelines(keyword, context, acceptor) - } + for (EObject el : TextualScenarioHelper.participantsDefinedBefore(context.rootModel as Model)) { + acceptor.accept( + createCompletionProposal("\"" + (el as Participant).name + "\"", (el as Participant).name, null, + context)) } } @@ -417,7 +432,7 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro for (String stateFragment : EmbeddedEditorInstanceHelper.getAvailableStateFragments( (model as StateFragment).keyword, (model as StateFragment).timeline)) { acceptor.accept( - createCompletionProposal("\"" + stateFragment + "\"", "\"" + stateFragment + "\"", null, context)) + createCompletionProposal("\"" + stateFragment + "\"", stateFragment, null, context)) } } @@ -440,12 +455,15 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } } - override completeReference_Timelines(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + override completeReference_Timelines(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { for (EObject el : TextualScenarioHelper.participantsDefinedBefore(context.rootModel as Model)) { - if (!(model as Reference).timelines.contains((el as Participant).name)) { - acceptor.accept( - createCompletionProposal("\"" + (el as Participant).name + "\"", (el as Participant).name, null, - context)) + if (model instanceof Reference) { + if (!(model as Reference).timelines.contains((el as Participant).name)) { + acceptor.accept( + createCompletionProposal("\"" + (el as Participant).name + "\"", (el as Participant).name, null, + context)) + } } } } @@ -476,7 +494,7 @@ class TextualScenarioProposalProvider extends AbstractTextualScenarioProposalPro } if (elementName !== null) { acceptor.accept( - createCompletionProposal("\"" + elementName + "\"", "\"" + elementName + "\"", null, context)) + createCompletionProposal("\"" + elementName + "\"", elementName, null, context)) } } } diff --git a/plugins/org.polarsys.capella.scenario.editor.dsl.ui/xtend-gen/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.java b/plugins/org.polarsys.capella.scenario.editor.dsl.ui/xtend-gen/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.java index 4696b66b..fca23fba 100644 --- a/plugins/org.polarsys.capella.scenario.editor.dsl.ui/xtend-gen/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.java +++ b/plugins/org.polarsys.capella.scenario.editor.dsl.ui/xtend-gen/org/polarsys/capella/scenario/editor/dsl/ui/contentassist/TextualScenarioProposalProvider.java @@ -1,15 +1,3 @@ -/******************************************************************************* - * Copyright (c) 2020 THALES GLOBAL SERVICES. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Thales - initial API and implementation - ******************************************************************************/ /** * Copyright (c) 2020 THALES GLOBAL SERVICES. * @@ -27,7 +15,6 @@ import com.google.common.base.Objects; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Set; @@ -45,6 +32,7 @@ import org.polarsys.capella.core.data.epbs.EPBSArchitecture; import org.polarsys.capella.core.data.fa.FunctionalExchange; import org.polarsys.capella.core.data.information.AbstractEventOperation; +import org.polarsys.capella.core.data.information.ExchangeItem; import org.polarsys.capella.core.model.helpers.CapellaElementExt; import org.polarsys.capella.scenario.editor.dsl.helpers.TextualScenarioHelper; import org.polarsys.capella.scenario.editor.dsl.textualScenario.ArmTimerMessage; @@ -55,7 +43,6 @@ import org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage; import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostMessage; import org.polarsys.capella.scenario.editor.dsl.textualScenario.Model; -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Operand; import org.polarsys.capella.scenario.editor.dsl.textualScenario.Participant; import org.polarsys.capella.scenario.editor.dsl.textualScenario.ParticipantDeactivation; import org.polarsys.capella.scenario.editor.dsl.textualScenario.Reference; @@ -78,15 +65,18 @@ public class TextualScenarioProposalProvider extends AbstractTextualScenarioProp */ @Override public void completeKeyword(final Keyword keyword, final ContentAssistContext contentAssistContext, final ICompletionProposalAcceptor acceptor) { - boolean _isParticipantKeyword = TextualScenarioHelper.isParticipantKeyword(keyword.getValue()); + String _value = keyword.getValue(); + boolean _isParticipantKeyword = TextualScenarioHelper.isParticipantKeyword(_value); if (_isParticipantKeyword) { - boolean _checkValidKeyword = EmbeddedEditorInstanceHelper.checkValidKeyword(keyword.getValue()); + String _value_1 = keyword.getValue(); + boolean _checkValidKeyword = EmbeddedEditorInstanceHelper.checkValidKeyword(_value_1); if (_checkValidKeyword) { super.completeKeyword(keyword, contentAssistContext, acceptor); } } else { final String[] messageKeywords = { "->", "->x", "->+", "->>", "->o", "o->" }; - boolean _contains = ((List)Conversions.doWrapArray(messageKeywords)).contains(keyword.getValue()); + String _value_2 = keyword.getValue(); + boolean _contains = ((List)Conversions.doWrapArray(messageKeywords)).contains(_value_2); boolean _not = (!_contains); if (_not) { super.completeKeyword(keyword, contentAssistContext, acceptor); @@ -150,21 +140,6 @@ public void getExistingParticipants(final String keyword, final ContentAssistCon } } - /** - * propose a list with the timelines (for adding states, modes or allocated functions) - */ - public void getExistingTimelines(final String keyword, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { - Collection _availableElements = EmbeddedEditorInstanceHelper.getAvailableElements(keyword); - for (final EObject el : _availableElements) { - { - String elementName = CapellaElementExt.getName(el); - ICompletionProposal _createCompletionProposal = this.createCompletionProposal((("\"" + elementName) + "\""), elementName, null, context); - ConfigurableCompletionProposal proposal = ((ConfigurableCompletionProposal) _createCompletionProposal); - acceptor.accept(proposal); - } - } - } - /** * check if a participant is already used in the text */ @@ -185,7 +160,8 @@ public void completeSequenceMessage_Source(final EObject model, final Assignment @Override public void completeSequenceMessage_Arrow(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { - acceptor.accept(this.createCompletionProposal("->", "-> : Sequence Message", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("->", "-> : Sequence Message", null, context); + acceptor.accept(_createCompletionProposal); } @Override @@ -196,12 +172,15 @@ public void completeSequenceMessage_Target(final EObject model, final Assignment @Override public void completeSequenceMessage_Name(final EObject messageObj, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { SequenceMessage message = ((SequenceMessage) messageObj); - this.createMessageProposal(message.getSource(), message.getTarget(), context, acceptor); + String _source = message.getSource(); + String _target = message.getTarget(); + this.createMessageProposal(_source, _target, context, acceptor); } public void createMessageProposal(final String source, final String target, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { EObject _rootModel = context.getRootModel(); - Object scenarioExchangesType = TextualScenarioHelper.getScenarioAllowedExchangesType(((Model) _rootModel).getElements()); + EList _elements = ((Model) _rootModel).getElements(); + Object scenarioExchangesType = TextualScenarioHelper.getScenarioAllowedExchangesType(_elements); List exchangesAvailable = EmbeddedEditorInstanceHelper.getExchangeMessages(source, target); String elementName = new String(); for (final EObject element : exchangesAvailable) { @@ -210,13 +189,16 @@ public void createMessageProposal(final String source, final String target, fina ((Model) _rootModel_1).getElements(); boolean _isInterfaceScenario = EmbeddedEditorInstanceHelper.isInterfaceScenario(); if (_isInterfaceScenario) { - elementName = CapellaElementExt.getName(((ExchangeItemAllocation) element).getAllocatedItem()); + ExchangeItem _allocatedItem = ((ExchangeItemAllocation) element).getAllocatedItem(); + String _name = CapellaElementExt.getName(_allocatedItem); + elementName = _name; } else { - elementName = CapellaElementExt.getName(element); + String _name_1 = CapellaElementExt.getName(element); + elementName = _name_1; } String exchangeType = TextualScenarioHelper.getExchangeType(element); if (((scenarioExchangesType == null) || scenarioExchangesType.equals(exchangeType))) { - String message = (("\"" + elementName) + "\""); + String message = elementName; if ((EmbeddedEditorInstanceHelper.isESScenario() && (element instanceof FunctionalExchange))) { String _sourceFunctionNameOfExchange = EmbeddedEditorInstanceHelper.getSourceFunctionNameOfExchange(((FunctionalExchange) element)); String _plus = ((message + " : FE [ ") + _sourceFunctionNameOfExchange); @@ -227,8 +209,8 @@ public void createMessageProposal(final String source, final String target, fina String _plus_3 = (_plus_2 + " ]"); message = _plus_3; } - acceptor.accept( - this.createCompletionProposal((("\"" + elementName) + "\""), message, null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal((("\"" + elementName) + "\""), message, null, context); + acceptor.accept(_createCompletionProposal); } } } @@ -237,10 +219,12 @@ public void createMessageProposal(final String source, final String target, fina @Override public void completeCreateMessage_Arrow(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { if (((!EmbeddedEditorInstanceHelper.isFSScenario()) && (!EmbeddedEditorInstanceHelper.isESScenario()))) { - acceptor.accept(this.createCompletionProposal("->+", "->+ : Create Message", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("->+", "->+ : Create Message", null, context); + acceptor.accept(_createCompletionProposal); } if ((EmbeddedEditorInstanceHelper.isInteractionScenario() && (!EmbeddedEditorInstanceHelper.isFSScenario()))) { - acceptor.accept(this.createCompletionProposal("->+", "->+ : Create Message", null, context)); + ICompletionProposal _createCompletionProposal_1 = this.createCompletionProposal("->+", "->+ : Create Message", null, context); + acceptor.accept(_createCompletionProposal_1); } } @@ -250,14 +234,16 @@ public void completeCreateMessage_Target(final EObject model, final Assignment a EObject _rootModel = context.getRootModel(); EList _participantsDefinedBefore = TextualScenarioHelper.participantsDefinedBefore(((Model) _rootModel)); for (final EObject el : _participantsDefinedBefore) { - boolean _equals = ((Participant) el).getName().equals(source); + String _name = ((Participant) el).getName(); + boolean _equals = _name.equals(source); boolean _not = (!_equals); if (_not) { - String _name = ((Participant) el).getName(); - String _plus = ("\"" + _name); + String _name_1 = ((Participant) el).getName(); + String _plus = ("\"" + _name_1); String _plus_1 = (_plus + "\""); - acceptor.accept( - this.createCompletionProposal(_plus_1, ((Participant) el).getName(), null, context)); + String _name_2 = ((Participant) el).getName(); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(_plus_1, _name_2, null, context); + acceptor.accept(_createCompletionProposal); } } } @@ -270,10 +256,12 @@ public void completeCreateMessage_Name(final EObject model, final Assignment ass @Override public void completeDeleteMessage_Arrow(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { if (((!EmbeddedEditorInstanceHelper.isFSScenario()) && (!EmbeddedEditorInstanceHelper.isESScenario()))) { - acceptor.accept(this.createCompletionProposal("->x", "->x : Delete Message", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("->x", "->x : Delete Message", null, context); + acceptor.accept(_createCompletionProposal); } if ((EmbeddedEditorInstanceHelper.isInteractionScenario() && (!EmbeddedEditorInstanceHelper.isFSScenario()))) { - acceptor.accept(this.createCompletionProposal("->x", "->x : Delete Message", null, context)); + ICompletionProposal _createCompletionProposal_1 = this.createCompletionProposal("->x", "->x : Delete Message", null, context); + acceptor.accept(_createCompletionProposal_1); } } @@ -283,14 +271,16 @@ public void completeDeleteMessage_Target(final EObject model, final Assignment a EObject _rootModel = context.getRootModel(); EList _participantsDefinedBefore = TextualScenarioHelper.participantsDefinedBefore(((Model) _rootModel)); for (final EObject el : _participantsDefinedBefore) { - boolean _equals = ((Participant) el).getName().equals(source); + String _name = ((Participant) el).getName(); + boolean _equals = _name.equals(source); boolean _not = (!_equals); if (_not) { - String _name = ((Participant) el).getName(); - String _plus = ("\"" + _name); + String _name_1 = ((Participant) el).getName(); + String _plus = ("\"" + _name_1); String _plus_1 = (_plus + "\""); - acceptor.accept( - this.createCompletionProposal(_plus_1, ((Participant) el).getName(), null, context)); + String _name_2 = ((Participant) el).getName(); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(_plus_1, _name_2, null, context); + acceptor.accept(_createCompletionProposal); } } } @@ -299,39 +289,30 @@ public void completeDeleteMessage_Target(final EObject model, final Assignment a public void completeParticipantDeactivation_Name(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { EObject modelContainer = TextualScenarioHelper.getModelContainer(((ParticipantDeactivation) model)); HashMap timelinesToPropose = new HashMap(); - this.createTimelinesHashMapToProposeForDeactivation(((ParticipantDeactivation) model), ((Model) modelContainer), timelinesToPropose); + ArrayList _arrayList = new ArrayList(); + List _allElements = TextualScenarioHelper.getAllElements(modelContainer, _arrayList); + this.createTimelinesHashMapToProposeForDeactivation(((ParticipantDeactivation) model), _allElements, timelinesToPropose); Set _keySet = timelinesToPropose.keySet(); for (final String timelineToPropose : _keySet) { Integer _get = timelinesToPropose.get(timelineToPropose); boolean _greaterEqualsThan = ((_get).intValue() >= 1); if (_greaterEqualsThan) { - acceptor.accept( - this.createCompletionProposal((("\"" + timelineToPropose) + "\""), timelineToPropose, null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal((("\"" + timelineToPropose) + "\""), timelineToPropose, null, context); + acceptor.accept(_createCompletionProposal); } } } - public HashMap createTimelinesHashMapToProposeForDeactivation(final ParticipantDeactivation participantDeactivation, final EObject modelContainer, final HashMap timelinesToPropose) { - List elements = TextualScenarioHelper.getElements(modelContainer); + public HashMap createTimelinesHashMapToProposeForDeactivation(final ParticipantDeactivation participantDeactivation, final List elements, final HashMap timelinesToPropose) { for (int i = 0; (i < elements.size()); i++) { - { - boolean _equals = elements.get(i).equals(participantDeactivation); - if (_equals) { - for (int j = 0; (j <= i); j++) { - this.updateHashMap(timelinesToPropose, elements.get(j), participantDeactivation); - } - return timelinesToPropose; - } - Element _get = elements.get(i); - if ((_get instanceof CombinedFragment)) { - Element _get_1 = elements.get(i); - this.createTimelinesHashMapToProposeForDeactivation(participantDeactivation, ((CombinedFragment) _get_1), timelinesToPropose); - } - Element _get_2 = elements.get(i); - if ((_get_2 instanceof Operand)) { - Element _get_3 = elements.get(i); - this.createTimelinesHashMapToProposeForDeactivation(participantDeactivation, ((Operand) _get_3), timelinesToPropose); + Element _get = elements.get(i); + boolean _equals = _get.equals(participantDeactivation); + if (_equals) { + for (int j = 0; (j <= i); j++) { + Element _get_1 = elements.get(j); + this.updateHashMap(timelinesToPropose, _get_1, participantDeactivation); } + return timelinesToPropose; } } return timelinesToPropose; @@ -346,6 +327,9 @@ public Integer updateHashMap(final HashMap timelinesToPropose, if ((element instanceof ArmTimerMessage)) { this.updateHashMapWithArmTimerMessage(timelinesToPropose, ((ArmTimerMessage) element)); } + if ((element instanceof FoundMessage)) { + this.updateHashMapWithFoundMessage(timelinesToPropose, ((FoundMessage) element)); + } Integer _xifexpression = null; if ((element instanceof ParticipantDeactivation)) { _xifexpression = this.updateHashMapWithParticipantDeactivation(timelinesToPropose, ((ParticipantDeactivation) element)); @@ -355,58 +339,112 @@ public Integer updateHashMap(final HashMap timelinesToPropose, return _xblockexpression; } + /** + * Update HashMap with the target of Sequence Message + * If the hashMap already contains the target (as key), increment with 1 the actual value + * If the hashMap doesn't contain the target, add the target as key and set its value to 1 + */ public Integer updateHashMapWithSequenceMessage(final HashMap timelinesToPropose, final SequenceMessage sequenceMessage) { Integer _xifexpression = null; String _execution = sequenceMessage.getExecution(); boolean _tripleNotEquals = (_execution != null); if (_tripleNotEquals) { Integer _xifexpression_1 = null; - boolean _containsKey = timelinesToPropose.containsKey(sequenceMessage.getTarget()); + String _target = sequenceMessage.getTarget(); + boolean _containsKey = timelinesToPropose.containsKey(_target); if (_containsKey) { Integer _xblockexpression = null; { - Integer value = timelinesToPropose.get(sequenceMessage.getTarget()); - _xblockexpression = timelinesToPropose.put(sequenceMessage.getTarget(), Integer.valueOf(((((Integer) value)).intValue() + 1))); + String _target_1 = sequenceMessage.getTarget(); + Integer value = timelinesToPropose.get(_target_1); + String _target_2 = sequenceMessage.getTarget(); + _xblockexpression = timelinesToPropose.put(_target_2, Integer.valueOf(((((Integer) value)).intValue() + 1))); } _xifexpression_1 = _xblockexpression; } else { - _xifexpression_1 = timelinesToPropose.put(sequenceMessage.getTarget(), Integer.valueOf(1)); + String _target_1 = sequenceMessage.getTarget(); + _xifexpression_1 = timelinesToPropose.put(_target_1, Integer.valueOf(1)); } _xifexpression = _xifexpression_1; } return _xifexpression; } + /** + * Update HashMap with the participant of ArmTimer Message + * If the hashMap already contains the participant (as key), increment with 1 the actual value + * If the hashMap doesn't contain the participant, add the participant as key and set its value to 1 + */ public Integer updateHashMapWithArmTimerMessage(final HashMap timelinesToPropose, final ArmTimerMessage armTimer) { Integer _xifexpression = null; String _execution = armTimer.getExecution(); boolean _tripleNotEquals = (_execution != null); if (_tripleNotEquals) { Integer _xifexpression_1 = null; - boolean _containsKey = timelinesToPropose.containsKey(armTimer.getParticipant()); + String _participant = armTimer.getParticipant(); + boolean _containsKey = timelinesToPropose.containsKey(_participant); + if (_containsKey) { + Integer _xblockexpression = null; + { + String _participant_1 = armTimer.getParticipant(); + Integer value = timelinesToPropose.get(_participant_1); + _xblockexpression = value = Integer.valueOf(((((Integer) value)).intValue() + 1)); + } + _xifexpression_1 = _xblockexpression; + } else { + String _participant_1 = armTimer.getParticipant(); + _xifexpression_1 = timelinesToPropose.put(_participant_1, Integer.valueOf(1)); + } + _xifexpression = _xifexpression_1; + } + return _xifexpression; + } + + /** + * Update HashMap with the target of Found Message + * If the hashMap already contains the target (as key), increment with 1 the actual value + * If the hashMap doesn't contain the target, add the target as key and set its value to 1 + */ + public Integer updateHashMapWithFoundMessage(final HashMap timelinesToPropose, final FoundMessage foundMessage) { + Integer _xifexpression = null; + String _execution = foundMessage.getExecution(); + boolean _tripleNotEquals = (_execution != null); + if (_tripleNotEquals) { + Integer _xifexpression_1 = null; + String _target = foundMessage.getTarget(); + boolean _containsKey = timelinesToPropose.containsKey(_target); if (_containsKey) { Integer _xblockexpression = null; { - Integer value = timelinesToPropose.get(armTimer.getParticipant()); + String _target_1 = foundMessage.getTarget(); + Integer value = timelinesToPropose.get(_target_1); _xblockexpression = value = Integer.valueOf(((((Integer) value)).intValue() + 1)); } _xifexpression_1 = _xblockexpression; } else { - _xifexpression_1 = timelinesToPropose.put(armTimer.getParticipant(), Integer.valueOf(1)); + String _target_1 = foundMessage.getTarget(); + _xifexpression_1 = timelinesToPropose.put(_target_1, Integer.valueOf(1)); } _xifexpression = _xifexpression_1; } return _xifexpression; } + /** + * Update HashMap with the deactivation + * Decrement with 1 the actual value of the deactivation name (timeline) + */ public Integer updateHashMapWithParticipantDeactivation(final HashMap timelinesToPropose, final ParticipantDeactivation participantDeactivation) { Integer _xifexpression = null; - boolean _containsKey = timelinesToPropose.containsKey(participantDeactivation.getName()); + String _name = participantDeactivation.getName(); + boolean _containsKey = timelinesToPropose.containsKey(_name); if (_containsKey) { Integer _xblockexpression = null; { - Integer value = timelinesToPropose.get(participantDeactivation.getName()); - _xblockexpression = timelinesToPropose.put(participantDeactivation.getName(), Integer.valueOf(((((Integer) value)).intValue() - 1))); + String _name_1 = participantDeactivation.getName(); + Integer value = timelinesToPropose.get(_name_1); + String _name_2 = participantDeactivation.getName(); + _xblockexpression = timelinesToPropose.put(_name_2, Integer.valueOf(((((Integer) value)).intValue() - 1))); } _xifexpression = _xblockexpression; } @@ -423,7 +461,8 @@ public void completeArmTimerMessage_Arrow(final EObject model, final Assignment boolean _isFSScenario = EmbeddedEditorInstanceHelper.isFSScenario(); boolean _not = (!_isFSScenario); if (_not) { - acceptor.accept(this.createCompletionProposal("->>", "->> : Arm Timer", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("->>", "->> : Arm Timer", null, context); + acceptor.accept(_createCompletionProposal); } } @@ -434,14 +473,16 @@ public void completeArmTimerMessage_Participant(final EObject model, final Assig @Override public void completeArmTimerMessage_Name(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { - acceptor.accept(this.createCompletionProposal("\"Arm Timer\"", "\"Arm Timer\"", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("\"Arm Timer\"", "\"Arm Timer\"", null, context); + acceptor.accept(_createCompletionProposal); } @Override public void completeLostMessage_Arrow(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { boolean _isESScenario = EmbeddedEditorInstanceHelper.isESScenario(); if (_isESScenario) { - acceptor.accept(this.createCompletionProposal("->o", "->o : Lost Message", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("->o", "->o : Lost Message", null, context); + acceptor.accept(_createCompletionProposal); } } @@ -453,20 +494,23 @@ public void completeLostMessage_Source(final EObject model, final Assignment ass @Override public void completeLostMessage_Name(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { LostMessage message = ((LostMessage) model); - this.createMessageProposal(message.getSource(), null, context, acceptor); + String _source = message.getSource(); + this.createMessageProposal(_source, null, context, acceptor); } @Override public void completeFoundMessage_Name(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { FoundMessage message = ((FoundMessage) model); - this.createMessageProposal(null, message.getTarget(), context, acceptor); + String _target = message.getTarget(); + this.createMessageProposal(null, _target, context, acceptor); } @Override public void completeFoundMessage_Arrow(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { boolean _isESScenario = EmbeddedEditorInstanceHelper.isESScenario(); if (_isESScenario) { - acceptor.accept(this.createCompletionProposal("o->", "o-> : Found Message", null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal("o->", "o-> : Found Message", null, context); + acceptor.accept(_createCompletionProposal); } } @@ -477,12 +521,15 @@ public void completeFoundMessage_Target(final EObject model, final Assignment as @Override public void completeStateFragment_Timeline(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { - List keywords = Collections.unmodifiableList(CollectionLiterals.newArrayList(DslConstants.ACTOR, DslConstants.ACTIVITY, DslConstants.FUNCTION, DslConstants.ROLE, DslConstants.ENTITY, DslConstants.ROLE, DslConstants.COMPONENT, DslConstants.CONFIGURATION_ITEM)); - for (final String keyword : keywords) { - boolean _checkValidKeyword = EmbeddedEditorInstanceHelper.checkValidKeyword(keyword); - if (_checkValidKeyword) { - this.getExistingTimelines(keyword, context, acceptor); - } + EObject _rootModel = context.getRootModel(); + EList _participantsDefinedBefore = TextualScenarioHelper.participantsDefinedBefore(((Model) _rootModel)); + for (final EObject el : _participantsDefinedBefore) { + String _name = ((Participant) el).getName(); + String _plus = ("\"" + _name); + String _plus_1 = (_plus + "\""); + String _name_1 = ((Participant) el).getName(); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(_plus_1, _name_1, null, context); + acceptor.accept(_createCompletionProposal); } } @@ -495,17 +542,19 @@ public void completeStateFragment_Keyword(final EObject model, final Assignment keywords.add(DslConstants.FUNCTION); } for (final String keyword : keywords) { - acceptor.accept(this.createCompletionProposal(keyword, keyword, null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(keyword, keyword, null, context); + acceptor.accept(_createCompletionProposal); } } @Override public void completeStateFragment_Name(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { - List _availableStateFragments = EmbeddedEditorInstanceHelper.getAvailableStateFragments( - ((StateFragment) model).getKeyword(), ((StateFragment) model).getTimeline()); + String _keyword = ((StateFragment) model).getKeyword(); + String _timeline = ((StateFragment) model).getTimeline(); + List _availableStateFragments = EmbeddedEditorInstanceHelper.getAvailableStateFragments(_keyword, _timeline); for (final String stateFragment : _availableStateFragments) { - acceptor.accept( - this.createCompletionProposal((("\"" + stateFragment) + "\""), (("\"" + stateFragment) + "\""), null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal((("\"" + stateFragment) + "\""), stateFragment, null, context); + acceptor.accept(_createCompletionProposal); } } @@ -514,14 +563,17 @@ public void completeCombinedFragment_Timelines(final EObject model, final Assign EObject _rootModel = context.getRootModel(); EList _participantsDefinedBefore = TextualScenarioHelper.participantsDefinedBefore(((Model) _rootModel)); for (final EObject el : _participantsDefinedBefore) { - boolean _contains = ((CombinedFragment) model).getTimelines().contains(((Participant) el).getName()); + EList _timelines = ((CombinedFragment) model).getTimelines(); + String _name = ((Participant) el).getName(); + boolean _contains = _timelines.contains(_name); boolean _not = (!_contains); if (_not) { - String _name = ((Participant) el).getName(); - String _plus = ("\"" + _name); + String _name_1 = ((Participant) el).getName(); + String _plus = ("\"" + _name_1); String _plus_1 = (_plus + "\""); - acceptor.accept( - this.createCompletionProposal(_plus_1, ((Participant) el).getName(), null, context)); + String _name_2 = ((Participant) el).getName(); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(_plus_1, _name_2, null, context); + acceptor.accept(_createCompletionProposal); } } } @@ -530,7 +582,8 @@ public void completeCombinedFragment_Timelines(final EObject model, final Assign public void completeReference_Name(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { List referencedScenarios = EmbeddedEditorInstanceHelper.getReferencedScenariosName(); for (final String referencedScenario : referencedScenarios) { - acceptor.accept(this.createCompletionProposal((("\"" + referencedScenario) + "\""), referencedScenario, null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal((("\"" + referencedScenario) + "\""), referencedScenario, null, context); + acceptor.accept(_createCompletionProposal); } } @@ -539,14 +592,19 @@ public void completeReference_Timelines(final EObject model, final Assignment as EObject _rootModel = context.getRootModel(); EList _participantsDefinedBefore = TextualScenarioHelper.participantsDefinedBefore(((Model) _rootModel)); for (final EObject el : _participantsDefinedBefore) { - boolean _contains = ((Reference) model).getTimelines().contains(((Participant) el).getName()); - boolean _not = (!_contains); - if (_not) { + if ((model instanceof Reference)) { + EList _timelines = ((Reference) model).getTimelines(); String _name = ((Participant) el).getName(); - String _plus = ("\"" + _name); - String _plus_1 = (_plus + "\""); - acceptor.accept( - this.createCompletionProposal(_plus_1, ((Participant) el).getName(), null, context)); + boolean _contains = _timelines.contains(_name); + boolean _not = (!_contains); + if (_not) { + String _name_1 = ((Participant) el).getName(); + String _plus = ("\"" + _name_1); + String _plus_1 = (_plus + "\""); + String _name_2 = ((Participant) el).getName(); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(_plus_1, _name_2, null, context); + acceptor.accept(_createCompletionProposal); + } } } } @@ -569,19 +627,24 @@ public boolean messageAlreadyInserted(final Model model, final String source, fi public void completeCreateDeleteMessageName(final EObject model, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) { SequenceMessageType message = ((SequenceMessageType) model); - List exchangesAvailable = EmbeddedEditorInstanceHelper.getExchangeMessages(message.getSource(), message.getTarget()); + String _source = message.getSource(); + String _target = message.getTarget(); + List exchangesAvailable = EmbeddedEditorInstanceHelper.getExchangeMessages(_source, _target); String elementName = new String(); for (final EObject element : exchangesAvailable) { { boolean _isInterfaceScenario = EmbeddedEditorInstanceHelper.isInterfaceScenario(); if (_isInterfaceScenario) { - elementName = CapellaElementExt.getName(((ExchangeItemAllocation) element).getAllocatedItem()); + ExchangeItem _allocatedItem = ((ExchangeItemAllocation) element).getAllocatedItem(); + String _name = CapellaElementExt.getName(_allocatedItem); + elementName = _name; } else { - elementName = CapellaElementExt.getName(element); + String _name_1 = CapellaElementExt.getName(element); + elementName = _name_1; } if ((elementName != null)) { - acceptor.accept( - this.createCompletionProposal((("\"" + elementName) + "\""), (("\"" + elementName) + "\""), null, context)); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal((("\"" + elementName) + "\""), elementName, null, context); + acceptor.accept(_createCompletionProposal); } } } @@ -594,8 +657,9 @@ public void proposeParticipants(final ContentAssistContext context, final ICompl String _name = ((Participant) el).getName(); String _plus = ("\"" + _name); String _plus_1 = (_plus + "\""); - acceptor.accept( - this.createCompletionProposal(_plus_1, ((Participant) el).getName(), null, context)); + String _name_1 = ((Participant) el).getName(); + ICompletionProposal _createCompletionProposal = this.createCompletionProposal(_plus_1, _name_1, null, context); + acceptor.accept(_createCompletionProposal); } } } diff --git a/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.xtend b/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.xtend index ec967199..357dd933 100644 --- a/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.xtend +++ b/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.xtend @@ -26,11 +26,11 @@ import org.polarsys.capella.scenario.editor.dsl.textualScenario.CombinedFragment import org.polarsys.capella.scenario.editor.dsl.textualScenario.Model import org.polarsys.capella.scenario.editor.dsl.textualScenario.Block import org.polarsys.capella.scenario.editor.dsl.textualScenario.Element -import org.polarsys.capella.scenario.editor.dsl.textualScenario.SequenceMessageType import java.util.Set import org.polarsys.capella.scenario.editor.dsl.textualScenario.Message import org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostMessage +import java.util.List /** * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist @@ -155,7 +155,7 @@ class TextualScenarioHelper { /* * get all elements on the same level as modelContainer */ - def static getElements(EObject modelContainer) { + def static getContainerElements(EObject modelContainer) { if (modelContainer instanceof Model) { return (modelContainer as Model).elements @@ -175,6 +175,21 @@ class TextualScenarioHelper { } } + /* + * get all elements from xtext + */ + def static List getAllElements(EObject modelContainer, List allElements) { + for (Element element : getContainerElements(modelContainer)) { + if (!(element instanceof CombinedFragment)) { + allElements.add(element) + } else { + allElements.add(element) + getAllElements(element, allElements) + } + } + return allElements; + } + /* * get the root model that contains the object given as para */ diff --git a/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.xtend b/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.xtend index 27a1cd21..cedc6a2f 100644 --- a/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.xtend +++ b/plugins/org.polarsys.capella.scenario.editor.dsl/src/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.xtend @@ -1,928 +1,900 @@ -/******************************************************************************* - * Copyright (c) 2020 THALES GLOBAL SERVICES. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Thales - initial API and implementation - *******************************************************************************/ -package org.polarsys.capella.scenario.editor.dsl.validation - -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Participant -import org.polarsys.capella.scenario.editor.dsl.textualScenario.SequenceMessageType -import org.polarsys.capella.scenario.editor.dsl.textualScenario.SequenceMessage -import org.polarsys.capella.scenario.editor.dsl.textualScenario.ParticipantDeactivation -import org.polarsys.capella.scenario.editor.dsl.textualScenario.TextualScenarioPackage -import org.eclipse.xtext.validation.Check -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Model -import org.polarsys.capella.scenario.editor.helper.EmbeddedEditorInstanceHelper -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Function -import org.polarsys.capella.scenario.editor.dsl.helpers.TextualScenarioHelper -import org.polarsys.capella.scenario.editor.dsl.textualScenario.CombinedFragment -import org.eclipse.emf.ecore.EObject -import org.polarsys.capella.scenario.editor.dsl.textualScenario.DeleteMessage -import org.polarsys.capella.scenario.editor.dsl.textualScenario.CreateMessage -import org.polarsys.capella.scenario.editor.dsl.textualScenario.StateFragment -import org.polarsys.capella.scenario.editor.helper.DslConstants -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Operand -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Block -import org.polarsys.capella.scenario.editor.dsl.textualScenario.ArmTimerMessage -import java.util.HashSet -import org.eclipse.emf.ecore.EAttribute -import java.util.List -import java.util.Set -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Reference -import java.util.HashMap -import java.util.LinkedList -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Element -import org.eclipse.emf.ecore.EReference -import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostMessage -import org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage -import org.polarsys.capella.scenario.editor.dsl.textualScenario.Message -import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostFoundMessage - -/** - * This class contains custom validation rules. - * - * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation - */ -class TextualScenarioValidator extends AbstractTextualScenarioValidator { - public static val INVALID_NAME = 'invalidName' - public static val DUPLICATED_NAME = 'duplicatedName' - public static val DUPLICATED_MESSAGES_NAME = 'duplicatedMessageName' - public static val SAME_SOURCE_AND_TARGET_ERROR = 'Invalid element! Source and target must be different!' - - @Check - def checkPartExists(Participant participant) { - if (!EmbeddedEditorInstanceHelper.getAvailablePartNames(participant.keyword).contains(participant.name)) { - if (participant instanceof Function) { - error('Function does not exist!', TextualScenarioPackage.Literals.PARTICIPANT__NAME, INVALID_NAME) - } else { - error('Represented part does not exist!', TextualScenarioPackage.Literals.PARTICIPANT__NAME, - INVALID_NAME) - } - } - } - - @Check - def checkParticipantKeywordIsValid(Participant participant) { - if (!EmbeddedEditorInstanceHelper.checkValidKeyword(participant.keyword)) { - error('\'' + participant.keyword + '\' can not be used in this diagram!', - TextualScenarioPackage.Literals.PARTICIPANT__KEYWORD) - } - } - - @Check - def checkMessagesExist(SequenceMessage message) { - if (!EmbeddedEditorInstanceHelper.getExchangeNames(message.getSource, message.getTarget).contains( - message.name)) { - error('Exchange does not exist between \"' + message.source + "\" and \"" + message.target +"\"!" - , TextualScenarioPackage.Literals.MESSAGE__NAME - ) - } - } - - - /* - * Check that the source and the target of the sequence messages type are defined in text, before using them in the message - */ - @Check - def checkParticipantsInvolvedExist(SequenceMessageType message) { - var participantsDefined = TextualScenarioHelper.participantsDefinedBeforeNames(message); - if (!participantsDefined.contains(message.source)) { - error( - 'Source participant not defined in text editor!', - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE - ) - } - if (!participantsDefined.contains(message.target)) { - error( - 'Target participant not defined in text editor!', - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET - ) - } - } - - @Check - def checkSequenceMessagesExchangeType(SequenceMessage sequenceMessage) { - checkMessagesExchangeType(sequenceMessage) - } - - @Check - def checkSequenceMessagesExchangeType(LostFoundMessage lostFoundMessage) { - checkMessagesExchangeType(lostFoundMessage) - } - - /* - * check that a CE (component exchange) and an FE (functional exchange) are not used in the same place - */ - def checkMessagesExchangeType(Message message) { - if (EmbeddedEditorInstanceHelper.isESScenario()) { - var model = TextualScenarioHelper.getModelContainer(message) - if (model instanceof Model) { - var scenarioExchangesType = TextualScenarioHelper. - getScenarioAllowedExchangesType((model as Model).elements) - var exchangeTypes = TextualScenarioHelper.getAllMessageExchangeType(message) as Set - if (scenarioExchangesType !== null && !exchangeTypes.contains(scenarioExchangesType)) { - error('Exchange type can not be used, expected ' + scenarioExchangesType + "!", - TextualScenarioPackage.Literals.MESSAGE__NAME) - } - } - } - } - - /* - * Do not allow duplicated names, we have a combination of unique keyword + name - * ex: not allowed: actor "A1", actor "A1" - * ex: allowed: actor "A1", component "A1" - */ - @Check - def checkDuplicatedParticipantsNames(Model model) { - var index = 0 - val names = newHashSet - for (p : model.participants) { - if (!names.add(getParticipantsMapKey(p))) { - error( - 'Duplicated participant!', - TextualScenarioPackage.Literals.MODEL__PARTICIPANTS, - index, - DUPLICATED_NAME - ) - } - index++ - } - } - - @Check - def checkDeactivateMessagesModel(Model model) { - checkDeactivateMessages(model, newLinkedList, model.elements) - } - - /* - * Checks on deactivation keyword - * If we encounter a deactivation on a target, check that we have a corresponding sequence message that can be deactivated - */ - def void checkDeactivateMessages(EObject container, - LinkedList messageTargets, - List elements) { - var index = 0 - // a message shall occur before a deactivation - // keep this array with the targets of each encountered message to check that the message happens before deactivation - for (obj : elements) { - if (obj instanceof SequenceMessage && (obj as SequenceMessage).execution !== null) { - // add the already encountered messages to the list - messageTargets.add((obj as SequenceMessage).target) - } - - if (obj instanceof ArmTimerMessage && (obj as ArmTimerMessage).execution !== null) { - // add the already encountered messages to the list - messageTargets.add((obj as ArmTimerMessage).participant) - } - - if (obj instanceof FoundMessage && (obj as FoundMessage).execution !== null) { - // add the already encountered messages to the list - messageTargets.add((obj as FoundMessage).target) - } - - if (obj instanceof CombinedFragment) { - var cf = obj as CombinedFragment - checkDeactivateMessages(cf.block, - messageTargets, - cf.block.blockElements - ) - cf.operands.forEach[operand | - checkDeactivateMessages(operand.block, - messageTargets, - operand.block.blockElements - ) - ] - } - - if (obj instanceof ParticipantDeactivation) { - var refFeature = TextualScenarioPackage.Literals.MODEL__ELEMENTS - if (container instanceof Block) { - refFeature = TextualScenarioPackage.Literals.BLOCK__BLOCK_ELEMENTS - } - showErrorDeactivateMessages( - obj as ParticipantDeactivation, - container, - messageTargets, - refFeature, - index - ) - } - index++ - } - } - - def showErrorDeactivateMessages( - ParticipantDeactivation deactivation, - EObject container, - LinkedList messageTargets, - EReference refFeature, - int index - ) { - // if we already encountered a message with target ad deactivation.name, - // we will remove the message from the messages list, because this message is matched with a deactivation - var indexOfTarget = messageTargets.lastIndexOf(deactivation.name) - if (indexOfTarget < 0) { - error( - 'Deactivation keyword not expected!', - container, - refFeature, - index - ) - } else { - messageTargets.remove(indexOfTarget) - } - } - - /* - * check that the messages we define are valid - * if the message is inside a combined fragment, the messages must be between the defined timelines of the combined fragment - */ - @Check - def checkDefinedTimelinesMessages(SequenceMessageType message) { - var participantsNames = TextualScenarioHelper.participantsDefinedBeforeNames(message) - if (!participantsNames.contains(message.source)) { - error(String.format("Timeline not defined in text editor!"), TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE) - return - } - - if (!participantsNames.contains(message.target)) { - error(String.format("Timeline not defined in text editor!"), TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) - return - } - } - - @Check - def checkContainedTimelinesMessages(SequenceMessageType message) { - // if the message is inside a combined fragment, check that source and target are covered by it - var container = TextualScenarioHelper.getDirectContainer(message) - if (container instanceof CombinedFragment) { - var upContainer = getUpperContainerCombinedFragmentTimelines(message, container) - if(upContainer !== null && upContainer instanceof CombinedFragment) { - checkTimelinesMessages(message, upContainer as CombinedFragment) - } - } - } - - def EObject getUpperContainerCombinedFragmentTimelines(SequenceMessageType message, CombinedFragment container) { - if (container.timelines.contains(message.source) || container.timelines.contains(message.target)) { - return container - } else { - var upperContainer = TextualScenarioHelper.getDirectContainer(container) - if (upperContainer instanceof CombinedFragment) { - return getUpperContainerCombinedFragmentTimelines(message, upperContainer as CombinedFragment); - } - } - return null - } - - def checkTimelinesMessages(SequenceMessageType message, CombinedFragment container) { - var msg = String.format("Timeline not covered by this " + container.keyword + "!" + - " Expected values in : " + container.timelines - ) - if (!container.timelines.contains(message.source)) { - error(msg, - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE) - } - - if (!container.timelines.contains(message.target)) { - error(msg, - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) - } - } - - - @Check - def checkDeleteMessage(DeleteMessage deleteMessage) { - checkCreateOrDeleteCouldBeUsed() - checkSameSourceAndTarget(deleteMessage) - } - - // check that in opened diagram create or delete messages could be used - def checkCreateOrDeleteCouldBeUsed() { - if (EmbeddedEditorInstanceHelper.isFSScenario() || - (EmbeddedEditorInstanceHelper.isESScenario() && !EmbeddedEditorInstanceHelper.isInteractionScenario) - ) { - error("Create or delete message can not be used in this diagram!", - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__ARROW) - } - } - - @Check - def checkArmTimer(ArmTimerMessage armTimer) { - // check arm timer could be used in opened diagram - if (EmbeddedEditorInstanceHelper.isFSScenario()) { - error("Arm Timer can not be used in this diagram!", - TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__ARROW) - } - - // check timeline exist - if (!TextualScenarioHelper.participantsDefinedBeforeNames(armTimer).contains(armTimer.participant)) { - error("Timeline not defined in text editor!", - TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__PARTICIPANT) - } - } - - @Check - def checkLostMessage(LostMessage message) { - // check lost message could be used in opened diagram - if (!EmbeddedEditorInstanceHelper.isESScenario()) { - error("Lost message can not be used in this diagram!", - TextualScenarioPackage.Literals.LOST_FOUND_MESSAGE__ARROW) - } - - // check timeline exist - if (!TextualScenarioHelper.participantsDefinedBeforeNames(message).contains(message.source)) { - error("Timeline not defined in text editor!", - TextualScenarioPackage.Literals.LOST_MESSAGE__SOURCE) - } - } - - @Check - def checkFoundMessage(FoundMessage message) { - // check found message could be used in opened diagram - if (!EmbeddedEditorInstanceHelper.isESScenario()) { - error("Found message can not be used in this diagram!", - TextualScenarioPackage.Literals.LOST_FOUND_MESSAGE__ARROW) - } - - // check timeline exist - if (!TextualScenarioHelper.participantsDefinedBeforeNames(message).contains(message.target)) { - error("Timeline not defined in text editor!", - TextualScenarioPackage.Literals.FOUND_MESSAGE__TARGET) - } - } - - def checkSameSourceAndTarget(SequenceMessageType message) { - if (message.source.equals(message.target)) { - error(SAME_SOURCE_AND_TARGET_ERROR, - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) - error(SAME_SOURCE_AND_TARGET_ERROR, - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE) - } - } - - /* - * check if a timeline involved in a combined fragment was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkTimelineUsedAfterDeleteMessage(CombinedFragment combinedFragment) { - var model = TextualScenarioHelper.getModelContainer(combinedFragment) - if (model instanceof Model) { - var index = 0 - for (timeline : combinedFragment.timelines) { - checkElementAfterDelete(model as Model, combinedFragment, timeline, - TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES, index++) - } - } - } - - /* - * check if the timeline involved in a state fragment was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkTimelineUsedAfterDeleteMessage(StateFragment fragment) { - var model = TextualScenarioHelper.getModelContainer(fragment) - if (model instanceof Model) - checkElementAfterDelete(model as Model, fragment, fragment.timeline, - TextualScenarioPackage.Literals.STATE_FRAGMENT__TIMELINE, 0) - } - - /* - * check if a participant involved in arm timer was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkParticipantUsedAfterDeleteMessage(ArmTimerMessage armTimer) { - var model = TextualScenarioHelper.getModelContainer(armTimer) - if (model instanceof Model) - checkElementAfterDelete(model as Model, armTimer, armTimer.participant, - TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__PARTICIPANT, 0) - } - - /* - * check if a participant involved in a lost message was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkParticipantUsedAfterLostMessage(LostMessage message) { - var model = TextualScenarioHelper.getModelContainer(message) - if (model instanceof Model) - checkElementAfterDelete(model as Model, message, message.source, - TextualScenarioPackage.Literals.LOST_MESSAGE__SOURCE, 0) - } - - /* - * check if a participant involved in a lost message was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkParticipantUsedAfterFoundMessage(FoundMessage message) { - var model = TextualScenarioHelper.getModelContainer(message) - if (model instanceof Model) - checkElementAfterDelete(model as Model, message, message.target, - TextualScenarioPackage.Literals.FOUND_MESSAGE__TARGET, 0) - } - - /* - * check if a sequence message source element was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkMessageSourceUsedAfterDeleteMessage(SequenceMessageType message) { - var model = TextualScenarioHelper.getModelContainer(message) - if (model instanceof Model) - checkElementAfterDelete(model as Model, message, message.source, - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE, 0) - } - - /* - * check if a sequence message target element was used after a delete message was already defined - * on the previous lines on the same timeline - */ - @Check - def checkMessageTargetUsedAfterDeleteMessage(SequenceMessageType message) { - var model = TextualScenarioHelper.getModelContainer(message) - if (model instanceof Model) - checkElementAfterDelete(model as Model, message, message.target, - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET, 0) - } - - - def boolean checkElementAfterDelete(EObject model, EObject checkedElement, String target, - EAttribute checkedAttribute, int index) { - var elements = TextualScenarioHelper.getElements(model) - - for (EObject element : elements) { - if (element.equals(checkedElement)) { - return true - } - - if (element instanceof DeleteMessage) { - if ((element as DeleteMessage).target.equals(target)) { - error(String.format( - "Element \"" + target + - "\" can not be used at this point! A delete message was already defined on this timeline." - ), checkedAttribute, index) - return true - } - } - - if (element instanceof CombinedFragment) { - if(checkElementAfterDelete(element, checkedElement, target, checkedAttribute, index)) { - return true; - } - } - } - return false; - } - - /* - * check if create message could be used - */ - @Check - def checkCreateMessage(CreateMessage createMessage) { - // check if create message could be used in opened diagram - checkCreateOrDeleteCouldBeUsed() - - // check if source and target are the same - checkSameSourceAndTarget(createMessage) - var model = TextualScenarioHelper.getModelContainer(createMessage) - if (model instanceof Model && !checkCreateMessageValid(model as Model, createMessage)) { - errorCreateMessage(createMessage.target) - } - } - - def boolean checkCreateMessageValid(EObject model, CreateMessage createMessage) { - var target = createMessage.target - var elements = TextualScenarioHelper.getElements(model) - - for (EObject element : elements) { - if (element instanceof SequenceMessageType) { - if (element.equals(createMessage)) { - return true - } - - if ((element as SequenceMessageType).target.equals(target) || - (element as SequenceMessageType).source.equals(target)) { - return false - } - } - - if (element instanceof ArmTimerMessage) { - if ((element as ArmTimerMessage).participant.equals(target)) { - return false - } - } - - if (element instanceof LostMessage) { - if ((element as LostMessage).source.equals(target)) { - return false - } - } - - if (element instanceof FoundMessage) { - if ((element as FoundMessage).target.equals(target)) { - return false - } - } - - if (element instanceof CombinedFragment) { - if ((element as CombinedFragment).timelines.contains(target)) { - return false - } else { - if (!(checkCreateMessageValid(element, createMessage) as Boolean)) { - return false - } - } - } - - if (element instanceof StateFragment) { - if ((element as StateFragment).timeline.equals(target)) { - return false - } - } - - if (element instanceof Reference) { - if ((element as Reference).timelines.contains(target)) { - return false; - } - } - } - return true - } - - def errorCreateMessage(String target) { - error(String.format("Target \"" + target +"\" can not be used in a create message at this point! Other operations were already defined on this timeline."), - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) - } - - - /* - * Validate a State Fragment - */ - @Check - def checkStateFragment(StateFragment fragment) { - if (!TextualScenarioHelper.participantsDefinedBeforeNames(fragment).contains(fragment.timeline)) { - error(String.format("Timeline not defined in text editor!", fragment.keyword), - TextualScenarioPackage.Literals.STATE_FRAGMENT__TIMELINE) - return - } - - var scenarioType = EmbeddedEditorInstanceHelper.getScenarioType(); - if (fragment.keyword.equals(DslConstants.FUNCTION) && scenarioType.equals(DslConstants.FUNCTIONAL)) { - error(String.format("\'function\' can not be used in this diagram!"), - TextualScenarioPackage.Literals.STATE_FRAGMENT__KEYWORD) - return - } - - var availableStateFragments = EmbeddedEditorInstanceHelper.getAvailableStateFragments(fragment.keyword, - fragment.timeline) - if (!availableStateFragments.contains(fragment.name)) { - error( - String.format("This " + fragment.keyword + " does not exist or is not available for \"" + - fragment.timeline +"\"!"), TextualScenarioPackage.Literals.STATE_FRAGMENT__NAME) - } - - } - - /* - * Check that each withExecution message is closed by deactivation (on the proper target) - */ - @Check - def checkWithExecutionHasDeactivateModel(Model model) { - var messageWithExecutionTargets = newLinkedList - var messageWithExecutionTargetsIndex = newLinkedList - var messageWithExecutionTargetsContainer = newLinkedList - checkWithExecutionHasDeactivate(model, - messageWithExecutionTargets, - messageWithExecutionTargetsIndex, - messageWithExecutionTargetsContainer, - model.elements - ) - - showErrorWithExecutionHasDeactivate(messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer) - } - - def void showErrorWithExecutionHasDeactivate( - LinkedList messageWithExecutionTargets, - LinkedList messageWithExecutionTargetsIndex, - LinkedList messageWithExecutionTargetsContainer - ) { - // if not all withExecution messages were matched with a deactivation, show an error - // use the index list to know on which message to display the error - for (var i = 0; i < messageWithExecutionTargets.size; i++) { - var container = messageWithExecutionTargetsContainer.get(i) - if (container instanceof Model) { - error( - 'Deactivation keyword expected for a withExecution message!', - container, - TextualScenarioPackage.Literals.MODEL__ELEMENTS, - messageWithExecutionTargetsIndex.get(i) - ) - } else if (container instanceof Block) { - error( - 'Deactivation keyword expected for a withExecution message!', - container, - TextualScenarioPackage.Literals.BLOCK__BLOCK_ELEMENTS, - messageWithExecutionTargets.get(i) - ) - } - } - } - - def void checkWithExecutionHasDeactivate(EObject container, - LinkedList messageWithExecutionTargets, - LinkedList messageWithExecutionTargetsIndex, - LinkedList messageWithExecutionTargetsContainer, - List elements - ) { - // keep a list with the target of the messages that contains the withExecution keyword - // keep also a list with the index on which withExecution message is found, to know on which line to show an error - var index = 0 - for (obj : elements) { - if (obj instanceof SequenceMessage && (obj as SequenceMessage).execution !== null) { - // add the SequenceMessage with execution to a list - messageWithExecutionTargets.add((obj as SequenceMessage).target) - messageWithExecutionTargetsIndex.add(index) - messageWithExecutionTargetsContainer.add(container) - } - - if (obj instanceof ArmTimerMessage && (obj as ArmTimerMessage).execution !== null) { - messageWithExecutionTargets.add((obj as ArmTimerMessage).participant) - messageWithExecutionTargetsIndex.add(index) - messageWithExecutionTargetsContainer.add(container) - } - - if (obj instanceof FoundMessage && (obj as FoundMessage).execution !== null) { - messageWithExecutionTargets.add((obj as FoundMessage).target) - messageWithExecutionTargetsIndex.add(index) - messageWithExecutionTargetsContainer.add(container) - } - - if (obj instanceof CombinedFragment) { - var cf = obj as CombinedFragment - checkWithExecutionHasDeactivate(cf.block, messageWithExecutionTargets, - messageWithExecutionTargetsIndex, - messageWithExecutionTargetsContainer, - cf.block.blockElements - ) - cf.operands.forEach[operand | - checkWithExecutionHasDeactivate(operand.block, - messageWithExecutionTargets, - messageWithExecutionTargetsIndex, - messageWithExecutionTargetsContainer, - operand.block.blockElements - ) - ] - } - - if (obj instanceof ParticipantDeactivation) { - var targetName = (obj as ParticipantDeactivation).name - var indexOfTarget = messageWithExecutionTargets.lastIndexOf(targetName) - - if (indexOfTarget >= 0) { - messageWithExecutionTargets.remove(indexOfTarget) - messageWithExecutionTargetsIndex.remove(indexOfTarget) - messageWithExecutionTargetsContainer.remove(indexOfTarget) - } - } - index++ - } - } - - /* - * Expression shall not be empty - */ - // @Check - def checkCombinedFragmentEmptyExpression(CombinedFragment combinedFragment) { - if (combinedFragment.expression === null || combinedFragment.expression.isEmpty) { - error( - 'Expression can not be empty!', - TextualScenarioPackage.Literals.COMBINED_FRAGMENT__EXPRESSION - ) - } - } - - /* - * Expression shall not be empty - */ -// @Check - def checkOperandEmptyExpression(Operand operand) { - if (operand.expression === null || operand.expression.isEmpty) { - error( - 'Expression can not be empty!', - TextualScenarioPackage.Literals.OPERAND__EXPRESSION - ) - } - } - - /* - * Else keyword shall be put on a combined fragment that is ALT - */ - @Check - def checkElseKeyworkAvailable(Operand operand) { - if (operand.eContainer instanceof CombinedFragment) { - var combinedFragment = operand.eContainer as CombinedFragment - if (combinedFragment.keyword == 'alt' && !combinedFragment.operands.isEmpty) { - if (operand.keyword != 'else') { - error( - 'Expected \'else\' keyword!', - TextualScenarioPackage.Literals.OPERAND__KEYWORD - ) - } - } - } - } - - /* - * No keyword shall be put on a combined fragment that is not ALT - */ - @Check - def checkKeyworkNotAvailable(Operand operand) { - if (operand.eContainer instanceof CombinedFragment) { - var combinedFragment = operand.eContainer as CombinedFragment - if (combinedFragment.keyword != 'alt' && !combinedFragment.operands.isEmpty) { - if (operand.keyword !== null || !operand.keyword.isEmpty) { - error( - 'Unexpected keyword!', - TextualScenarioPackage.Literals.OPERAND__KEYWORD - ) - } - } - } - } - - /* - * Check that the combine fragments is allocated on valid timelines - */ - @Check - def checkCombinedFragmentOnValidTimelines(CombinedFragment combinedFragment) { - var participantsDefined = TextualScenarioHelper.participantsDefinedBeforeNames(combinedFragment); - var index = 0 - for (timeline : combinedFragment.timelines) { - if (!participantsDefined.contains(timeline)) { - error('Timeline not defined in text editor!', - TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES, index) - } - index++ - } - } - - /* - * Check that a inner combine fragment has timelines over a subset in the parent combined fragment - */ - @Check - def checkContainedCombinedFragment(CombinedFragment combinedFragment) { - var container = TextualScenarioHelper.getDirectContainer(combinedFragment) - if (container instanceof CombinedFragment) { - var upperContainer = getContainerCombinedFragmentTimelines(combinedFragment.timelines, container) - if (upperContainer !== null && upperContainer instanceof CombinedFragment) { - error( - 'Timelines covered by this ' + combinedFragment.keyword + - ' must be a subset of the parent covered timelines ' + - (upperContainer as CombinedFragment).timelines + "!", - TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES - ) - } - } - } - - @Check - def checkReference(Reference reference) { - // check duplicated timelines - var hashMap = new HashMap() - var index = 0; - for (timeline : reference.timelines) { - if (hashMap.get(timeline) == null) { - hashMap.put(timeline, 1) - } else { - error('Duplicated timeline!', - TextualScenarioPackage.Literals.REFERENCE__TIMELINES, index) - } - index++ - } - - // check valid timeline (participant exists in xtext) - var participantsDefined = TextualScenarioHelper.participantsDefinedBeforeNames(reference); - index = 0 - for (timeline : reference.timelines) { - if (!participantsDefined.contains(timeline)) { - error('Timeline not defined in text editor!', - TextualScenarioPackage.Literals.REFERENCE__TIMELINES, index) - } - index++ - } - - // check reference exists - if (!EmbeddedEditorInstanceHelper.referencedScenariosName.contains(reference.name)) { - error('Referenced scenario does not exist!', - TextualScenarioPackage.Literals.REFERENCE__NAME) - } - - // check that timelines are a subset of combined fragment timelines - var container = TextualScenarioHelper.getDirectContainer(reference) - if (container instanceof CombinedFragment) { - var upperContainer = getContainerCombinedFragmentTimelines(reference.timelines, container) - if (upperContainer !== null && upperContainer instanceof CombinedFragment) { - error( - 'Timelines covered by this reference must be a subset of the parent covered timelines ' + - (upperContainer as CombinedFragment).timelines + "!", - TextualScenarioPackage.Literals.REFERENCE__TIMELINES - ) - } - } - // check timeline used after delete message - var model = TextualScenarioHelper.getModelContainer(reference) - if (model instanceof Model) { - index = 0 - for (timeline : reference.timelines) { - checkElementAfterDelete(model as Model, reference, timeline, - TextualScenarioPackage.Literals.REFERENCE__TIMELINES, index++) - } - } - } - - def EObject getContainerCombinedFragmentTimelines(List timelines, CombinedFragment container) { - // timeline must be a subset of the parent timeline - if (innerCombinedFragment(timelines, container) && - !isASubset(timelines, (container as CombinedFragment).timelines)) { - return container - } else { - var upperContainer = TextualScenarioHelper.getDirectContainer(container) - if (upperContainer instanceof CombinedFragment) { - return getContainerCombinedFragmentTimelines(timelines, upperContainer as CombinedFragment); - } - } - return null - } - - /* - * check if the smallList is a subset in the containerList - */ - def boolean isASubset(List smallList, List containerList) { - for (element : smallList) { - if(!containerList.contains(element)) { - return false - } - } - return true - } - - /* - * check if the smallList is a sublist in the containerList - */ - def boolean isASublist(List smallList, List containerList) { - for (var i = 0; i < containerList.size; i++) { - if (i < containerList.size && (i + smallList.size) <= containerList.size) { - var subset = containerList.subList(i, i + smallList.size) - if (subset !== null && smallList.equals(subset)) - return true - } - } - return false - } - /* - * we consider that it is a inner combined fragment if it has some same timelines as the parent - * added this due to the limitation that a paralel combined fragment in diagram, is represented inside the text - */ - def boolean innerCombinedFragment(List timelines, CombinedFragment container) { - for (timeline : timelines) { - if (container.timelines.contains(timeline)) - return true - } - return false - } - - def getParticipantsMapKey(Participant p) { - p.name + ":" + p.keyword - } - - def getElementMapKey(EObject element) { - - if (element instanceof CombinedFragment) { - var key = element.keyword + element.expression - for (String timeline : element.timelines.toSet.sort) { - key = key + ":" + timeline - } - return key - - } - if (element instanceof SequenceMessageType) { - return element.name + ":" + element.arrow + ":" + element.source + ":" + element.target - } - - if (element instanceof ArmTimerMessage) { - return element.participant + ":" + element.name - } - } -} +/******************************************************************************* + * Copyright (c) 2020 THALES GLOBAL SERVICES. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Thales - initial API and implementation + *******************************************************************************/ +package org.polarsys.capella.scenario.editor.dsl.validation + +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Participant +import org.polarsys.capella.scenario.editor.dsl.textualScenario.SequenceMessageType +import org.polarsys.capella.scenario.editor.dsl.textualScenario.SequenceMessage +import org.polarsys.capella.scenario.editor.dsl.textualScenario.ParticipantDeactivation +import org.polarsys.capella.scenario.editor.dsl.textualScenario.TextualScenarioPackage +import org.eclipse.xtext.validation.Check +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Model +import org.polarsys.capella.scenario.editor.helper.EmbeddedEditorInstanceHelper +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Function +import org.polarsys.capella.scenario.editor.dsl.helpers.TextualScenarioHelper +import org.polarsys.capella.scenario.editor.dsl.textualScenario.CombinedFragment +import org.eclipse.emf.ecore.EObject +import org.polarsys.capella.scenario.editor.dsl.textualScenario.DeleteMessage +import org.polarsys.capella.scenario.editor.dsl.textualScenario.CreateMessage +import org.polarsys.capella.scenario.editor.dsl.textualScenario.StateFragment +import org.polarsys.capella.scenario.editor.helper.DslConstants +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Operand +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Block +import org.polarsys.capella.scenario.editor.dsl.textualScenario.ArmTimerMessage +import org.eclipse.emf.ecore.EAttribute +import java.util.List +import java.util.Set +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Reference +import java.util.HashMap +import java.util.LinkedList +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Element +import org.eclipse.emf.ecore.EReference +import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostMessage +import org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage +import org.polarsys.capella.scenario.editor.dsl.textualScenario.Message +import org.polarsys.capella.scenario.editor.dsl.textualScenario.LostFoundMessage + +/** + * This class contains custom validation rules. + * + * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation + */ +class TextualScenarioValidator extends AbstractTextualScenarioValidator { + public static val INVALID_NAME = 'invalidName' + public static val DUPLICATED_NAME = 'duplicatedName' + public static val DUPLICATED_MESSAGES_NAME = 'duplicatedMessageName' + public static val SAME_SOURCE_AND_TARGET_ERROR = 'Invalid element! Source and target must be different!' + + @Check + def checkPartExists(Participant participant) { + if (!EmbeddedEditorInstanceHelper.getAvailablePartNames(participant.keyword).contains(participant.name)) { + if (participant instanceof Function) { + error('Function does not exist!', TextualScenarioPackage.Literals.PARTICIPANT__NAME, INVALID_NAME) + } else { + error('Represented part does not exist!', TextualScenarioPackage.Literals.PARTICIPANT__NAME, + INVALID_NAME) + } + } + } + + @Check + def checkParticipantKeywordIsValid(Participant participant) { + if (!EmbeddedEditorInstanceHelper.checkValidKeyword(participant.keyword)) { + error('\'' + participant.keyword + '\' can not be used in this diagram!', + TextualScenarioPackage.Literals.PARTICIPANT__KEYWORD) + } + } + + @Check + def checkMessagesExist(SequenceMessage message) { + if (!EmbeddedEditorInstanceHelper.getExchangeNames(message.getSource, message.getTarget).contains( + message.name)) { + error('Exchange does not exist between \"' + message.source + "\" and \"" + message.target +"\"!" + , TextualScenarioPackage.Literals.MESSAGE__NAME + ) + } + } + + @Check + def checkMessagesExist(LostMessage message) { + if (!EmbeddedEditorInstanceHelper.getExchangeNames(message.getSource, null).contains( + message.name)) { + error('Exchange does not exist from \"' + message.source + "\"!" + , TextualScenarioPackage.Literals.MESSAGE__NAME + ) + } + } + + @Check + def checkMessagesExist(FoundMessage message) { + if (!EmbeddedEditorInstanceHelper.getExchangeNames(null, message.target).contains( + message.name)) { + error('Exchange does not exist to \"' + message.target + "\"!" + , TextualScenarioPackage.Literals.MESSAGE__NAME + ) + } + } + + @Check + def checkSequenceMessagesExchangeType(SequenceMessage sequenceMessage) { + checkMessagesExchangeType(sequenceMessage) + } + + @Check + def checkSequenceMessagesExchangeType(LostFoundMessage lostFoundMessage) { + checkMessagesExchangeType(lostFoundMessage) + } + + /* + * check that a CE (component exchange) and an FE (functional exchange) are not used in the same place + */ + def checkMessagesExchangeType(Message message) { + if (EmbeddedEditorInstanceHelper.isESScenario()) { + var model = TextualScenarioHelper.getModelContainer(message) + if (model instanceof Model) { + var scenarioExchangesType = TextualScenarioHelper. + getScenarioAllowedExchangesType((model as Model).elements) + var exchangeTypes = TextualScenarioHelper.getAllMessageExchangeType(message) as Set + if (scenarioExchangesType !== null && !exchangeTypes.contains(scenarioExchangesType)) { + error('Exchange type can not be used, expected ' + scenarioExchangesType + "!", + TextualScenarioPackage.Literals.MESSAGE__NAME) + } + } + } + } + + /* + * Do not allow duplicated names, we have a combination of unique keyword + name + * ex: not allowed: actor "A1", actor "A1" + * ex: allowed: actor "A1", component "A1" + */ + @Check + def checkDuplicatedParticipantsNames(Model model) { + var index = 0 + val names = newHashSet + for (p : model.participants) { + if (!names.add(getParticipantsMapKey(p))) { + error( + 'Duplicated participant!', + TextualScenarioPackage.Literals.MODEL__PARTICIPANTS, + index, + DUPLICATED_NAME + ) + } + index++ + } + } + + @Check + def checkDeactivateMessagesModel(Model model) { + checkDeactivateMessages(model, newLinkedList, model.elements) + } + + /* + * Checks on deactivation keyword + * If we encounter a deactivation on a target, check that we have a corresponding sequence message that can be deactivated + */ + def void checkDeactivateMessages(EObject container, + LinkedList messageTargets, + List elements) { + var index = 0 + // a message shall occur before a deactivation + // keep this array with the targets of each encountered message to check that the message happens before deactivation + for (obj : elements) { + if (obj instanceof SequenceMessage && (obj as SequenceMessage).execution !== null) { + // add the already encountered messages to the list + messageTargets.add((obj as SequenceMessage).target) + } + + if (obj instanceof ArmTimerMessage && (obj as ArmTimerMessage).execution !== null) { + // add the already encountered messages to the list + messageTargets.add((obj as ArmTimerMessage).participant) + } + + if (obj instanceof FoundMessage && (obj as FoundMessage).execution !== null) { + // add the already encountered messages to the list + messageTargets.add((obj as FoundMessage).target) + } + + if (obj instanceof CombinedFragment) { + var cf = obj as CombinedFragment + checkDeactivateMessages(cf.block, + messageTargets, + cf.block.blockElements + ) + cf.operands.forEach[operand | + checkDeactivateMessages(operand.block, + messageTargets, + operand.block.blockElements + ) + ] + } + + if (obj instanceof ParticipantDeactivation) { + var refFeature = TextualScenarioPackage.Literals.MODEL__ELEMENTS + if (container instanceof Block) { + refFeature = TextualScenarioPackage.Literals.BLOCK__BLOCK_ELEMENTS + } + showErrorDeactivateMessages( + obj as ParticipantDeactivation, + container, + messageTargets, + refFeature, + index + ) + } + index++ + } + } + + def showErrorDeactivateMessages( + ParticipantDeactivation deactivation, + EObject container, + LinkedList messageTargets, + EReference refFeature, + int index + ) { + // if we already encountered a message with target ad deactivation.name, + // we will remove the message from the messages list, because this message is matched with a deactivation + var indexOfTarget = messageTargets.lastIndexOf(deactivation.name) + if (indexOfTarget < 0) { + error( + 'Deactivation keyword not expected!', + container, + refFeature, + index + ) + } else { + messageTargets.remove(indexOfTarget) + } + } + + /* + * check that the messages we define are valid + * if the message is inside a combined fragment, the messages must be between the defined timelines of the combined fragment + */ + @Check + def checkDefinedTimelinesMessages(SequenceMessageType message) { + var participantsNames = TextualScenarioHelper.participantsDefinedBeforeNames(message) + if (!participantsNames.contains(message.source)) { + error(String.format("Timeline not defined in text editor!"), TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE) + return + } + + if (!participantsNames.contains(message.target)) { + error(String.format("Timeline not defined in text editor!"), TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) + return + } + } + + @Check + def checkContainedTimelinesMessages(SequenceMessageType message) { + // if the message is inside a combined fragment, check that source and target are covered by it + var container = TextualScenarioHelper.getDirectContainer(message) + if (container instanceof CombinedFragment) { + var upContainer = getUpperContainerCombinedFragmentTimelines(message, container) + if(upContainer !== null && upContainer instanceof CombinedFragment) { + checkTimelinesMessages(message, upContainer as CombinedFragment) + } + } + } + + def EObject getUpperContainerCombinedFragmentTimelines(SequenceMessageType message, CombinedFragment container) { + if (container.timelines.contains(message.source) || container.timelines.contains(message.target)) { + return container + } else { + var upperContainer = TextualScenarioHelper.getDirectContainer(container) + if (upperContainer instanceof CombinedFragment) { + return getUpperContainerCombinedFragmentTimelines(message, upperContainer as CombinedFragment); + } + } + return null + } + + def checkTimelinesMessages(SequenceMessageType message, CombinedFragment container) { + var msg = String.format("Timeline not covered by this " + container.keyword + "!" + + " Expected values in : " + container.timelines + ) + if (!container.timelines.contains(message.source)) { + error(msg, + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE) + } + + if (!container.timelines.contains(message.target)) { + error(msg, + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) + } + } + + + @Check + def checkDeleteMessage(DeleteMessage deleteMessage) { + checkCreateOrDeleteCouldBeUsed() + checkSameSourceAndTarget(deleteMessage) + } + + // check that in opened diagram create or delete messages could be used + def checkCreateOrDeleteCouldBeUsed() { + if (EmbeddedEditorInstanceHelper.isFSScenario() || + (EmbeddedEditorInstanceHelper.isESScenario() && !EmbeddedEditorInstanceHelper.isInteractionScenario) + ) { + error("Create or delete message can not be used in this diagram!", + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__ARROW) + } + } + + @Check + def checkArmTimer(ArmTimerMessage armTimer) { + // check arm timer could be used in opened diagram + if (EmbeddedEditorInstanceHelper.isFSScenario()) { + error("Arm Timer can not be used in this diagram!", + TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__ARROW) + } + + // check timeline exist + if (!TextualScenarioHelper.participantsDefinedBeforeNames(armTimer).contains(armTimer.participant)) { + error("Timeline not defined in text editor!", + TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__PARTICIPANT) + } + } + + @Check + def checkLostMessage(LostMessage message) { + // check lost message could be used in opened diagram + if (!EmbeddedEditorInstanceHelper.isESScenario()) { + error("Lost message can not be used in this diagram!", + TextualScenarioPackage.Literals.LOST_FOUND_MESSAGE__ARROW) + } + + // check timeline exist + if (!TextualScenarioHelper.participantsDefinedBeforeNames(message).contains(message.source)) { + error("Timeline not defined in text editor!", + TextualScenarioPackage.Literals.LOST_MESSAGE__SOURCE) + } + } + + @Check + def checkFoundMessage(FoundMessage message) { + // check found message could be used in opened diagram + if (!EmbeddedEditorInstanceHelper.isESScenario()) { + error("Found message can not be used in this diagram!", + TextualScenarioPackage.Literals.LOST_FOUND_MESSAGE__ARROW) + } + + // check timeline exist + if (!TextualScenarioHelper.participantsDefinedBeforeNames(message).contains(message.target)) { + error("Timeline not defined in text editor!", + TextualScenarioPackage.Literals.FOUND_MESSAGE__TARGET) + } + } + + def checkSameSourceAndTarget(SequenceMessageType message) { + if (message.source.equals(message.target)) { + error(SAME_SOURCE_AND_TARGET_ERROR, + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) + error(SAME_SOURCE_AND_TARGET_ERROR, + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE) + } + } + + /* + * check if a timeline involved in a combined fragment was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkTimelineUsedAfterDeleteMessage(CombinedFragment combinedFragment) { + var model = TextualScenarioHelper.getModelContainer(combinedFragment) + if (model instanceof Model) { + var index = 0 + for (timeline : combinedFragment.timelines) { + checkElementAfterDelete(model as Model, combinedFragment, timeline, + TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES, index++) + } + } + } + + /* + * check if the timeline involved in a state fragment was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkTimelineUsedAfterDeleteMessage(StateFragment fragment) { + var model = TextualScenarioHelper.getModelContainer(fragment) + if (model instanceof Model) + checkElementAfterDelete(model as Model, fragment, fragment.timeline, + TextualScenarioPackage.Literals.STATE_FRAGMENT__TIMELINE, 0) + } + + /* + * check if a participant involved in arm timer was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkParticipantUsedAfterDeleteMessage(ArmTimerMessage armTimer) { + var model = TextualScenarioHelper.getModelContainer(armTimer) + if (model instanceof Model) + checkElementAfterDelete(model as Model, armTimer, armTimer.participant, + TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__PARTICIPANT, 0) + } + + /* + * check if a participant involved in a lost message was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkParticipantUsedAfterLostMessage(LostMessage message) { + var model = TextualScenarioHelper.getModelContainer(message) + if (model instanceof Model) + checkElementAfterDelete(model as Model, message, message.source, + TextualScenarioPackage.Literals.LOST_MESSAGE__SOURCE, 0) + } + + /* + * check if a participant involved in a lost message was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkParticipantUsedAfterFoundMessage(FoundMessage message) { + var model = TextualScenarioHelper.getModelContainer(message) + if (model instanceof Model) + checkElementAfterDelete(model as Model, message, message.target, + TextualScenarioPackage.Literals.FOUND_MESSAGE__TARGET, 0) + } + + /* + * check if a sequence message source element was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkMessageSourceUsedAfterDeleteMessage(SequenceMessageType message) { + var model = TextualScenarioHelper.getModelContainer(message) + if (model instanceof Model) + checkElementAfterDelete(model as Model, message, message.source, + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE, 0) + } + + /* + * check if a sequence message target element was used after a delete message was already defined + * on the previous lines on the same timeline + */ + @Check + def checkMessageTargetUsedAfterDeleteMessage(SequenceMessageType message) { + var model = TextualScenarioHelper.getModelContainer(message) + if (model instanceof Model) + checkElementAfterDelete(model as Model, message, message.target, + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET, 0) + } + + + def boolean checkElementAfterDelete(EObject model, EObject checkedElement, String target, + EAttribute checkedAttribute, int index) { + var elements = TextualScenarioHelper.getContainerElements(model) + + for (EObject element : elements) { + if (element.equals(checkedElement)) { + return true + } + + if (element instanceof DeleteMessage) { + if ((element as DeleteMessage).target.equals(target)) { + error(String.format( + "Element \"" + target + + "\" can not be used at this point! A delete message was already defined on this timeline." + ), checkedAttribute, index) + return true + } + } + + if (element instanceof CombinedFragment) { + if(checkElementAfterDelete(element, checkedElement, target, checkedAttribute, index)) { + return true; + } + } + } + return false; + } + + /* + * check if create message could be used + */ + @Check + def checkCreateMessage(CreateMessage createMessage) { + // check if create message could be used in opened diagram + checkCreateOrDeleteCouldBeUsed() + + // check if source and target are the same + checkSameSourceAndTarget(createMessage) + var model = TextualScenarioHelper.getModelContainer(createMessage) + if (model instanceof Model && !checkCreateMessageValid(model as Model, createMessage)) { + errorCreateMessage(createMessage.target) + } + } + + def boolean checkCreateMessageValid(EObject model, CreateMessage createMessage) { + var target = createMessage.target + var elements = TextualScenarioHelper.getContainerElements(model) + + for (EObject element : elements) { + if (element instanceof SequenceMessageType) { + if (element.equals(createMessage)) { + return true + } + + if ((element as SequenceMessageType).target.equals(target) || + (element as SequenceMessageType).source.equals(target)) { + return false + } + } + + if (element instanceof ArmTimerMessage) { + if ((element as ArmTimerMessage).participant.equals(target)) { + return false + } + } + + if (element instanceof LostMessage) { + if ((element as LostMessage).source.equals(target)) { + return false + } + } + + if (element instanceof FoundMessage) { + if ((element as FoundMessage).target.equals(target)) { + return false + } + } + + if (element instanceof CombinedFragment) { + if ((element as CombinedFragment).timelines.contains(target)) { + return false + } else { + if (!(checkCreateMessageValid(element, createMessage) as Boolean)) { + return false + } + } + } + + if (element instanceof StateFragment) { + if ((element as StateFragment).timeline.equals(target)) { + return false + } + } + + if (element instanceof Reference) { + if ((element as Reference).timelines.contains(target)) { + return false; + } + } + } + return true + } + + def errorCreateMessage(String target) { + error(String.format("Target \"" + target +"\" can not be used in a create message at this point! Other operations were already defined on this timeline."), + TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET) + } + + + /* + * Validate a State Fragment + */ + @Check + def checkStateFragment(StateFragment fragment) { + if (!TextualScenarioHelper.participantsDefinedBeforeNames(fragment).contains(fragment.timeline)) { + error(String.format("Timeline not defined in text editor!", fragment.keyword), + TextualScenarioPackage.Literals.STATE_FRAGMENT__TIMELINE) + return + } + + var scenarioType = EmbeddedEditorInstanceHelper.getScenarioType(); + if (fragment.keyword.equals(DslConstants.FUNCTION) && scenarioType.equals(DslConstants.FUNCTIONAL)) { + error(String.format("\'function\' can not be used in this diagram!"), + TextualScenarioPackage.Literals.STATE_FRAGMENT__KEYWORD) + return + } + + var availableStateFragments = EmbeddedEditorInstanceHelper.getAvailableStateFragments(fragment.keyword, + fragment.timeline) + if (!availableStateFragments.contains(fragment.name)) { + error( + String.format("This " + fragment.keyword + " does not exist or is not available for \"" + + fragment.timeline +"\"!"), TextualScenarioPackage.Literals.STATE_FRAGMENT__NAME) + } + + } + + /* + * Check that each withExecution message is closed by deactivation (on the proper target) + */ + @Check + def checkWithExecutionHasDeactivateModel(Model model) { + var messageWithExecutionTargets = newLinkedList + var messageWithExecutionTargetsIndex = newLinkedList + var messageWithExecutionTargetsContainer = newLinkedList + checkWithExecutionHasDeactivate(model, + messageWithExecutionTargets, + messageWithExecutionTargetsIndex, + messageWithExecutionTargetsContainer, + model.elements + ) + + showErrorWithExecutionHasDeactivate(messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer) + } + + def void showErrorWithExecutionHasDeactivate( + LinkedList messageWithExecutionTargets, + LinkedList messageWithExecutionTargetsIndex, + LinkedList messageWithExecutionTargetsContainer + ) { + // if not all withExecution messages were matched with a deactivation, show an error + // use the index list to know on which message to display the error + for (var i = 0; i < messageWithExecutionTargets.size; i++) { + var container = messageWithExecutionTargetsContainer.get(i) + if (container instanceof Model) { + error( + 'Deactivation keyword expected for a withExecution message!', + container, + TextualScenarioPackage.Literals.MODEL__ELEMENTS, + messageWithExecutionTargetsIndex.get(i) + ) + } else if (container instanceof Block) { + error( + 'Deactivation keyword expected for a withExecution message!', + container, + TextualScenarioPackage.Literals.BLOCK__BLOCK_ELEMENTS, + messageWithExecutionTargets.get(i) + ) + } + } + } + + def void checkWithExecutionHasDeactivate(EObject container, + LinkedList messageWithExecutionTargets, + LinkedList messageWithExecutionTargetsIndex, + LinkedList messageWithExecutionTargetsContainer, + List elements + ) { + // keep a list with the target of the messages that contains the withExecution keyword + // keep also a list with the index on which withExecution message is found, to know on which line to show an error + var index = 0 + for (obj : elements) { + if (obj instanceof SequenceMessage && (obj as SequenceMessage).execution !== null) { + // add the SequenceMessage with execution to a list + messageWithExecutionTargets.add((obj as SequenceMessage).target) + messageWithExecutionTargetsIndex.add(index) + messageWithExecutionTargetsContainer.add(container) + } + + if (obj instanceof ArmTimerMessage && (obj as ArmTimerMessage).execution !== null) { + messageWithExecutionTargets.add((obj as ArmTimerMessage).participant) + messageWithExecutionTargetsIndex.add(index) + messageWithExecutionTargetsContainer.add(container) + } + + if (obj instanceof FoundMessage && (obj as FoundMessage).execution !== null) { + messageWithExecutionTargets.add((obj as FoundMessage).target) + messageWithExecutionTargetsIndex.add(index) + messageWithExecutionTargetsContainer.add(container) + } + + if (obj instanceof CombinedFragment) { + var cf = obj as CombinedFragment + checkWithExecutionHasDeactivate(cf.block, messageWithExecutionTargets, + messageWithExecutionTargetsIndex, + messageWithExecutionTargetsContainer, + cf.block.blockElements + ) + cf.operands.forEach[operand | + checkWithExecutionHasDeactivate(operand.block, + messageWithExecutionTargets, + messageWithExecutionTargetsIndex, + messageWithExecutionTargetsContainer, + operand.block.blockElements + ) + ] + } + + if (obj instanceof ParticipantDeactivation) { + var targetName = (obj as ParticipantDeactivation).name + var indexOfTarget = messageWithExecutionTargets.lastIndexOf(targetName) + + if (indexOfTarget >= 0) { + messageWithExecutionTargets.remove(indexOfTarget) + messageWithExecutionTargetsIndex.remove(indexOfTarget) + messageWithExecutionTargetsContainer.remove(indexOfTarget) + } + } + index++ + } + } + + /* + * Else keyword shall be put on a combined fragment that is ALT + */ + @Check + def checkElseKeyworkAvailable(Operand operand) { + if (operand.eContainer instanceof CombinedFragment) { + var combinedFragment = operand.eContainer as CombinedFragment + if (combinedFragment.keyword == 'alt' && !combinedFragment.operands.isEmpty) { + if (operand.keyword != 'else') { + error( + 'Expected \'else\' keyword!', + TextualScenarioPackage.Literals.OPERAND__KEYWORD + ) + } + } + } + } + + /* + * No keyword shall be put on a combined fragment that is not ALT + */ + @Check + def checkKeyworkNotAvailable(Operand operand) { + if (operand.eContainer instanceof CombinedFragment) { + var combinedFragment = operand.eContainer as CombinedFragment + if (combinedFragment.keyword != 'alt' && !combinedFragment.operands.isEmpty) { + if (operand.keyword !== null || !operand.keyword.isEmpty) { + error( + 'Unexpected keyword!', + TextualScenarioPackage.Literals.OPERAND__KEYWORD + ) + } + } + } + } + + /* + * Check that the combine fragments is allocated on valid timelines + */ + @Check + def checkCombinedFragmentOnValidTimelines(CombinedFragment combinedFragment) { + var participantsDefined = TextualScenarioHelper.participantsDefinedBeforeNames(combinedFragment); + var index = 0 + for (timeline : combinedFragment.timelines) { + if (!participantsDefined.contains(timeline)) { + error('Timeline not defined in text editor!', + TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES, index) + } + index++ + } + } + + /* + * Check that a inner combine fragment has timelines over a subset in the parent combined fragment + */ + @Check + def checkContainedCombinedFragment(CombinedFragment combinedFragment) { + var container = TextualScenarioHelper.getDirectContainer(combinedFragment) + if (container instanceof CombinedFragment) { + var upperContainer = getContainerCombinedFragmentTimelines(combinedFragment.timelines, container) + if (upperContainer !== null && upperContainer instanceof CombinedFragment) { + error( + 'Timelines covered by this ' + combinedFragment.keyword + + ' must be a subset of the parent covered timelines ' + + (upperContainer as CombinedFragment).timelines + "!", + TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES + ) + } + } + } + + @Check + def checkReference(Reference reference) { + // check duplicated timelines + var hashMap = new HashMap() + var index = 0; + for (timeline : reference.timelines) { + if (hashMap.get(timeline) == null) { + hashMap.put(timeline, 1) + } else { + error('Duplicated timeline!', + TextualScenarioPackage.Literals.REFERENCE__TIMELINES, index) + } + index++ + } + + // check valid timeline (participant exists in xtext) + var participantsDefined = TextualScenarioHelper.participantsDefinedBeforeNames(reference); + index = 0 + for (timeline : reference.timelines) { + if (!participantsDefined.contains(timeline)) { + error('Timeline not defined in text editor!', + TextualScenarioPackage.Literals.REFERENCE__TIMELINES, index) + } + index++ + } + + // check reference exists + if (!EmbeddedEditorInstanceHelper.referencedScenariosName.contains(reference.name)) { + error('Referenced scenario does not exist!', + TextualScenarioPackage.Literals.REFERENCE__NAME) + } + + // check that timelines are a subset of combined fragment timelines + var container = TextualScenarioHelper.getDirectContainer(reference) + if (container instanceof CombinedFragment) { + var upperContainer = getContainerCombinedFragmentTimelines(reference.timelines, container) + if (upperContainer !== null && upperContainer instanceof CombinedFragment) { + error( + 'Timelines covered by this reference must be a subset of the parent covered timelines ' + + (upperContainer as CombinedFragment).timelines + "!", + TextualScenarioPackage.Literals.REFERENCE__TIMELINES + ) + } + } + // check timeline used after delete message + var model = TextualScenarioHelper.getModelContainer(reference) + if (model instanceof Model) { + index = 0 + for (timeline : reference.timelines) { + checkElementAfterDelete(model as Model, reference, timeline, + TextualScenarioPackage.Literals.REFERENCE__TIMELINES, index++) + } + } + } + + def EObject getContainerCombinedFragmentTimelines(List timelines, CombinedFragment container) { + // timeline must be a subset of the parent timeline + if (innerCombinedFragment(timelines, container) && + !isASubset(timelines, (container as CombinedFragment).timelines)) { + return container + } else { + var upperContainer = TextualScenarioHelper.getDirectContainer(container) + if (upperContainer instanceof CombinedFragment) { + return getContainerCombinedFragmentTimelines(timelines, upperContainer as CombinedFragment); + } + } + return null + } + + /* + * check if the smallList is a subset in the containerList + */ + def boolean isASubset(List smallList, List containerList) { + for (element : smallList) { + if(!containerList.contains(element)) { + return false + } + } + return true + } + + /* + * check if the smallList is a sublist in the containerList + */ + def boolean isASublist(List smallList, List containerList) { + for (var i = 0; i < containerList.size; i++) { + if (i < containerList.size && (i + smallList.size) <= containerList.size) { + var subset = containerList.subList(i, i + smallList.size) + if (subset !== null && smallList.equals(subset)) + return true + } + } + return false + } + /* + * we consider that it is a inner combined fragment if it has some same timelines as the parent + * added this due to the limitation that a paralel combined fragment in diagram, is represented inside the text + */ + def boolean innerCombinedFragment(List timelines, CombinedFragment container) { + for (timeline : timelines) { + if (container.timelines.contains(timeline)) + return true + } + return false + } + + def getParticipantsMapKey(Participant p) { + p.name + ":" + p.keyword + } + + def getElementMapKey(EObject element) { + + if (element instanceof CombinedFragment) { + var key = element.keyword + element.expression + for (String timeline : element.timelines.toSet.sort) { + key = key + ":" + timeline + } + return key + + } + if (element instanceof SequenceMessageType) { + return element.name + ":" + element.arrow + ":" + element.source + ":" + element.target + } + + if (element instanceof ArmTimerMessage) { + return element.participant + ":" + element.name + } + } +} diff --git a/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.java b/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.java index 3c74bcac..9c14b5c2 100644 --- a/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.java +++ b/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/helpers/TextualScenarioHelper.java @@ -1,15 +1,3 @@ -/******************************************************************************* - * Copyright (c) 2020 THALES GLOBAL SERVICES. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Thales - initial API and implementation - ******************************************************************************/ /** * Copyright (c) 2020 THALES GLOBAL SERVICES. * @@ -192,7 +180,7 @@ public static boolean isParticipantKeyword(final String keywordValue) { /** * get all elements on the same level as modelContainer */ - public static List getElements(final EObject modelContainer) { + public static List getContainerElements(final EObject modelContainer) { if ((modelContainer instanceof Model)) { return ((Model) modelContainer).getElements(); } @@ -208,7 +196,23 @@ public static List getElements(final EObject modelContainer) { if ((modelContainer instanceof Block)) { return ((Block) modelContainer).getBlockElements(); } - return null; + return CollectionLiterals.newArrayList(); + } + + /** + * get all elements from xtext + */ + public static List getAllElements(final EObject modelContainer, final List allElements) { + List _containerElements = TextualScenarioHelper.getContainerElements(modelContainer); + for (final Element element : _containerElements) { + if ((!(element instanceof CombinedFragment))) { + allElements.add(element); + } else { + allElements.add(element); + TextualScenarioHelper.getAllElements(element, allElements); + } + } + return allElements; } /** diff --git a/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.java b/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.java index 7f6de3e9..8f429926 100644 --- a/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.java +++ b/plugins/org.polarsys.capella.scenario.editor.dsl/xtend-gen/org/polarsys/capella/scenario/editor/dsl/validation/TextualScenarioValidator.java @@ -59,17 +59,20 @@ */ @SuppressWarnings("all") public class TextualScenarioValidator extends AbstractTextualScenarioValidator { - public static final String INVALID_NAME = "invalidName"; + public final static String INVALID_NAME = "invalidName"; - public static final String DUPLICATED_NAME = "duplicatedName"; + public final static String DUPLICATED_NAME = "duplicatedName"; - public static final String DUPLICATED_MESSAGES_NAME = "duplicatedMessageName"; + public final static String DUPLICATED_MESSAGES_NAME = "duplicatedMessageName"; - public static final String SAME_SOURCE_AND_TARGET_ERROR = "Invalid element! Source and target must be different!"; + public final static String SAME_SOURCE_AND_TARGET_ERROR = "Invalid element! Source and target must be different!"; @Check public void checkPartExists(final Participant participant) { - boolean _contains = EmbeddedEditorInstanceHelper.getAvailablePartNames(participant.getKeyword()).contains(participant.getName()); + String _keyword = participant.getKeyword(); + List _availablePartNames = EmbeddedEditorInstanceHelper.getAvailablePartNames(_keyword); + String _name = participant.getName(); + boolean _contains = _availablePartNames.contains(_name); boolean _not = (!_contains); if (_not) { if ((participant instanceof Function)) { @@ -83,11 +86,12 @@ public void checkPartExists(final Participant participant) { @Check public void checkParticipantKeywordIsValid(final Participant participant) { - boolean _checkValidKeyword = EmbeddedEditorInstanceHelper.checkValidKeyword(participant.getKeyword()); + String _keyword = participant.getKeyword(); + boolean _checkValidKeyword = EmbeddedEditorInstanceHelper.checkValidKeyword(_keyword); boolean _not = (!_checkValidKeyword); if (_not) { - String _keyword = participant.getKeyword(); - String _plus = ("\'" + _keyword); + String _keyword_1 = participant.getKeyword(); + String _plus = ("\'" + _keyword_1); String _plus_1 = (_plus + "\' can not be used in this diagram!"); this.error(_plus_1, TextualScenarioPackage.Literals.PARTICIPANT__KEYWORD); @@ -96,39 +100,50 @@ public void checkParticipantKeywordIsValid(final Participant participant) { @Check public void checkMessagesExist(final SequenceMessage message) { - boolean _contains = EmbeddedEditorInstanceHelper.getExchangeNames(message.getSource(), message.getTarget()).contains( - message.getName()); + String _source = message.getSource(); + String _target = message.getTarget(); + List _exchangeNames = EmbeddedEditorInstanceHelper.getExchangeNames(_source, _target); + String _name = message.getName(); + boolean _contains = _exchangeNames.contains(_name); boolean _not = (!_contains); if (_not) { - String _source = message.getSource(); - String _plus = ("Exchange does not exist between \"" + _source); + String _source_1 = message.getSource(); + String _plus = ("Exchange does not exist between \"" + _source_1); String _plus_1 = (_plus + "\" and \""); - String _target = message.getTarget(); - String _plus_2 = (_plus_1 + _target); + String _target_1 = message.getTarget(); + String _plus_2 = (_plus_1 + _target_1); String _plus_3 = (_plus_2 + "\"!"); this.error(_plus_3, TextualScenarioPackage.Literals.MESSAGE__NAME); } } - /** - * Check that the source and the target of the sequence messages type are defined in text, before using them in the message - */ @Check - public void checkParticipantsInvolvedExist(final SequenceMessageType message) { - ArrayList participantsDefined = TextualScenarioHelper.participantsDefinedBeforeNames(message); - boolean _contains = participantsDefined.contains(message.getSource()); + public void checkMessagesExist(final LostMessage message) { + String _source = message.getSource(); + List _exchangeNames = EmbeddedEditorInstanceHelper.getExchangeNames(_source, null); + String _name = message.getName(); + boolean _contains = _exchangeNames.contains(_name); boolean _not = (!_contains); if (_not) { - this.error( - "Source participant not defined in text editor!", - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE); + String _source_1 = message.getSource(); + String _plus = ("Exchange does not exist from \"" + _source_1); + String _plus_1 = (_plus + "\"!"); + this.error(_plus_1, TextualScenarioPackage.Literals.MESSAGE__NAME); } - boolean _contains_1 = participantsDefined.contains(message.getTarget()); - boolean _not_1 = (!_contains_1); - if (_not_1) { - this.error( - "Target participant not defined in text editor!", - TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET); + } + + @Check + public void checkMessagesExist(final FoundMessage message) { + String _target = message.getTarget(); + List _exchangeNames = EmbeddedEditorInstanceHelper.getExchangeNames(null, _target); + String _name = message.getName(); + boolean _contains = _exchangeNames.contains(_name); + boolean _not = (!_contains); + if (_not) { + String _target_1 = message.getTarget(); + String _plus = ("Exchange does not exist to \"" + _target_1); + String _plus_1 = (_plus + "\"!"); + this.error(_plus_1, TextualScenarioPackage.Literals.MESSAGE__NAME); } } @@ -150,7 +165,8 @@ public void checkMessagesExchangeType(final Message message) { if (_isESScenario) { EObject model = TextualScenarioHelper.getModelContainer(message); if ((model instanceof Model)) { - Object scenarioExchangesType = TextualScenarioHelper.getScenarioAllowedExchangesType(((Model) model).getElements()); + EList _elements = ((Model) model).getElements(); + Object scenarioExchangesType = TextualScenarioHelper.getScenarioAllowedExchangesType(_elements); Set _allMessageExchangeType = TextualScenarioHelper.getAllMessageExchangeType(message); Set exchangeTypes = ((Set) _allMessageExchangeType); if (((scenarioExchangesType != null) && (!exchangeTypes.contains(scenarioExchangesType)))) { @@ -173,7 +189,8 @@ public void checkDuplicatedParticipantsNames(final Model model) { EList _participants = model.getParticipants(); for (final Participant p : _participants) { { - boolean _add = names.add(this.getParticipantsMapKey(p)); + String _participantsMapKey = this.getParticipantsMapKey(p); + boolean _add = names.add(_participantsMapKey); boolean _not = (!_add); if (_not) { this.error( @@ -188,7 +205,9 @@ public void checkDuplicatedParticipantsNames(final Model model) { @Check public void checkDeactivateMessagesModel(final Model model) { - this.checkDeactivateMessages(model, CollectionLiterals.newLinkedList(), model.getElements()); + LinkedList _newLinkedList = CollectionLiterals.newLinkedList(); + EList _elements = model.getElements(); + this.checkDeactivateMessages(model, _newLinkedList, _elements); } /** @@ -200,23 +219,31 @@ public void checkDeactivateMessages(final EObject container, final LinkedList _blockElements = _block_1.getBlockElements(); + this.checkDeactivateMessages(_block, messageTargets, _blockElements); + EList _operands = cf.getOperands(); final Consumer _function = (Operand operand) -> { - this.checkDeactivateMessages(operand.getBlock(), messageTargets, - operand.getBlock().getBlockElements()); + Block _block_2 = operand.getBlock(); + Block _block_3 = operand.getBlock(); + EList _blockElements_1 = _block_3.getBlockElements(); + this.checkDeactivateMessages(_block_2, messageTargets, _blockElements_1); }; - cf.getOperands().forEach(_function); + _operands.forEach(_function); } if ((obj instanceof ParticipantDeactivation)) { EReference refFeature = TextualScenarioPackage.Literals.MODEL__ELEMENTS; @@ -234,7 +261,8 @@ public void checkDeactivateMessages(final EObject container, final LinkedList messageTargets, final EReference refFeature, final int index) { String _xblockexpression = null; { - int indexOfTarget = messageTargets.lastIndexOf(deactivation.getName()); + String _name = deactivation.getName(); + int indexOfTarget = messageTargets.lastIndexOf(_name); String _xifexpression = null; if ((indexOfTarget < 0)) { this.error( @@ -254,16 +282,20 @@ public String showErrorDeactivateMessages(final ParticipantDeactivation deactiva @Check public void checkDefinedTimelinesMessages(final SequenceMessageType message) { ArrayList participantsNames = TextualScenarioHelper.participantsDefinedBeforeNames(message); - boolean _contains = participantsNames.contains(message.getSource()); + String _source = message.getSource(); + boolean _contains = participantsNames.contains(_source); boolean _not = (!_contains); if (_not) { - this.error(String.format("Timeline not defined in text editor!"), TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE); + String _format = String.format("Timeline not defined in text editor!"); + this.error(_format, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE); return; } - boolean _contains_1 = participantsNames.contains(message.getTarget()); + String _target = message.getTarget(); + boolean _contains_1 = participantsNames.contains(_target); boolean _not_1 = (!_contains_1); if (_not_1) { - this.error(String.format("Timeline not defined in text editor!"), TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET); + String _format_1 = String.format("Timeline not defined in text editor!"); + this.error(_format_1, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET); return; } } @@ -300,13 +332,17 @@ public void checkTimelinesMessages(final SequenceMessageType message, final Comb EList _timelines = container.getTimelines(); String _plus_3 = (_plus_2 + _timelines); String msg = String.format(_plus_3); - boolean _contains = container.getTimelines().contains(message.getSource()); + EList _timelines_1 = container.getTimelines(); + String _source = message.getSource(); + boolean _contains = _timelines_1.contains(_source); boolean _not = (!_contains); if (_not) { this.error(msg, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE); } - boolean _contains_1 = container.getTimelines().contains(message.getTarget()); + EList _timelines_2 = container.getTimelines(); + String _target = message.getTarget(); + boolean _contains_1 = _timelines_2.contains(_target); boolean _not_1 = (!_contains_1); if (_not_1) { this.error(msg, @@ -334,7 +370,9 @@ public void checkArmTimer(final ArmTimerMessage armTimer) { this.error("Arm Timer can not be used in this diagram!", TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__ARROW); } - boolean _contains = TextualScenarioHelper.participantsDefinedBeforeNames(armTimer).contains(armTimer.getParticipant()); + ArrayList _participantsDefinedBeforeNames = TextualScenarioHelper.participantsDefinedBeforeNames(armTimer); + String _participant = armTimer.getParticipant(); + boolean _contains = _participantsDefinedBeforeNames.contains(_participant); boolean _not = (!_contains); if (_not) { this.error("Timeline not defined in text editor!", @@ -350,7 +388,9 @@ public void checkLostMessage(final LostMessage message) { this.error("Lost message can not be used in this diagram!", TextualScenarioPackage.Literals.LOST_FOUND_MESSAGE__ARROW); } - boolean _contains = TextualScenarioHelper.participantsDefinedBeforeNames(message).contains(message.getSource()); + ArrayList _participantsDefinedBeforeNames = TextualScenarioHelper.participantsDefinedBeforeNames(message); + String _source = message.getSource(); + boolean _contains = _participantsDefinedBeforeNames.contains(_source); boolean _not_1 = (!_contains); if (_not_1) { this.error("Timeline not defined in text editor!", @@ -366,7 +406,9 @@ public void checkFoundMessage(final FoundMessage message) { this.error("Found message can not be used in this diagram!", TextualScenarioPackage.Literals.LOST_FOUND_MESSAGE__ARROW); } - boolean _contains = TextualScenarioHelper.participantsDefinedBeforeNames(message).contains(message.getTarget()); + ArrayList _participantsDefinedBeforeNames = TextualScenarioHelper.participantsDefinedBeforeNames(message); + String _target = message.getTarget(); + boolean _contains = _participantsDefinedBeforeNames.contains(_target); boolean _not_1 = (!_contains); if (_not_1) { this.error("Timeline not defined in text editor!", @@ -375,7 +417,9 @@ public void checkFoundMessage(final FoundMessage message) { } public void checkSameSourceAndTarget(final SequenceMessageType message) { - boolean _equals = message.getSource().equals(message.getTarget()); + String _source = message.getSource(); + String _target = message.getTarget(); + boolean _equals = _source.equals(_target); if (_equals) { this.error(TextualScenarioValidator.SAME_SOURCE_AND_TARGET_ERROR, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET); @@ -413,7 +457,8 @@ public boolean checkTimelineUsedAfterDeleteMessage(final StateFragment fragment) EObject model = TextualScenarioHelper.getModelContainer(fragment); boolean _xifexpression = false; if ((model instanceof Model)) { - _xifexpression = this.checkElementAfterDelete(((Model) model), fragment, fragment.getTimeline(), + String _timeline = fragment.getTimeline(); + _xifexpression = this.checkElementAfterDelete(((Model) model), fragment, _timeline, TextualScenarioPackage.Literals.STATE_FRAGMENT__TIMELINE, 0); } _xblockexpression = _xifexpression; @@ -432,7 +477,8 @@ public boolean checkParticipantUsedAfterDeleteMessage(final ArmTimerMessage armT EObject model = TextualScenarioHelper.getModelContainer(armTimer); boolean _xifexpression = false; if ((model instanceof Model)) { - _xifexpression = this.checkElementAfterDelete(((Model) model), armTimer, armTimer.getParticipant(), + String _participant = armTimer.getParticipant(); + _xifexpression = this.checkElementAfterDelete(((Model) model), armTimer, _participant, TextualScenarioPackage.Literals.ARM_TIMER_MESSAGE__PARTICIPANT, 0); } _xblockexpression = _xifexpression; @@ -451,7 +497,8 @@ public boolean checkParticipantUsedAfterLostMessage(final LostMessage message) { EObject model = TextualScenarioHelper.getModelContainer(message); boolean _xifexpression = false; if ((model instanceof Model)) { - _xifexpression = this.checkElementAfterDelete(((Model) model), message, message.getSource(), + String _source = message.getSource(); + _xifexpression = this.checkElementAfterDelete(((Model) model), message, _source, TextualScenarioPackage.Literals.LOST_MESSAGE__SOURCE, 0); } _xblockexpression = _xifexpression; @@ -470,7 +517,8 @@ public boolean checkParticipantUsedAfterFoundMessage(final FoundMessage message) EObject model = TextualScenarioHelper.getModelContainer(message); boolean _xifexpression = false; if ((model instanceof Model)) { - _xifexpression = this.checkElementAfterDelete(((Model) model), message, message.getTarget(), + String _target = message.getTarget(); + _xifexpression = this.checkElementAfterDelete(((Model) model), message, _target, TextualScenarioPackage.Literals.FOUND_MESSAGE__TARGET, 0); } _xblockexpression = _xifexpression; @@ -489,7 +537,8 @@ public boolean checkMessageSourceUsedAfterDeleteMessage(final SequenceMessageTyp EObject model = TextualScenarioHelper.getModelContainer(message); boolean _xifexpression = false; if ((model instanceof Model)) { - _xifexpression = this.checkElementAfterDelete(((Model) model), message, message.getSource(), + String _source = message.getSource(); + _xifexpression = this.checkElementAfterDelete(((Model) model), message, _source, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__SOURCE, 0); } _xblockexpression = _xifexpression; @@ -508,7 +557,8 @@ public boolean checkMessageTargetUsedAfterDeleteMessage(final SequenceMessageTyp EObject model = TextualScenarioHelper.getModelContainer(message); boolean _xifexpression = false; if ((model instanceof Model)) { - _xifexpression = this.checkElementAfterDelete(((Model) model), message, message.getTarget(), + String _target = message.getTarget(); + _xifexpression = this.checkElementAfterDelete(((Model) model), message, _target, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET, 0); } _xblockexpression = _xifexpression; @@ -517,7 +567,7 @@ public boolean checkMessageTargetUsedAfterDeleteMessage(final SequenceMessageTyp } public boolean checkElementAfterDelete(final EObject model, final EObject checkedElement, final String target, final EAttribute checkedAttribute, final int index) { - List elements = TextualScenarioHelper.getElements(model); + List elements = TextualScenarioHelper.getContainerElements(model); for (final EObject element : elements) { { boolean _equals = element.equals(checkedElement); @@ -525,12 +575,13 @@ public boolean checkElementAfterDelete(final EObject model, final EObject checke return true; } if ((element instanceof DeleteMessage)) { - boolean _equals_1 = ((DeleteMessage) element).getTarget().equals(target); + String _target = ((DeleteMessage) element).getTarget(); + boolean _equals_1 = _target.equals(target); if (_equals_1) { - this.error( - String.format( - (("Element \"" + target) + - "\" can not be used at this point! A delete message was already defined on this timeline.")), checkedAttribute, index); + String _format = String.format( + (("Element \"" + target) + + "\" can not be used at this point! A delete message was already defined on this timeline.")); + this.error(_format, checkedAttribute, index); return true; } } @@ -554,13 +605,14 @@ public void checkCreateMessage(final CreateMessage createMessage) { this.checkSameSourceAndTarget(createMessage); EObject model = TextualScenarioHelper.getModelContainer(createMessage); if (((model instanceof Model) && (!this.checkCreateMessageValid(((Model) model), createMessage)))) { - this.errorCreateMessage(createMessage.getTarget()); + String _target = createMessage.getTarget(); + this.errorCreateMessage(_target); } } public boolean checkCreateMessageValid(final EObject model, final CreateMessage createMessage) { String target = createMessage.getTarget(); - List elements = TextualScenarioHelper.getElements(model); + List elements = TextualScenarioHelper.getContainerElements(model); for (final EObject element : elements) { { if ((element instanceof SequenceMessageType)) { @@ -574,25 +626,29 @@ public boolean checkCreateMessageValid(final EObject model, final CreateMessage } } if ((element instanceof ArmTimerMessage)) { - boolean _equals_1 = ((ArmTimerMessage) element).getParticipant().equals(target); + String _participant = ((ArmTimerMessage) element).getParticipant(); + boolean _equals_1 = _participant.equals(target); if (_equals_1) { return false; } } if ((element instanceof LostMessage)) { - boolean _equals_2 = ((LostMessage) element).getSource().equals(target); + String _source = ((LostMessage) element).getSource(); + boolean _equals_2 = _source.equals(target); if (_equals_2) { return false; } } if ((element instanceof FoundMessage)) { - boolean _equals_3 = ((FoundMessage) element).getTarget().equals(target); + String _target = ((FoundMessage) element).getTarget(); + boolean _equals_3 = _target.equals(target); if (_equals_3) { return false; } } if ((element instanceof CombinedFragment)) { - boolean _contains = ((CombinedFragment) element).getTimelines().contains(target); + EList _timelines = ((CombinedFragment) element).getTimelines(); + boolean _contains = _timelines.contains(target); if (_contains) { return false; } else { @@ -604,13 +660,15 @@ public boolean checkCreateMessageValid(final EObject model, final CreateMessage } } if ((element instanceof StateFragment)) { - boolean _equals_4 = ((StateFragment) element).getTimeline().equals(target); + String _timeline = ((StateFragment) element).getTimeline(); + boolean _equals_4 = _timeline.equals(target); if (_equals_4) { return false; } } if ((element instanceof Reference)) { - boolean _contains_1 = ((Reference) element).getTimelines().contains(target); + EList _timelines_1 = ((Reference) element).getTimelines(); + boolean _contains_1 = _timelines_1.contains(target); if (_contains_1) { return false; } @@ -621,7 +679,8 @@ public boolean checkCreateMessageValid(final EObject model, final CreateMessage } public void errorCreateMessage(final String target) { - this.error(String.format((("Target \"" + target) + "\" can not be used in a create message at this point! Other operations were already defined on this timeline.")), + String _format = String.format((("Target \"" + target) + "\" can not be used in a create message at this point! Other operations were already defined on this timeline.")); + this.error(_format, TextualScenarioPackage.Literals.SEQUENCE_MESSAGE_TYPE__TARGET); } @@ -630,32 +689,39 @@ public void errorCreateMessage(final String target) { */ @Check public void checkStateFragment(final StateFragment fragment) { - boolean _contains = TextualScenarioHelper.participantsDefinedBeforeNames(fragment).contains(fragment.getTimeline()); + ArrayList _participantsDefinedBeforeNames = TextualScenarioHelper.participantsDefinedBeforeNames(fragment); + String _timeline = fragment.getTimeline(); + boolean _contains = _participantsDefinedBeforeNames.contains(_timeline); boolean _not = (!_contains); if (_not) { - this.error(String.format("Timeline not defined in text editor!", fragment.getKeyword()), + String _keyword = fragment.getKeyword(); + String _format = String.format("Timeline not defined in text editor!", _keyword); + this.error(_format, TextualScenarioPackage.Literals.STATE_FRAGMENT__TIMELINE); return; } String scenarioType = EmbeddedEditorInstanceHelper.getScenarioType(); if ((fragment.getKeyword().equals(DslConstants.FUNCTION) && scenarioType.equals(DslConstants.FUNCTIONAL))) { - this.error(String.format("\'function\' can not be used in this diagram!"), + String _format_1 = String.format("\'function\' can not be used in this diagram!"); + this.error(_format_1, TextualScenarioPackage.Literals.STATE_FRAGMENT__KEYWORD); return; } - List availableStateFragments = EmbeddedEditorInstanceHelper.getAvailableStateFragments(fragment.getKeyword(), - fragment.getTimeline()); - boolean _contains_1 = availableStateFragments.contains(fragment.getName()); + String _keyword_1 = fragment.getKeyword(); + String _timeline_1 = fragment.getTimeline(); + List availableStateFragments = EmbeddedEditorInstanceHelper.getAvailableStateFragments(_keyword_1, _timeline_1); + String _name = fragment.getName(); + boolean _contains_1 = availableStateFragments.contains(_name); boolean _not_1 = (!_contains_1); if (_not_1) { - String _keyword = fragment.getKeyword(); - String _plus = ("This " + _keyword); + String _keyword_2 = fragment.getKeyword(); + String _plus = ("This " + _keyword_2); String _plus_1 = (_plus + " does not exist or is not available for \""); - String _timeline = fragment.getTimeline(); - String _plus_2 = (_plus_1 + _timeline); + String _timeline_2 = fragment.getTimeline(); + String _plus_2 = (_plus_1 + _timeline_2); String _plus_3 = (_plus_2 + "\"!"); - this.error( - String.format(_plus_3), TextualScenarioPackage.Literals.STATE_FRAGMENT__NAME); + String _format_2 = String.format(_plus_3); + this.error(_format_2, TextualScenarioPackage.Literals.STATE_FRAGMENT__NAME); } } @@ -667,8 +733,8 @@ public void checkWithExecutionHasDeactivateModel(final Model model) { LinkedList messageWithExecutionTargets = CollectionLiterals.newLinkedList(); LinkedList messageWithExecutionTargetsIndex = CollectionLiterals.newLinkedList(); LinkedList messageWithExecutionTargetsContainer = CollectionLiterals.newLinkedList(); - this.checkWithExecutionHasDeactivate(model, messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer, - model.getElements()); + EList _elements = model.getElements(); + this.checkWithExecutionHasDeactivate(model, messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer, _elements); this.showErrorWithExecutionHasDeactivate(messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer); } @@ -677,16 +743,16 @@ public void showErrorWithExecutionHasDeactivate(final LinkedList message { EObject container = messageWithExecutionTargetsContainer.get(i); if ((container instanceof Model)) { + Integer _get = messageWithExecutionTargetsIndex.get(i); this.error( "Deactivation keyword expected for a withExecution message!", container, - TextualScenarioPackage.Literals.MODEL__ELEMENTS, - (messageWithExecutionTargetsIndex.get(i)).intValue()); + TextualScenarioPackage.Literals.MODEL__ELEMENTS, (_get).intValue()); } else { if ((container instanceof Block)) { + String _get_1 = messageWithExecutionTargets.get(i); this.error( "Deactivation keyword expected for a withExecution message!", container, - TextualScenarioPackage.Literals.BLOCK__BLOCK_ELEMENTS, - messageWithExecutionTargets.get(i)); + TextualScenarioPackage.Literals.BLOCK__BLOCK_ELEMENTS, _get_1); } } } @@ -698,29 +764,37 @@ public void checkWithExecutionHasDeactivate(final EObject container, final Linke for (final Element obj : elements) { { if (((obj instanceof SequenceMessage) && (((SequenceMessage) obj).getExecution() != null))) { - messageWithExecutionTargets.add(((SequenceMessage) obj).getTarget()); + String _target = ((SequenceMessage) obj).getTarget(); + messageWithExecutionTargets.add(_target); messageWithExecutionTargetsIndex.add(Integer.valueOf(index)); messageWithExecutionTargetsContainer.add(container); } if (((obj instanceof ArmTimerMessage) && (((ArmTimerMessage) obj).getExecution() != null))) { - messageWithExecutionTargets.add(((ArmTimerMessage) obj).getParticipant()); + String _participant = ((ArmTimerMessage) obj).getParticipant(); + messageWithExecutionTargets.add(_participant); messageWithExecutionTargetsIndex.add(Integer.valueOf(index)); messageWithExecutionTargetsContainer.add(container); } if (((obj instanceof FoundMessage) && (((FoundMessage) obj).getExecution() != null))) { - messageWithExecutionTargets.add(((FoundMessage) obj).getTarget()); + String _target_1 = ((FoundMessage) obj).getTarget(); + messageWithExecutionTargets.add(_target_1); messageWithExecutionTargetsIndex.add(Integer.valueOf(index)); messageWithExecutionTargetsContainer.add(container); } if ((obj instanceof CombinedFragment)) { CombinedFragment cf = ((CombinedFragment) obj); - this.checkWithExecutionHasDeactivate(cf.getBlock(), messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer, - cf.getBlock().getBlockElements()); + Block _block = cf.getBlock(); + Block _block_1 = cf.getBlock(); + EList _blockElements = _block_1.getBlockElements(); + this.checkWithExecutionHasDeactivate(_block, messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer, _blockElements); + EList _operands = cf.getOperands(); final Consumer _function = (Operand operand) -> { - this.checkWithExecutionHasDeactivate(operand.getBlock(), messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer, - operand.getBlock().getBlockElements()); + Block _block_2 = operand.getBlock(); + Block _block_3 = operand.getBlock(); + EList _blockElements_1 = _block_3.getBlockElements(); + this.checkWithExecutionHasDeactivate(_block_2, messageWithExecutionTargets, messageWithExecutionTargetsIndex, messageWithExecutionTargetsContainer, _blockElements_1); }; - cf.getOperands().forEach(_function); + _operands.forEach(_function); } if ((obj instanceof ParticipantDeactivation)) { String targetName = ((ParticipantDeactivation) obj).getName(); @@ -736,28 +810,6 @@ public void checkWithExecutionHasDeactivate(final EObject container, final Linke } } - /** - * Expression shall not be empty - */ - public void checkCombinedFragmentEmptyExpression(final CombinedFragment combinedFragment) { - if (((combinedFragment.getExpression() == null) || combinedFragment.getExpression().isEmpty())) { - this.error( - "Expression can not be empty!", - TextualScenarioPackage.Literals.COMBINED_FRAGMENT__EXPRESSION); - } - } - - /** - * Expression shall not be empty - */ - public void checkOperandEmptyExpression(final Operand operand) { - if (((operand.getExpression() == null) || operand.getExpression().isEmpty())) { - this.error( - "Expression can not be empty!", - TextualScenarioPackage.Literals.OPERAND__EXPRESSION); - } - } - /** * Else keyword shall be put on a combined fragment that is ALT */ @@ -826,14 +878,15 @@ public void checkCombinedFragmentOnValidTimelines(final CombinedFragment combine public void checkContainedCombinedFragment(final CombinedFragment combinedFragment) { EObject container = TextualScenarioHelper.getDirectContainer(combinedFragment); if ((container instanceof CombinedFragment)) { - EObject upperContainer = this.getContainerCombinedFragmentTimelines(combinedFragment.getTimelines(), ((CombinedFragment)container)); + EList _timelines = combinedFragment.getTimelines(); + EObject upperContainer = this.getContainerCombinedFragmentTimelines(_timelines, ((CombinedFragment)container)); if (((upperContainer != null) && (upperContainer instanceof CombinedFragment))) { String _keyword = combinedFragment.getKeyword(); String _plus = ("Timelines covered by this " + _keyword); String _plus_1 = (_plus + " must be a subset of the parent covered timelines "); - EList _timelines = ((CombinedFragment) upperContainer).getTimelines(); - String _plus_2 = (_plus_1 + _timelines); + EList _timelines_1 = ((CombinedFragment) upperContainer).getTimelines(); + String _plus_2 = (_plus_1 + _timelines_1); String _plus_3 = (_plus_2 + "!"); this.error(_plus_3, TextualScenarioPackage.Literals.COMBINED_FRAGMENT__TIMELINES); @@ -873,7 +926,9 @@ public void checkReference(final Reference reference) { index++; } } - boolean _contains = EmbeddedEditorInstanceHelper.getReferencedScenariosName().contains(reference.getName()); + List _referencedScenariosName = EmbeddedEditorInstanceHelper.getReferencedScenariosName(); + String _name = reference.getName(); + boolean _contains = _referencedScenariosName.contains(_name); boolean _not = (!_contains); if (_not) { this.error("Referenced scenario does not exist!", @@ -881,10 +936,11 @@ public void checkReference(final Reference reference) { } EObject container = TextualScenarioHelper.getDirectContainer(reference); if ((container instanceof CombinedFragment)) { - EObject upperContainer = this.getContainerCombinedFragmentTimelines(reference.getTimelines(), ((CombinedFragment)container)); + EList _timelines_2 = reference.getTimelines(); + EObject upperContainer = this.getContainerCombinedFragmentTimelines(_timelines_2, ((CombinedFragment)container)); if (((upperContainer != null) && (upperContainer instanceof CombinedFragment))) { - EList _timelines_2 = ((CombinedFragment) upperContainer).getTimelines(); - String _plus = ("Timelines covered by this reference must be a subset of the parent covered timelines " + _timelines_2); + EList _timelines_3 = ((CombinedFragment) upperContainer).getTimelines(); + String _plus = ("Timelines covered by this reference must be a subset of the parent covered timelines " + _timelines_3); String _plus_1 = (_plus + "!"); this.error(_plus_1, TextualScenarioPackage.Literals.REFERENCE__TIMELINES); @@ -893,8 +949,8 @@ public void checkReference(final Reference reference) { EObject model = TextualScenarioHelper.getModelContainer(reference); if ((model instanceof Model)) { index = 0; - EList _timelines_3 = reference.getTimelines(); - for (final String timeline_2 : _timelines_3) { + EList _timelines_4 = reference.getTimelines(); + for (final String timeline_2 : _timelines_4) { int _plusPlus = index++; this.checkElementAfterDelete(((Model) model), reference, timeline_2, TextualScenarioPackage.Literals.REFERENCE__TIMELINES, _plusPlus); @@ -952,7 +1008,8 @@ public boolean isASublist(final List smallList, final List conta */ public boolean innerCombinedFragment(final List timelines, final CombinedFragment container) { for (final String timeline : timelines) { - boolean _contains = container.getTimelines().contains(timeline); + EList _timelines = container.getTimelines(); + boolean _contains = _timelines.contains(timeline); if (_contains) { return true; } @@ -972,7 +1029,9 @@ public String getElementMapKey(final EObject element) { String _keyword = ((CombinedFragment)element).getKeyword(); String _expression = ((CombinedFragment)element).getExpression(); String key = (_keyword + _expression); - List _sort = IterableExtensions.sort(IterableExtensions.toSet(((CombinedFragment)element).getTimelines())); + EList _timelines = ((CombinedFragment)element).getTimelines(); + Set _set = IterableExtensions.toSet(_timelines); + List _sort = IterableExtensions.sort(_set); for (final String timeline : _sort) { key = ((key + ":") + timeline); } diff --git a/plugins/org.polarsys.capella.scenario.editor.embeddededitor/src/org/polarsys/capella/scenario/editor/embeddededitor/commands/XtextToDiagramCommands.java b/plugins/org.polarsys.capella.scenario.editor.embeddededitor/src/org/polarsys/capella/scenario/editor/embeddededitor/commands/XtextToDiagramCommands.java index 167d6a4d..39e25827 100644 --- a/plugins/org.polarsys.capella.scenario.editor.embeddededitor/src/org/polarsys/capella/scenario/editor/embeddededitor/commands/XtextToDiagramCommands.java +++ b/plugins/org.polarsys.capella.scenario.editor.embeddededitor/src/org/polarsys/capella/scenario/editor/embeddededitor/commands/XtextToDiagramCommands.java @@ -787,6 +787,9 @@ protected static boolean hasExecution(Message elementFromXtext) { if (elementFromXtext instanceof org.polarsys.capella.scenario.editor.dsl.textualScenario.ArmTimerMessage) { return ((org.polarsys.capella.scenario.editor.dsl.textualScenario.ArmTimerMessage) elementFromXtext).getExecution() != null; } + if (elementFromXtext instanceof org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage) { + return ((org.polarsys.capella.scenario.editor.dsl.textualScenario.FoundMessage) elementFromXtext).getExecution() != null; + } return false; } diff --git a/plugins/org.polarsys.capella.scenario.editor/src/org/polarsys/capella/scenario/editor/helper/EmbeddedEditorInstanceHelper.java b/plugins/org.polarsys.capella.scenario.editor/src/org/polarsys/capella/scenario/editor/helper/EmbeddedEditorInstanceHelper.java index fe64442f..12a13325 100644 --- a/plugins/org.polarsys.capella.scenario.editor/src/org/polarsys/capella/scenario/editor/helper/EmbeddedEditorInstanceHelper.java +++ b/plugins/org.polarsys.capella.scenario.editor/src/org/polarsys/capella/scenario/editor/helper/EmbeddedEditorInstanceHelper.java @@ -148,8 +148,11 @@ public static boolean isFSScenario() { } public static AbstractFunction getSourceFunctionOfExchange(FunctionalExchange exchange) { + if(exchange.getSource() instanceof AbstractFunction) { + return (AbstractFunction) exchange.getSource(); + } FunctionOutputPort source = exchange.getSourceFunctionOutputPort(); - if (source != null && source.eContainer() instanceof AbstractFunction) { + if(source != null && source.eContainer() instanceof AbstractFunction) { return (AbstractFunction) source.eContainer(); } return null; @@ -161,6 +164,9 @@ public static String getSourceFunctionNameOfExchange(FunctionalExchange exchange } public static AbstractFunction getTargetFunctionOfExchange(FunctionalExchange exchange) { + if(exchange.getTarget() instanceof AbstractFunction) { + return (AbstractFunction) exchange.getTarget(); + } FunctionInputPort target = exchange.getTargetFunctionInputPort(); if (target != null && target.eContainer() instanceof AbstractFunction) { return (AbstractFunction) target.eContainer();