edoras one - User Guide

Version 1.1.0.S44


Table of Contents

1. Form binding expressions
1.1. Simple variable bindings
1.2. Bindings to other work objects
1.3. Common bindings
2. Process model expressions
2.1. Accessing work object data
2.2. Work object ID conversion
2.3. User properties
2.4. Resolving hierarchy variables
2.5. Bean resolution
2.5.1. Process variable handling service
2.6. Process expression usage
2.6.1. Task name and description
2.6.2. Service task expression
2.6.3. Conditional sequence flows

List of Tables

1.1. Standard form bindings
2.1. Work object user expressions
2.2. User properties

Chapter 1. Form binding expressions

Forms are used to display and edit the data of underlying work objects. The work object data and the form definition are fetched from the server, and the expressions used within the form definition are then used to link the form fields with corresponding data. For editable fields, any changes made are reflected in the underlying work object data, which is sent back to the server to be persisted when the form is submitted:

Form data binding expressions are placed between two sets of curly braces, e.g.{{expression}}, and are set into a form component's Value property:

Tip:

The Value property of a form component may only be bound to a single expression, and this may not be preceded or followed by other text.

The only exception to this rule is the output component, which doesn't display and edit a single value, but uses form expressions embedded within a rich text template to create textual output dynamically.

1.1. Simple variable bindings

A simple value name in double curly braces (e.g.{{value}}) is used to link to the corresponding variable in the current work object. If the work object variable doesn't exist when the form is opened then it will be created automatically.

1.2. Bindings to other work objects

A work object in edoras one is typically part of a hierarchy, where work objects are linked together in a tree of parent/child relationships. For example a case typically serves as a container for other work objects (tasks, running processes, documents etc.). Form binding expressions can also be used to access the values from related work objects in the work object hierarchy. This is done be preceding the variable to be accessed by a qualifier:

{{parent.value}}

binds to the corresponding value in the current work object's parent.

{{root.value}}

binds to the corresponding value in the work object that is at the root of the current work object's hierarchy. The root is determined by following the parent references until a work object is found that has no parent.

As an example, if we start a process within a case then the process's parent work object will be the case. A form task created by that process will have the process work object as its parent:

In this case {{root.name}} will bind to"Example case", {{parent.name}} will bind to "Example process" and {{name}} will bind to"Example task".

1.3. Common bindings

Bindings can be created for new variables as required, but a number of predefined bindings are used to access common work object attributes:

Table 1.1. Standard form bindings

BindingEditableForm ComponentBinds to
{{name}} YesTextthe work object's name
{{description}} YesTextthe work object's description
{{state}} NoTextthe work object's state
{{type}} NoTextthe work object's type
{{ownerId}} YesUser selectionthe work object's owner
{{assigneeId}} YesUser selectionthe work object's assignee
{{candidateGroupIds}} YesShare with groups selectionthe work object's candidate groups
{{creationTime}} NoDatethe work object's creation time
{{updateTime}} NoDatethe work object's last update time
{{dueTime}} YesDatethe work object's last due time
{{resubmissionTime}} YesDatethe work object's last resubmission time

Chapter 2. Process model expressions

Expressions can also be used within the process models to access data from the work object hierarchy and interact with other system components. In contrast to the form binding expressions, process model expressions can be more complex and have side-effects within the system (for example causing an e-mail to be sent). Whereas form expressions serve simply to link a particular data item with a form component (which then takes over the responsibility of interacting with the data), process expressions allow data object hierarchies to be traversed and method calls to be made.

Tip:

The full expression language is part of the EE6 specification and only an brief overview will be provided here. For a full description of the expression language syntax please refer to the EE6 specification.

There are two basic expression types:

  • value expressions have the form #{value.property} and resolve to a value

  • method expressions have the form #{bean.method(value)} and result in a method invocation

One other difference between the form bindings and process expressions is that the work objects used by a form binding may have been pre-processed by the server so that the property values are in a form that makes more sense in the client's context. With process expressions this processing is not performed so you will be working with raw work objects.

As an example, state is represented in a work object by an instance of the State class. In a form binding, the {{state}} expression will be bound to the name field of this object (e.g."ACTIVE"). The conversion from State instance to the state name string has already been performed by the server. The corresponding process binding, #{state} resolves to the underlying State object, which if it is used in a string context will be converted to a string literal, e.g. [State@51d838d9 name = 'ACTIVE']. To access the plain string value ("ACTIVE") we can use the java bean property convention to get the name: #{state.name}.

