10.1 About the ECMA Expression Builder

Designer incorporates an ECMAScript interpreter and expression editor, which allows you create script expressions that refer to and modify workflow data. For example, you can use scripting to:

This section describes some of the techniques and capabilities applicable to the use of scripting.

NOTE:To define expressions for a workflow, you need to understand how workflow activities are configured. In addition, you need to understand the various types of data that are available within a workflow. For details on configuring workflow activities, see Section 8.0, Workflow Activity Reference. For descriptions of the system variables available in a workflow, see Section 4.3.3, Understanding Workflow Data.

10.1.1 About ECMAScript

ECMAScript is an object-oriented scripting language for manipulating objects in a host environment (in this case, Designer). ECMAScript (ECMA-262 and ISO/IEC 16262) is the standards-based scripting language underpinning both JavaScript (Netscape*) and JScript* (Microsoft*). It is designed to complement and extend existing functionality in a host environment such as Designer’s graphical user interface. As a host environment, Designer provides ECMAScript access to various objects for processing. ECMAScript in turn provides a Java-like language that can operate on those objects.

The extensibility of ECMAScript, and its powerful string-handling tools (including regular expressions), make it an ideal language to extend the functionality of Designer.

NOTE:You can find detailed information about ECMAScript at the European Computer Manufacturers Association (ECMA) Web site.

10.1.2 ECMAScript Capabilities

In addition to enabling you to incorporate finely-tuned custom logic into your workflow, scripting gives you a great deal of flexibility in manipulating data because of the various DOM- and XPath-related objects and methods available in the ECMAScript extensions incorporated into the Expression Builder.

