# Specifying Model Operations

## Introduction

Most modelers created with Sirius are not just used to view models, but also to edit them. The edition behavior is specified through different kinds of tools (e.g. Direct Edit, Creation Tool, etc.) which depend on the dialect. The behavior of each tool of each dialect is specified inside the VSM using a small Domain Specific Language of model operations. This document describes all the model operations supported by this language. Unless otherwise specified, model operations can be used/composed for any tool of any dialect.

## Flow Control Operations

### Begin

This element has no property. It only serves as an entry point to the specification of a tool’s behavior. Note that a Begin element can only contain a single operation. It is recommended to begin a tool’s specification by creating a no-op Change Context operation directly inside the Begin, as a Change Context can contain multiple operations.

### Change Context

Every model operation is executed in the context of a specific model element (the equivalent of `this` or `self` in a programming language). Usually, at the beginning of a tool, the context is the semantic element to which the tool is applied (the actual details can vary from tool to tool, refer to their documentation). The Change Context operation changes the context to a new element and then executes any sub-operations it contains in sequence (in the order of definition).

The new context element to go to is specified by the Browse Expression property of the Change Context operation. It is executed in the context element of the Change Context operation itself, and should return another model element (which will become the context for the sub-operations). If the expression does not return any element, it is not an error, but the sub-operations are not executed. If the expression returns several elements, only the first one is retained and used as the context for the sub-operations.

Tip: Using a no-op Change Context (with a browse expression like `aql:self` which does not actually change the context) can be useful to group multiple operations into a single “block”, especially in contexts where only one model operation is supported (e.g. inside a Begin element).

### If

The If operation is used for condition execution. It first evaluates its Condition Expression in the current context, and if the result of this expression (interpreted as a boolean) is true then it executes any sub-operations it contains in sequence (in the order of definition). If the expression returns a false value, If does nothing.

Note: “else” and “else if” constructs are not supported directly, but the same effect can be achieved using the Switch operation with the appropriate Cases.

### Switch/Case

A Switch operation is used for branching. It is a generalization of the If constructs which supports multiple conditions. The Switch operation itself has not property; it serves only as a container for one or more Case elements, and an optional Default element. Each Case element has a Condition Expression, and may contain sub-operations. The Default element has no property but may contain sub-operations.

When a Switch is executed, the Condition Expressions or each of its Case elements is evaluated (in the current context) until one returns a true value. If one is found, the sub-operations of the Case element are executed in sequence, and the rest of the Switch is ignored (the remaining conditions, if any, are not tested). If none of the Cases has an expression which returns true, then the sub-operations of the Default element, if any, are executed in sequence.

A combination of Switch/Case/Default is equivalent to `if (...) { ... } elsif (...) { ... } else { ... }` in a programming language.

### For

The For element is used to loop over collections of model elements and execute some operations on all of them. The Expression of the For element is executed in the current context, and should return a collection of model elements. The Iterator name property is a fixed string ( `i` by default) which give the name of the variable used for the iteration.

After evaluating the Expression, each of the element in the returned collection will be bound in turn to a variable named as specified in Iterator name before the sub-operations of the For element are executed in sequence (once for each of the returned element). Inside the sub-operations, you can access the current element of the iteration using the variable named in Iterator name. The actual syntax will vary depending on the query language you use.

### Let

The Let operation is used in order to create a new variable which can be used by child model operations. The Variable name is a fixed string used to access the variable in child model operation. The Value expression is executed in order to set the value of the variable. The Let operation is similar to a For operation with an expression returning only one element for the iteration. If the Variable name is “self”, the behavior of the Let will be the same as the behavior of a Change Context. It is not recommended to use a Let with the Variable name “self”, prefer the Change Context for a better readability of your odesign.

## Model Change Operations

### Create Instance

The Create Instance operation is used to create new semantic elements to be added into the user’s model. You must specify :

1. the Type Name (using the same syntax as for Domain Class properties) of the new object to create
2. the Reference Name through which the created element will be attached to the current context.

When the Create Instance operation is executed, say in the context of semantic element S, a new instance of the specified type name is created and then added to S's reference named in Reference Name. The reference name must correspond to a valid containment reference for the context element of the operation, otherwise the newly created object will not be properly integrated into the semantic model.

The Variable Name property can be set to any valid variable name ( `instance` by default). The named variable is assigned with the newly created object, so that it can be accessed from the remaining operations in the tool.