2.1. Accessing work object data

The same binding values that are used in forms (seeTable 1.1, “Standard form bindings”) can also be used in process model expressions, although in some cases the expression results will have a different type than the corresponding form binding (see the state example above for an explanation).

The parent and root qualifiers are supported by process expressions, and there is also a self qualifier that refers to the current work object. self is the default qualifier, and so it's rarely needed.

2.2. Work object ID conversion

Work objects are referenced using IDs, and is often necessary to access not the ID itself but the referenced work object. To support this use case, an expression that resolves to a work object ID will automatically be converted to the corresponding work object instance if is followed by another expression. For example the expression #{ownerId.name} will extract the owner ID value, look up the corresponding work object (the user definition) and then access the name property of that work object.

As access to the user data for a work object is so common there are also some shortcut expressions to access this information directly:

Table 2.1. Work object user expressions

ExpressionReturn typeDescription
owner User work objectthe work object's owner (corresponding toownerId.value)
assignee User work objectthe work object's assignee (corresponding toassigneeId.value)

2.3. User properties

The previous section showed how we can gain access to the user information relating to a work object. Once we have accessed the user work object there are a number of useful user properties that can be accessed (e.g. as#{owner.name}:

Table 2.2. User properties

PropertyReturn typeDescription
userLogin Stringthe user's login name (email address)
name Stringthe user's display name
userFirstName Stringthe user's first name
userName Stringthe user's surname
userAddress Stringthe user's address
userPhone Stringthe user's telephone number
userMobile Stringthe user's mobile telephone number
language Stringthe user's language

2.4. Resolving hierarchy variables

Another difference between form binding expressions and process binding expressions is the visibility of work object variables within the work object hierarchy. With form binding expressions, accessing parent or root variables requires explicit use of the appropriate parent or root qualifier. With process expressions, however, this is not always required. With a process expression, variables from parent work objects in the hierarchy are also visible in the child work object. If a parent and child both have variables with the same name then the child variable will be resolved.

For example, take the following work object hierarchy:

If we are resolving variables in the task context, then the expression #{root.message} will resolve to "Case message" as root refers to the case. The expression #{parent.message} will also resolve to "Case message" as parent refers to the process and this work object will inherit the message value from its parent (the case). The expression #{message} will resolve to "Task message" however, as the inherited variable from the case has been hidden by a more local value.

2.5. Bean resolution

As mentioned earlier, process expressions can also be used to invoke methods and access properties of java beans. For security reasons it is obviously not a good idea to allow access to all beans within the server, and so edoras one defines a bean white-list containing the bean names that may be accessed. Exactly which beans are available will depend on the edoras one installation, but the following sections describe standard service beans that may be supported.

2.5.1. Process variable handling service

The process variable handling service allows process variables to be manipulated using a process service task. The following methods are provided:

#{processVariables.initVariables(execution, "variableName", "variableValue")}

initializes variables if they have not yet been set on the process scope. Variable names and values may also be provided by expressions (e.g.#{processVariables.initVariables(execution, "var", owner.name)}), and multiple variable name/value pairs may also be set in one call (e.g. #{processVariables.initVariables(execution, "var1", "a", "var2", "b")}).

#{processVariables.setVariables(execution, "variableName", "variableValue")}

follows the same syntax as processVariables.initVariables() but will overwrite the variable values if the variable already exists.

Tip:

The modeler provides predefined task definitions for a number of common operations, including initializing variables. It will usually be easier and more reliable to use these templates instead of directly using expressions to achieve the same results.

2.6. Process expression usage

Process expressions can be used in a number of different places within a process description. The following sections describe the details of each possible usage.

2.6.1. Task name and description

Expressions may be embedded within a task name to automatically create task names that are based on the context:

When the task is created, the expressions embedded in the task name will be replaced by the evaluation results.

2.6.2. Service task expression

A service task contains an Expression property which will evaluated when the service task is created. This will typically be used to invoke a bean method that performs the required action:

2.6.3. Conditional sequence flows

Sequence flows can be controlled by adding a condition expression to the sequence flow transition:

The expression should resolve to a boolean expression using the boolean operators from the EE6 specification. The sequence flow will be taken when the expression resolves totrue.