The usefulness of ECMAScript is especially apparent when dealing with in-memory DOMs. The ECMA expression builder constructs XML documents as in-memory objects according to the W3C DOM Level 2 specification. The DOM-2 specification, in turn, defines an ECMAScript binding (see the W3C Recommendation ECMAScript Language Binding, with numerous methods and properties that provide ready access to DOM-tree contents. The flowdata DOM is recognized by the ECMA expression builder, and any of the W3C-defined ECMAScript extensions that apply to DOMs can be used.

ECMAScript also provides bridges to other expression languages such as XPath. This allows you to use XPath syntax on a DOM to address various elements within its document structure.

10.1.3 Using the ECMA Expression Builder

Designer provides access to ECMAScript in various places in the User Application design tools. The most common form of access is through the expression builder, which can be displayed whenever you see this button:

The button can be found in Designer displays, such as the Properties for a Condition activity or the Data Item Mapping view for an Entitlement Provisioning activity. Click the button to display the ECMA expression builder.

Figure 10-1 ECMA Expression Builder

The ECMA expression builder provides pick lists of available objects, methods, and properties in the top panes (all of which are resizable), with rollover tool tips to help you build ECMAScript statements. Double-clicking any item in any pick list causes a corresponding ECMAScript statement to appear in the edit pane in the lower portion of the window. In the figure, the process pick list has been selected in the ECMAScript Variables pane, and the name variable has been double-clicked. The ECMAScript expression that can access the contents of this workflow variable is inserted automatically in the edit pane.

This section includes the following topics:

Checking Syntax

The ECMA expression builder includes a Check Syntax button. Clicking the button causes the ECMAScript interpreter to check the syntax of the expression. If there are problems involving ECMAScript syntax, an error message is displayed. You can then edit the expression and validate again as needed. Validation is optional.

NOTE:The syntax checking process does not execute your expression. It just checks syntax. Because ECMAScript is an interpreted language, syntax checking doesn’t check any runtime-dependent expressions, other than to see if they conform to valid ECMAScript syntax.

Selecting a DN

The ECMA expression builder also includes an Identity Vault button that is displayed when you are working with activities that might require selecting a DN from the Identity Vault (for example, Start, Approval, and Entitlement activities).

Figure 10-2 Identity Vault Button

The Identity Vault button displays a dialog box that you use to navigate the Identity Vault to select a DN. The Identity Vault button is dimmed (to indicate that it is unavailable) if you are not connected to the Identity Vault.

ECMAScript Variables

This pane displays the names of variables that are relevant in the current context. For example, if you are working in the provisioning request definition editor, you see system variables for the current workflow process, system variables for the current activity, and flowdata variables created in the current workflow. Double-click the name of a variable to insert that variable into your script. For descriptions of the system variables available in a workflow, see Section 4.3.3, Understanding Workflow Data.

The ECMA expression builder provides two methods for reading flowdata variables.

Table 10-1 Methods for Reading Flowdata Variables

Method

Description

flowdata.get(variable-name)

Returns a string as the node value for a variable (representing an XPath expression) in the workflow document.

flowdata.getObject(variable-name)

Returns an object as a node value for a variable (representing an XPath expression) in the workflow document. Use this method to retrieve the values of multivalued controls.

Functions/Methods

For a description of the functions and methods available in the ECMA expression builder, see Section 10.3, ECMAScript API.

ECMAScript Operators

The following tables provide descriptions of the operators supported by the ECMA expression builder.

Table 10-2 Math

Operator

Description

+ Add

Returns the sum of two numerical values (either literals or variables).

- Subtract

Subtracts one number from another.

* Multiply

Returns the product of two numerical values (either literals or variables).

/ Divide

Divides one number by another.

Table 10-3 Assignment

Operator

Description

= Assignment

Assigns the value of the right operand to the left operand.

+= Add to this

Adds the left and right operands and assigns the result to the left operand. For example, a += b is the same as a = a + b.

-= Subtract from this

Subtracts the right operand from the left operand and assigns the result to the left operand. For example, a -= b is the same as a = a - b.

*= Multiply to this

Multiplies the two operands and assigns the result to the left operand. For example, a *= b is the same as a = a * b.

/= Divide this to

Divides the left operand by the right operand and assigns the result to the left operand. For example, a /= b is the same as a = a / b.

%= Modulus

Divides the left operand by the right operand and assigns the remainder to the left operand. For example, a %= b is the same as a = a % b.

&= Apply bitwise AND to this

Performs bitwise AND on operands and assigns the result to the left operand. For example, a &= b is the same as a = a & b.

|= Apply bitwise OR to this

Performs bitwise OR on operands and assigns the result to the left operand. For example, a |= b is the same as a = a | b.

<<= Apply bitwise left shift to this

Performs bitwise left shift on operands and assigns the result to the left operand. For example, a <<= b is the same as a = a << b.

>>= Apply bitwise signed right shift to this

Performs bitwise right shift on operands and assigns the result to the left operand. For example, a >>= b is the same as a = a >> b.

>>>= Apply bitwise unsigned right shift to this

Performs bitwise unsigned right shift on operands and assigns the result to the left operand. For example, a >>>= b is the same as a = a> >> b.

Table 10-4 Other

Operator

Description

% Modulus

Divides the left operand by the right operand and returns the integer remainder.

++ Autoincrement

Increments the operand by one (can be used before or after the operand).

-- Autodecrement

Decrements the operand by one (can be used before or after the operand).

~ Bitwise NOT

Inverts the bits of its operand.

& Bitwise AND

Returns a 1 in each bit position for which the corresponding bits of both operands are ones.

| Bitwise OR

Returns a 1 in each bit position for which the corresponding bits of either or both operands are ones.

^ Bitwise XOR

Returns a 1 in each bit position for which the corresponding bits of either but not both operands are ones.

<< Bitwise left shift

Shifts the digits of the binary representation of the first operand to the left by the number of places specified by the second operand. The spaces created to the right are filled in by zeros, and any digits shifted to the left are discarded.

>> Signed bitwise right shift

Shifts the digits of the binary representation of the first operand to the right by the number of places specified by the second operand, discarding any digits shifted to the right. The copies of the leftmost bit are added on from the left, preserving the sign of the number.

>>> Unsigned bitwise right shift

Shifts the binary representation of the first operand to the right by the number of places specified by the second operand. Bits shifted to the right are discarded and zeroes are added to the left.

Table 10-5 Relational

Operator

Description

== Equal

Assigns the value of the right operand to the left operand.

!= Not Equal

Returns a Boolean True if the operands are not equal.

< Less than

Returns True if the left operand is less than the right operand.

> Greater than

Returns True if the left operand is greater than the right operand.

<= Less than or equal

Returns True if the left operand is less than or equal to the right operand.

>= Greater than or equal

Returns True if the left operand is greater than or equal to the right operand.

Table 10-6 Logical

Operator

Description

&& AND

Returns a Boolean true if both operands are true; otherwise, returns False.

|| OR

Returns True if either operand is true. Returns false when both operands are False.

! NOT

Returns False if its single operand can be converted to true (or if it is a non-Boolean value). Returns True if its operand can be converted to False.

Table 10-7 String

Operator

Description

+ Concatenate

Concatenates two string operands, returning a string that is the union of the two operand strings.

VDX Expr

This pane allows you to insert Entity definitions (see Section 3.2, Working with Entities and Attributes) that are defined in the Identity Vault into your scripts. Both system and user-defined entities are available. The format of an expression to retrieve data from the Identity Vault is

IDVault.get(dn, object-type, attribute)

For example if you want the recipient's manager for a data item, you would open the User node in the VDX Expr Panel and double-click the Manager item, which inserts IDVault.get({ enter dn expression here }, 'user', 'manager'). This expression evaluates to the string for the manager’s DN (LDAP distinguished name).

Using Special Characters

You can use special characters in literal strings in the ECMA expression builder by using escape sequences. Escape sequences begin with a backslash character ( \ ). The following table contains some commonly used escape sequences:

Table 10-8 Escape Sequences

Escape Sequence

Character

\b

Backspace

\f

Form feed

\n

New line

\r

Carriage return

\t

Horizontal tab

\”

Double quote

\\

Backslash (\)

\’

Apostrophe

You also can specify any Unicode character by using \u followed immediately by four hexadecimal digits. Here are some examples:

Table 10-9 Escape Sequence Examples for Unicode Characters

Escape Sequence

Character

\u00A3

Pound symbol (£)

\u20AC

Euro symbol (€)

10.1.4 About Java Integration

Java is integrated into the workflow process through the ECMA expression builder, which provides a bridge to external Java objects. To access a Java class through the ECMA expression builder, the class must be in the classpath of the workflow engine. To accomplish this, you must add the Java class to the WEB-INF\lib directory in the User Application WAR file ( IDM.war).

NOTE:Unlike ECMAScript that is available in other parts of the provisioning request definition editor, form action scripts are executed on the browser, not the server. All directory access from within a form action script is handled by AJAX calls from the browser to the server. See Section 10.3.1, Form Action Script Methods.

Adding the Java Class to the User Application WAR

  1. Use a WAR file utility to open the IDM.war file. The IDM.war file is located in the application server \server\IDM\deploy directory.

  2. Copy the Java class into the WEB-INF\lib directory.

Accessing Java from ECMAScript

To access a Java class, create a function inline in the ECMA expression builder. Instantiate the function, then within the function, use ECMAScript syntax to call your Java methods. The following example creates a vector:

function list() { v=new java.util.Vector(); v.add('{Enter Item 1}'); v.add('{Enter Item 2}'); return v; };  list();

To access a custom Java class, you must preface the class name with “Packages”. For example:

v = new Packages.com.novell.myClass("value");

The ECMA expression builder is built on Mozilla* Rhino. Rhino is an open-source implementation of JavaScript written entirely in Java. For more information about accessing Java from ECMAScript, see Scripting Java.

10.1.5 About XPath Integration

This section includes the following topics:

XPath in Workflows

A provisioning request definition workflow supports a special object called flowdata (see Section 4.3.3, Understanding Workflow Data). The flowdata object is a DOM (an XML document constructed as an object in memory). You can use XPath syntax to navigate the structure of the flowdata DOM, and add, modify or delete elements and contents.

To add an object to flowdata:

Syntax

Examples

flowdata.parent/child[1]
flowdata.reason

To get an object from flowdata:

Syntax

Examples

flowdata.getObject('parent/child[1]')
flowdata.get('reason')

For information about the flowdata.get() and flowdata.getObject() methods, see Table 10-1.

XPath in Integration Activities

When you are working with an Integration activity, the ECMAScript interpreter recognizes a custom method called XPath(). This method allows expressions such as:

Input.XPath("GetBNQuoteSoapIn/GetBNQuote/sISBN")

When you use the ECMA expression builder, this type of expression is built for you automatically when you select nodes in ECMA expression builder pick lists.

The Integration activity uses the XPath addressing syntax adopted by W3C. The XPath syntax is similar to URI address syntax but includes many subtle and powerful features for addressing and manipulating XML. Some of the more common syntax rules are listed in the following table.

Table 10-10 XPath Syntax

XPath Syntax

Description

/

The single forward slash represents an absolute path to an element. For example, /ABC selects the root element ABC.

//

Double slashes represent all elements in a path. //ABC selects all occurrences of ABC. For example, //ABC//DEF selects all DEF elements that are children of ABC.

*

The asterisk selects all elements located by the preceding path. For example, *ABC/DEF selects all elements enclosed by elements ABC/DEF. //* selects all elements.

[ ]

Square brackets specifies a particular element. For example /ABC[3] selects the third element in ABC. This can also be used as a filter (similar to a Where clause in SQL). //ABC[“Table”] selects all elements that have the content “Table.”

@

The At sign selects elements with a specified attribute. For example, /ABC@name selects all elements in ABC that have an attribute called name.

|

The vertical bar allows you to specify multiple paths. For example, //ACB|//DEF selects all elements in ACB and in DEF.

$

The dollar sign allows you to reference other documents besides the current one: INVOICEBATCH/INVOICE[SELLER/NAME= $PROJECT/USERCONFIG/COMPANYNAME]

function()

XPath has numerous functions that you can add to your XPath addresses. For example, //*[count(*)=2] selects all elements that have two children.

math operator()

XPath has numerous math operators that you can add to your XPath addresses. For example, /ABC|position() mod 2 = 0] selects all even elements in ABC.

