Associate and Manipulate Data

After you define business types and objects to store your application’s data, you need to manage their use within flow elements.

Work with Expressions

Use expressions to evaluate and perform calculations on data stored in data objects, using standard operators and functions.

Use expressions to change values passed to and from a sequence flow. You can create expressions when configuring data associations and transformations, and when configuring properties for these flow elements:
  • Human tasks: Use an expression to dynamically determine assignees

  • Conditional sequence flows: Use an expression to define its condition

  • Timer catch events: Use an expression to configure its time condition

  • Notification tasks: Use expressions to define dynamic e-mail notification

  • Sub-process tasks: Use an expression to conditionally call a subprocess

To create an expression, click the Expression Editor Expression Editor icon icon or Expressions Mode field during data association or from the flow element’s properties. The Expression Editor dialog box opens.


Description of expression_editor.png follows
Description of the illustration expression_editor.png
  • In most cases, the Expression Mode field is set to Simple, but for some flow elements, Plain Text and XML Literal options are listed. The field below it displays the expression as you configure it.

  • Create an expression by selecting the Data Objects or Operators tab, and selecting data objects and operators for your expression. Click Insert Into Expression to add a selected object or operator, or manually enter them.

  • In the expressions field, enter a . (period) after a data object to view options available for its type (trigger a completion action).

  • Click Validate, and results display in the expression field. The Error tab lists any errors found.

Using Functions

You can include the following functions in expressions, depending on data type. For example, you might use the string function to pass an integer value.

  • String — text

  • int — whole numbers

  • double — decimal numbers

  • Boolean — true or false

  • char — single characters

  • byte — eight bits, the smallest unit of data

  • short — small whole numbers

  • long — large whole numbers

  • float — large decimal numbers

  • Date — dates only

  • Time — times only

  • DateTime — dates and times

Function Guidelines and Examples

  • If the field name is inputDataObject, and the type must be string, enter string(inputDataObject).

  • A field with a data type of int can contain integers only, or whole numbers. A field of type double or float can contain decimal numbers.

  • In data association, if the input type is int, the output type can be any numeric data type, such as int, double, or float. However, if the output type is int, the input type must also be int, or an error occurs. Depending on needs, use the round(), int(), floor(), or ceil() functions.

  • If the field name is loanAppDataObject.form.income, for basic forms, change it to round(loanAppDataObject.form.income) or loanAppDataObject.form.income.round() and for web forms, change it to round(loanAppDataObject.income) or loanAppDataObject.income.round().

About Simple Expressions

Simple expressions are defined using a basic expression language and support. You can use these operators to write expressions and conditions to define your process flow. Generally these expressions perform their calculations based on the data objects in your business process. You can write expressions and conditions using the value of the data objects, but you can’t explicitly modify the value within the data object.

Here are some examples of expressions using operators:

  • totalAmount - discount

  • activationCount > 3

  • unitsSold <= 1200

Operator Precedence

Operator precedence defines the order in which the compiler evaluates operators. You can change operator precedence in an expression by using parentheses. In Process, the operator precedence is:

  • Addition, Subtraction

  • Multiplication, Division, Remainder

  • Plus, Minus

  • Less than, Greater than, Less than or equal to, Greater than or equal to

  • Equals, Not equals

  • Not

  • Conditional And

  • Conditional Or

Arithmetic Operators

Operator Name Description
+ Addition Adds numeric data types; also concatenates strings
- Subtraction Subtracts numeric data types
* Multiplication Multiplies numeric data types
/ Division Divides numeric data types
% Remainder Calculates the remainder of a division in which the divisor doesn't exactly divide the dividend
() Precedence Indicates the order of evaluation of an arithmetic expression

Unary Operators

Operator Name Description
+ Plus Has no effect on the value of the numeric operand. Use it to explicitly indicate that a certain value is positive.
- Minus Negates an arithmetic expression.
! Not Logical complement operator. Negates the value of a Boolean expression.

Equality and Relational Operators

Operator Name Description
= or == Equal to Returns true if the first operand is equal to the second operand
!= Not equal to Returns true if the first operand isn't equal to the second operand
> Greater than Returns true if the first operand is greater than the second operand
>= Greater than or equal to Returns true if the first operand is greater than or equal to the second operand
< Less than Returns true if the first operand is less than the second operand
<= Less than or equal to Returns true if the first operand is less than or equal to the second operand

Conditional Operators

Operator Name Description
and Conditional And Returns true if both operands evaluate to true
or Conditional Or Returns true if either operand evaluates to true

String Operators