Inside the Create Instance element you can add sub-operations, which will be executed in sequence in the context of the newly created element. This is useful to correctly initialize the new object’s properties.

### Set

The Set operation is used to set the value of a feature (attribute or reference) of the current element. When executed, it evaluates the Value Expression in the current context element. The expression’s result is then set as the new value of the feature named in Feature Name of the current context element. The value returned by the expression must be type-compatible with the named feature.

Inside the Set element you can add sub-operations, which will be executed in sequence in the same context.

### Unset

The Unset operation is used to remove elements from a feature (attribute or reference) of the current element. When executed, it evaluates the Element Expression in the current context element, which may return one or more elements. Each of the returned elements are then removed from the feature named in Feature Name of the current context element. It is not an error if some of the returned elements are not actually part of the specified feature, they are simply ignored.

Inside the Unset element you can add sub-operations, which will be executed in sequence in the same context.

### Remove

The Remove operation is used to remove the current element from its parent element. It takes no parameter. When executed, it simply removes the element from its containing feature.

### Move

The Move operation is used to move the current element from its current parent into a new one. The New Container Expression is evaluated in the current context and should return the (single) element in which to move. The Feature Name indicates the containment feature of the new parent in which to add the current element.

## Representations Operations

### Create View

This operation is specific to diagrams. It can be used to explicitly create a view (graphical representation) of the current element, which is mostly useful when using unsynchronized diagrams and/or mappings.

The Container View Expression is evaluated in the context of the current semantic element, and should return the view ( `DDiagram`, `DNode` or `DNodeContainer`) in which the new view should appear. The Mapping indicates the kind of view to create. If the container view expression returns an element which can contain a view for the current semantic element and specified mapping (and does not already contain one), the view will be created, even if the diagram and/or mapping is not synchronized.

Note that because the Container View Expression is evaluated in the context of a semantic element and must return a view, you must use the cross-referencer to navigate from the semantic model to the view model. Using the Acceleo 3 language you can use the `eInverse()` service to find which elements point to the current one and then select only those which do it through a reference named `target` (the views in Sirius diagrams reference their target semantic element through this reference).

The Variable Name property can be set to any valid variable name ( `createdView` by default). The named variable is assigned with the newly created view, so that it can be accessed from the remaining operations in the tool.

### Create Edge View

This operation is specific to diagrams. It can be used to explicitly create an edge view (graphical representation) of the current element, which is mostly useful when using unsynchronized diagrams and/or mappings.

It works similarly to the Create View operation, except that in addition to the Container View Expression, you must also provide a Source Expression and a Target Expression, which should return the semantic elements between which the edge should be created, if source and target views are found regarding the selected edge mapping properties.

### Delete View

This operation is specific to diagrams. It can be used to explicitly remove a view (graphical representation) from the diagram, without deleting the corresponding semantic element. It is mostly useful when using unsynchronized diagrams and/or mappings.

It has no parameter and works similarly to the Remove operation; you must already be in the context of the view element you want to delete.

### Navigation

This operation is specific to diagrams. It can be used to navigate to another diagram representing the current element. The Diagram Description indicates the type of diagram to open, and the Create if not existent flag indicates whether a new diagram of the specified type should be created on the current element if none exists.

The operation does nothing if the current element is not compatible with the specified diagram type or if there is no existing diagram and the Create if not existent flag is not set.

## Dialog & Wizard

Warning: The model operations below are provided by the Sirius properties view plugins. To make sure those operations will be available to the end user, you should add the following plugins in your modeler dependencies:

- org.eclipse.sirius.properties
- org.eclipse.sirius.ui.properties

If those plugins are missing at runtime, Open Dialog and Open Wizard operations will not be executable.

### Open Dialog

The Open Dialog model operation is used in order to open a new dialog where the end user will be able to see and manipulate some pieces of information. You can change the title of the dialog with the Title expression. This expression must return a string. You can specify one Page with various Groups to specify the content of the dialog. You can leverage existing Pages and Groups from existing definition of your Properties View.

A dialog can contain multiple buttons. If you do not specify any button, two will be created by default. The first one, with the label “Cancel”, will close the dialog and rollback any changes made during the execution of the model operation chain. The second one, with the label “OK”, will close the dialog and execute the child model operations of the dialog.