You can find the complete list of operators in the W3 Recommendation XML Path Language (XPath).

10.1.6 Performance Considerations

ECMAScript is an interpreted language, which means that every line of script in an expression must be parsed and translated to the Java equivalent before it can be executed. This adds considerable overhead to the code and results in overall slower execution of scripts than pure Java. Before using ECMAScript, you should think about the possible performance ramifications.

The following guidelines will help you to achieve optimal performance in your components and services:

  • Consider whether a task can be accomplished using a custom Java class (which you can call from ECMAScript).

  • When you need the fine control offered by scripting, use ECMAScript.

Bear in mind that the key to good performance is always a good implementation (for example, choosing the correct algorithm and attention to reuse of variables). Good code written in a slow language often outperforms bad code written in a fast language. Writing something in Java does not guarantee that it will be faster than the equivalent logic written in ECMAScript because Java has its own overhead constraints, such as, constructor call-chains (when you call a constructor for a Java object that inherits from other objects, the constructors for all ancestral objects are also called).

ECMAScript’s core objects (String, Array, Date, etc.) have many built-in convenience methods for data manipulation, formatting, parsing, sorting, and conversion of strings and arrays. These methods are implemented in highly optimized Java code inside the interpreter. It is to your advantage to use these methods whenever possible, rather than creating customized data-parsing or formatting functions. For example, suppose you want to break a long string into substrings, based on the occurrence of a delimiter. You could create a loop that uses the String methods indexOf() and substring() to parse out the substrings and assign them to slots in an array. But this would be a very inefficient technique when you could simply do the following:

var myArrayOfSubstrings = bigString.split( delimiter );

The ECMAScript String method split() breaks a string into an array of substrings based on whatever delimiter value you supply. It executes in native Java and requires the interpreter to interpret only one line of script. Trying to do the same thing with a loop that iteratively calls indexOf() and substring() would involve a great deal of needless interpreter and function-call overhead, with the accompanying performance hit.

Skillful use of built-in ECMAScript methods pays worthwhile performance dividends. If you use scripts extensively, take time to learn about the fine points of the ECMAScript language because this can help you eliminate performance bottlenecks.