Operator Description Usage Expression Usage Result
+ String concatenation “pine” + “apple” “pineapple”
== Equals “apples” == “apples” true
!= Not equals “apples” != “oranges” true
> Greater than “word” > “work” false
>= Greater than or equals “work” >= “work” true
< Less than “word” < “work” true
<= Less than or equals “work” <= “work” true
contains Returns true if the first argument string contains the second argument string; otherwise returns false “caramel”.contains(“ram”) true
endsWith Returns true if the first argument string ends with the second argument string; otherwise returns false “immutable”.endsWith(“table”) true
length Returns the number of characters in a string “house”.length() 5
lowerCase Returns a string with all the characters in the argument converted to lower-case representation “Example”.lowerCase() “example”
startsWith Returns true if the first argument string starts with the second argument string, otherwise returns false “caramel”.startsWith(“car”) true
substring Returns the substring of the first argument starting at the position specified in the second argument and continuing to the end of the string “care”.substring(1) “are”
substring Returns the substring of the first argument starting at the position specified in the second argument with length specified in the third argument “care”.substring(0,3) “car”
upperCase Returns a string with all the characters in the argument converted to upper-case representation “Example”.upperCase() EXAMPLE

Integer Operators

Operator Description Usage Expression Usage Result
+ Addition 2 + 8 10
- Subtraction 7 – 4 3
* Multiplication 3 * 4 12
/ Division 3 / 2 1.5
% Remainder 3 % 2 1
== Equals 12 == 13 false
!= Not equals 12 != 13 true
> Greater than 15 > 16 false
>= Greater than or equals 15 >= 15 true
< Less than 12 < 10 false
<= Less than or equals 12 <= 12 true
abs Returns the absolute value of a number - 6 6

Non-integer Operators

Operator Description Usage Expression Usage Result
floor Returns the largest (closest to positive infinity) number that isn't greater than the argument and is an integer floor(5.60) 5
ceil Returns the smallest (closest to negative infinity) number that isn't less than the argument and is an integer ceil(5.60) 6
round Returns the number that is closest to the argument and is an integer round(5.60) 6

Date and Time Operators

Operator Description
+ Addition (valid only when the second argument is a duration)
- Subtraction (valid only when the second argument is a duration)
== Equals
!= Not equals
> Greater than
>= Greater than or equals
< Less than
<= Less than or equals
format Returns the formatted string of date-time using the provided format picture
year Returns a number representing the year component of the date-time argument
month Returns a number representing the month component of the date-time argument
day Returns a number representing the day component of the date-time argument
hours Returns a number between 0 and 23, both inclusive, representing the hours component of the date-time argument
minutes Returns a number between 0 and 59, both inclusive, representing the minutes component of the date-time argument
seconds Returns a number between 0 and 59, both inclusive, representing the seconds component of the date-time argument
timezone Returns an interval value, representing the time offset from UTC

Boolean Operators

Operator Description Usage Expression Usage Result
== Equals true == true true
!= Not equals true != false true
and Conditional — And true and false false
or Conditional — Or true or false true
not Logical complement operator, inverts the value of a Boolean expression. not true false

Duration Operators

Operator Description
== Equals
!= Not equals
> Greater than
>= Greater than or equals
< Less than
<= Less than or equals

Base64Binary Operators

Operator Description
== Equals
!= Not equals

Array Operators

Operator Description
[ ] Access a particular element into the array
== Equals
!= Not equals
length Returns the number of elements contained within the array

Other Operators

Operator Description
== Equals
!= Not equals

Special Constants

Constants Description
null Null value
true Logical true
false Logical false
‘now’ Current dateTime

Casting

In some cases, it could be desirable to bypass the type validation in order to assign types that aren't necessarily compatible. For example, you may want to assign an 'int' value to a 'string' one and in order to do that you can use the conversion operation like this:

<conversionTypeName> ( <valueToConvert> )

where the 'conversionTypeName' is the type you want to see as the value.

Here are some conversion examples:

  • string(myIntDO)

  • int(myStringDO)

  • duration(mystringDO)

Note:

You can only cast to primitive types, so the 'conversionTypeName' will only accept those that have a valid value.

Assigning two values that are incompatible will result in a runtime error.

Identity Service

Function Description Available Usage Function Prototype Usage Example
getManager Returns a string containing the manager of the specific user Process wide IdentityService.getManager(<userName:string>): string IdentityService.getManager("wfaulkner")
getManager Returns a string containing the manager of a certain user in the realm specified Process wide IdentityService.getManager(<userName: string>,<realm:string>): string IdentityService.getManager("wfaulkner", "myRealm")