You can create Dialog Buttons in a dialog in order to specify the behavior of the buttons. If at least one Dialog Button is specified, the default behavior previously described will not be used anymore. For each Dialog Button description, a button will be added in the user interface of the dialog. The label of the button can be specified with the Label expression which must return a string. The Is Enabled expression is used to determine if the button must be activated or not. This can be used to prevent the end user from finishing an action. This expression must return a boolean. An Initial Operation is available on a Dialog Button in order to specify the behavior to execute when the user will click on the button.

The specifier can indicate that a Dialog Button should be considered by default with the default boolean. When a Dialog Button should be used by default, it is focused by default when the dialog is opened. A Dialog Button can also close the dialog by using the property Close Dialog On Click. By specifying false as the value for Close Dialog On Click and by using an Initial Operation on the button, a specifier can easily create a button to restore a default value. Finally, a boolean is available in order to Rollback Changes On Close. By setting this value to true, when the button will be pressed, it will have the same behavior as a regular cancel button by rollbacking the whole model operation chain.

### Open Wizard

The Open Wizard model operation is used in order to open a new wizard to let the end user specify some information using multiple Pages. You can configure the title of the window by returning a string with the Window Title expression. You can also configure the title and description of the wizard with the Title and Description expressions. Both expressions should also return a string. You can prevent the end user from finishing early the wizard and from switching to another page by returning false for the Is Page Complete expression. A wizard can be closed only if all Pages are completed.

The wizard can also contain various Pages and Groups using the Properties View domain specific langage available in Sirius. You can leverage existing Pages and Groups from existing definition of your Properties View. A wizard can also contain an Initial Operation used to define the child model operations to execute when the user will finish the wizard.

## Java Extensions

Beyond the operations which are described above, you can also execute arbitrary Java code in the context of a tool by providing an External Java Action and invoking it with the corresponding operation.

### External Java Action

When used as a model operation (instead of as a full-blown tool), you only have to specify the Java Action Id. It should correspond to an extension of the `org.eclipse.sirius.externalJavaAction` extension point which registers a class implementing `org.eclipse.sirius.tools.api.ui.IExternalJavaAction` to be executed. You may also create External Java Action Parameter elements inside the External Java Action element. Each one has a fixed Key and a computed Value, which will be evaluated before the operation is executed and made available to the Java class through the `parameters` argument of the `execute()` method.

As the External Java Action uses the Eclipse extension point mechanism, it means you cannot use it in development mode (when the Viewpoint Specification Model you are working on is in the workspace).

### External Java Action Call

External Java Action Call is simply a convenience operation to invoke an External Java Action defined elsewhere in the VSM, with potentially different parameters.

### Standard Java Actions

The following External Java Actions are available in standard and can be used in Viewpoint Specification Models . Note that if you want to create your own actions, you can implement `org.eclipse.sirius.tools.api.ui.IExternalJavaAction` directly or inherit from `org.eclipse.sirius.business.api.action.AbstractExternalJavaAction` which provides some helper methods.

#### org.eclipse.sirius.business.api.action.moveElement

This external Java action can be used to move an element to a different position inside a many-valued EReference.

Action parameters:

- `referenceOwner` (an EObject): the owner of the EReference to edit.
- `referenceName` (a string): the name of the EReference of the owner object to edit. This must be a many-valued, changeable reference.
- `element` (an EObject): the element to move inside the list. It is an error if the specified element is not in the list.
- `predecessor`: the element of the list right before which element must be moved, i.e. after the operation, predecessor will be the direct predecessor of element in the list. May be null to indicate that element should be moved at the front of the list. If not null, it is an error if predecessor is not in the list.

#### org.eclipse.sirius.business.api.action.printVariables

This external Java action is designed to help debugging Viewpoint Specification Models by printing (in standard output)
all the variables accessible to model operations at the invocation point.

Action parameters:

- `title`: an optional string header to print before the list of variables, for example to distinguish different uses of this action in the same VSM.
- `enabled`: an optional boolean (defaults to true) to indicate if the action should be executed or not. This is useful to quickly enable/disable an action with minimal editing of the VSM.

#### org.eclipse.sirius.ui.business.api.action.openHelpSection

This external Java action can be used to open the Eclipse Help system (or actually any web page) on a specific section from inside a tool (typically a popup menu).

Action parameters:

- `href`: the URL of the help resource. To open an Eclipse Help section, use an URI of the form `/com.example.pluginName/path/to/document.html#sectionId`