Human Task

Function Description Available Usage Function Prototype Usage Example
getPerformer   Assignee Selection HumanTask.getPerformer(): string HumanTask.getPerformer()
getLastPerformer   Assignee Selection HumanTask.getLastPerformer(): string HumanTask.getLastPerformer()

Form

Function Description Available Usage Function Prototype Usage Example
getWebform Returns a base64 encoded value representing the PDF image of the specified webform data object Process wide Form.getWebform(<webFormDataObject:catalogObject>): base64 Form.getWebform(myWebformDO)
getWebform Returns a base64 encoded value representing the image of the specified webform data object in the format passed as the second argument (valid values are "PDF" or "PNG") Process wide Form.getWebform(<webFormDataObject:catalogObject>,<format:string>): base64 Form.getWebform(myWebformDO, "PNG")
getWebform Returns a base64 encoded value representing the image of the specified webform data object having the name determined in the third argument in the format passed as the second argument (valid values are "PDF" or "PNG") Process wide Form.getWebform(<webFormDataObject:catalogObject>,<format:string>,<webFormName:string>): base64 Form.getWebform(myWebformDO, "PNG","MyWebformDO")

Document Service

Function Description Available Usage Function Prototype Usage Example
getDocumentAssetProperty Get some property for a specific document asset, which can be one of the following: Id, Type Process wide DocumentService.getDocumentAssetProperty(<propertyName:string>,<documentAssetName:string>): string DocumentService.getDocumentAssetProperty("Id","myFolder")

Get or Else

Function Description Available Usage Function Prototype Usage Example
boolean Request an object property along with a backup value. The backup value is used if the first argument corresponds to a missing node or an uninitialized value. This function set is useful while dealing with an untrustworthy data source, where initialization isn’t guaranteed. Process wide GetOrElse.boolean(<expression:boolean>,<fallbackValue:boolean>): boolean GetOrElse.boolean(myDO.boolAtt, true)
string Process wide GetOrElse.string(<expression:string>,<fallbackValue:string>): string GetOrElse.string(myDO.stringAtt, "User")
decimal Process wide GetOrElse.decimal(<expression:decimal>,<fallbackValue:decimal>): decimal GetOrElse.decimal(myDO.decimalAtt, 25.9)
byte Process wide GetOrElse.byte(<expression:byte>,<fallbackValue:byte>): byte GetOrElse.byte(myDO.byteAtt, byteVar)
short Process wide GetOrElse.short(<expression:short>,<fallbackValue:short>): short GetOrElse.short(myDO.shortAtt, shortVar)
int Process wide GetOrElse.int(<expression:int>,<fallbackValue:int>): int GetOrElse.int(myDO.intAtt, 12)
long Process wide GetOrElse.long(<expression:long>,<fallbackValue:long>): long GetOrElse.long(myDO.longAtt, 1000)
double Process wide GetOrElse.double(<expression:double>,<fallbackValue:double>): double GetOrElse.double(myDO.doubleAtt, 25.3d)
float Process wide GetOrElse.float(<expression:float>,<fallbackValue:float>): float GetOrElse.float(myDO.floatAtt, floatVar)
binary Process wide GetOrElse.binary(<expression:base64Binary>,<fallbackValue:base64Binary>): base64Binary GetOrElse.binary(myDO.binaryAtt, binaryVar)
integer Process wide GetOrElse.integer(<expression:integer>,<fallbackValue:integer>): integer GetOrElse.integer(myDO.integerAtt, 12)
time Process wide GetOrElse.time(<expression:time>,<fallbackValue:time>): time GetOrElse.time(myDO.timeAtt, '9:20')
date Process wide GetOrElse.date(<expression:date>,<fallbackValue:date>): date GetOrElse.date(myDO.dateAtt, '1988/08/08')
dateTime Process wide GetOrElse.dateTime(<expression:dateTime>,<fallbackValue:dateTime>): dateTime GetOrElse.dateTime(myDO.dateTimeAtt, '1988/08/08 9:20')
duration Process wide GetOrElse.duration(<expression:duration>,<fallbackValue:duration>): duration GetOrElse.duration(myDO.durationAtt, '5s')

Note:

The Get or Else function set is available only for regular data associations within a structured process. It isn’t available either for data transformations or dynamic processes.

Append to Array

An array is a series or list of data elements of the same type. You can add a single data element to an array with the Append action available in the Data mapper.

Append is available in the Data Association editor for both structured and dynamic processes.

Keep in mind the following:
  • The target expression type must be always an array.

  • The source expression type must be of the same data type as the target array.

    The only exception is when the source data type can be assigned to the target array. For example, you can append an integer to an array of type double since you can assign an integer to a double.

  • Both the source and target expressions have to be valid.

Suppose you have a list of colors: blue, green, and black in a form. Now you want to add another color red to the list. Let’s append “red” (string) to the list of colors (string of type array) in design time, validate and test the application, and finally check if the append action is successful in runtime.

  1. In design time, open the Data Association editor. Expand Data Object in the right pane and then expand colorContainer.
  2. Drag and drop colors (array) to the target field in the Data Association editor.
  3. Enter “red” in the source field.

    Notice that the association icon turns red and you get an error message.

    Description of append-array-1.png follows
    Description of the illustration append-array-1.png

  4. Click the association icon. A drop-down menu appears.
  5. Click Append.

    The association icon turns green indicating that the append action was successful.

    Description of append-array-3.png follows
    Description of the illustration append-array-3.png

  6. Click Apply.
  7. Test activate and try the application in test mode.
  8. In runtime, open, complete, and submit the start task.

    You get a message that an instance has been created.

  9. Click My Tasks and open the task that has the color list.

    Notice that red has been added to the list of colors in the form.

    Description of append-array-4.png follows
    Description of the illustration append-array-4.png

You have successfully appended a string to an array in this example.

Filter Array Data Objects

While defining data associations between process components, you can selectively filter elements from a source array object and assign them to a target array.

In the Data Association editor of a structured process, a dynamic process, or a transformation, an option to define a filter appears if the following conditions are met:
  • The target expression type is an array.
  • The source expression type is an array. The base type of the source is assignable to the base type of the target (for example, integer to double assignments).
  • Both the source and target expressions are valid.

To define a new filter:

  1. Click the Data Association icon and select Filter.

    Description of filter-action.png follows
    Description of the illustration filter-action.png

  2. Select the Create action in the resulting window and provide a suitable name for the filter, for example, MyStringFilter, and click Create again. A window to define the filter condition appears.

    Note:

    If a suitable filter already exists, you can select or edit it from the Create Filter window.
  3. Based on the type of your array, define a filter condition using the available operators. For a simple array object (of the type integer, string, or double), an element named VALUE is present in the window, which represents each element of the source array.
    1. Drag and drop the VALUE element into the Condition field to define an expression. If needed, click the fx (Expression) icon and use the Expression editor. The following figure shows a filter condition defined for a string array:

      Description of filter-condition.png follows
      Description of the illustration filter-condition.png

      In this case, only the elements of the source array of length 5 are assigned to the target array.

    2. For a complex array object, you can define a condition comprising all attributes it contains:

      Description of filter-condition-complex.png follows
      Description of the illustration filter-condition-complex.png

      Note:

      Currently, while defining a filter condition for a complex array object, you must type in each array element and its associated condition into the Condition field. Drag and drop functionality is supported only for a single object or element.
  4. Save the filter condition.
  5. To view or edit any filter defined within the process, click Actions in the Data Association editor.
  6. Finally, click Apply to save all data associations and filters.

    In runtime, target arrays are populated according to the filter conditions you’ve defined.

Define Conditions for Data Associations

There may be a business scenario where you want a data association to execute in runtime only when a particular condition fulfills. Control the execution of data associations in runtime by adding conditions to them in the Data Association editor.

A data association that has been configured with conditional mapping executes in runtime only when the defined condition fulfills. Otherwise, it fails to execute. All other data associations that do not have conditional mapping defined execute normally in runtime.

Note that you can set conditions for data mapping in both structured and dynamic processes.

To define a new condition:

  1. Click the Data Association icon in the data association for which you want to configure a condition. You can define the new condition in the resulting dialog box.
  2. Define the new condition by typing directly in the Add field. For example, form.Arg.cost>5000.
  3. Optionally, click the Expression Editor icon to use the Expression Editor to define a condition using standard functions and operators.
  4. If the condition is valid a green icon Valid Data Association is displayed next to the Data Association icon.
  5. If the configured condition is invalid, the icon turns red Invalid Data Condition. To know more about the error, click the Data Association icon. An error message with details about the error is displayed below the condition field.
  6. Finally, click Apply to save all data associations including the data associations with conditions set on them.
In runtime, the data associations for which you have defined conditions execute only if the conditions fulfill. In case of our example, the payload from the Cost field in the process Start activity passes on to the next activity of the process, only if its value is more than 5000.