Sun[TM] Identity Manager 8.0 Workflows, Forms, and Views |
Chapter 4
XPRESS LanguageThis chapter introduces the basic features of XPRESS, an XML-based expression and scripting language. Statements written in this language, called expressions, are used throughout Identity Manager to add data transformation capabilities to forms and to incorporate state transition logic within objects such as workflow and forms.
Topics in this Chapter
Read this chapter to understand these basic topics:
About the XPRESS LanguageXPRESS is a functional language that uses syntax based on XML. Every statement in the language is a function call that takes zero or more arguments and returns a value. Identity Manager provides a rich set of built-in functions, and you can also define new functions. XPRESS also supports the invocation of methods on any Java class and the evaluation of JavaScript within an expression.
Prefix Notation
The XPRESS language makes no distinction between a function call and what languages such as C refer to as an expression operator. This results in a syntactical style known as prefix notation. Prefix notation differs from the more common infix notation in that the operator of an expression is written first, followed by the operands. For example, consider the following simple logical expression written in C using infix notation:
x == 42
If C used prefix notation, the previous statement would be written:
== x 42
If C provided no expression operators and instead supplied only functions, the statement could be written as follows:
equals(x, 42)
Prefix notation is easily understood if you think in terms of calling functions rather than writing expressions.
XML Syntax and Example
XPRESS uses an XML syntax that is easy to parse and manipulate and can be embedded naturally in other XML vocabularies used within Identity Manager. The names of the XML elements are the names of functions to be called. Nested elements are the arguments to the function. In addition, there are beginning and end tags for each element (in this case, <add></add>).
Example
<add> <ref>counter</ref> <i>10</i> </add>
In the preceding example, the <add> element represents a call to the function named add. This function is passed two arguments:
- first argument – value is determined by calling a function named ref. The argument to the ref function is a literal string that is assumed to be the name of a variable. The value returned by the ref function is the current value of the variable counter.
- second argument – value is determined by calling a function named i. The argument to the i function is a literal string that is an integer. The value that the i function returns is the integer 10.
The value returned by the add function will then be the result of adding the integer 10 to the current value of the variable counter. Every function call either returns a value or performs an operation on one of its arguments. For example, if the ref call returns the value of the counter, then the <i> call returns the integer 10, and the <add> call returns the addition of the two calls.
Another example is the classic Hello World program, which is written in XPRESS as follows:
<print><s>Hello World!</s></print>
Integration with Identity Manager
Although XPRESS can be used with a standalone interpreter, it is typically embedded within an application that wants to use XPRESS statements to control or customize their behavior. This application is called the host application. Two of the more important host applications within the Identity Manager system are workflow and forms.
The host application makes calls to the XPRESS interpreter and supplies services to the interpreter. One of the more important services that the host application provides is the resolution of external variable references. Expressions often reference variables that are not defined within the expression, and the host application must then provide the values of these variables. In the case of the workflow host application, an expression can reference any variable defined within the workflow process. In the forms host application, an expression can reference the value of any form field or defvar whose value is set before the expression is evaluated.
Why Use Expressions?
Expressions are used primarily for the following tasks:
- Customizing the User Interface and Administrator Interface forms. Forms use XPRESS to control the visibility of fields and to transform the data to be displayed.
- Defining flow of control in workflow. Workflow uses XPRESS to define transition conditions, which determine the order in which steps in the workflow process are performed.
- Implementing workflow actions. Workflow actions can be implemented using XPRESS. Action expressions can perform simple calculations, or call out to Java classes or JavaScript to perform a complex operation.
For information on using expressions in workflow scripts or editing forms, see Chapter 1, "Workflow".
Working with ExpressionsThis section presents examples of some of the more common usages of expressions within Identity Manager, in particular:
Controlling Field Visibility
A common form design problem requires suppressing the display of certain fields until a particular condition is met. For example, certain resource-specific fields are relevant only when a particular resource is assigned to the user. These fields should be visible only when the resource is assigned. Otherwise, these fields should be hidden from view and not evaluated. The following example illustrates a field definition that uses an expression within the <Disable> element to control the visibility of such a field.
The <Disable> element is part of the Form XML language. The contents of the <Disable> element can be any expression in the XPRESS language. In this case, the expression is testing to see if the string Solaris appears in a list stored in the external variable named accountInfo.typeNames. With forms, this variable contains a list of all resource types currently assigned to the user.
When the form is processed for display, the expression in the <Disable> element is evaluated. If it returns true, this field is not displayed.
The values null and 0 are logically false. Non-null or non-zero fields are logically true. This means that the sting represented with the expression <s>false</s> is logically true because it is non-null.
Field values can be calculated by XPRESS using one of three elements specified in the field declaration: Derivation, Default, and Expansion.
Calculating Default Field Values
Field values can be calculated from other fields or simply set to an initial value using the <Default> element. The <Default> element is typically used to initialize an editable field and is evaluated only if the field does not already have a value assigned to it. The <Default> element is often used to calculate an account ID based on the first and last name of the user. The following example shows a field definition that uses string manipulation expressions to calculate a default account ID consisting of the first letter of the user’s first name concatenated with the user’s last name.
<Field name='waveset.accountId'>
<Display class='Text'/>
<Property name='title' value='AccountID'/>
</Display>
<Default>
<concat>
<substr>
<ref>accounts[AD].firstname</ref>
<i>0</i>
<i>1</i>
</substr>
<ref>accounts[AD].lastname</ref>
</concat>
</Default>
</Field>
The <Default> element is part of the Form XML language. This element can contain either an XPRESS expression or elements in another language called XML Object. (For more information on XML Object language, see the chapter titled XML Object Language)
When this field is processed, the system checks to see if a value already exists for the waveset.accountId attribute. If no value exists, it evaluates the expression in the <Default> element. In this case, a value is calculated by concatenating the first letter of the first name with the last name.
You may need to make sure that firstname and lastname fields have values, as demonstrated by the following example:
<cond>
<and>
<notnull><ref>accounts[AD].firstname</ref></notnull>
<notnull><ref>accounts[AD].lastname</ref></notnull>
</and>
<concat>
<substr>
<ref>accounts[AD].firstname</ref>
<i>0</i>
<i>1</i>
</substr>
<ref>accounts[AD].lastname</ref>
</concat>
</cond>
The preceding code is structured as an if-then statement in other programming languages. This cond expression has two arguments:
First, the conditional expression is evaluated. If the result of this expression is logically true, the value of cond will be the value of the then expression. If the result of the conditional expression is false, the value of cond will be null.
In this example, the cond statement ensures that values exist for two account attributes before using them to calculate accountID. The Default expression will continue to be evaluated each time the form is refreshed or saved until the prerequisites are finally set or until the user provides a value in the field. The Default expression will not be evaluated if the associated field contains a non-null value.
Deriving Field Values
A <Derivation> expression is similar to a <Default> expression except that it always calculates a value for the field, even if the field already has a non-null value. This is typically used to display a field whose value is a permutation of another field’s value. This is a valuable design feature if the resource attribute value is encoded and would not be obvious to the user.
The following example shows a field definition that uses conditional logic to map one set of values into another set.
<Field name='location' prompt='Location'>
<Display class='Text'/>
<Derivation>
<switch>
<ref>accounts[Oracle].locCode</ref>
<case>
<s>AUS</s>
<s>Austin</s>
</case>
<case>
<s>HOU</s>
<s>Houston</s>
</case>
<case>
<s>DAL</s>
<s>Dallas</s>
</case>
<case default='true'>
<s>unknown</s>
</case>
</switch>
</Derivation>
</Field>
The <Derivation> element is part of the Form XML language that can contain an expression. When this field is processed, the expression in the <Derivation> element is evaluated to determine the value to be displayed for this field.
In the preceding example, the value of the resource account attribute accounts[Oracle].locCode is compared to the first value in each case expression. If a match is found, the result of the switch expression is the second value in the matching case expression.If no matches are found, the result of the switch is the value within the default case.
Generating Field Values
In certain forms, you might want to first display a set of abstract derived fields to the user, then generate a different set of concrete resource account attribute values when the form is submitted. This is known as form expansion. An <Expansion> element is typically used in hidden fields that depend on editable fields in the form. One purpose of the <Expansion> element is to convert data that is familiar and readable to an end-user into data that is recognized by a resource. For example, a user can see a manager’s full name in the form, but the system receives a unique ID that it recognizes as belonging to a manager.
The following example shows a field definition that uses conditional logic to convert the value derived for the location field in the previous example back into a three-letter abbreviation.
<Field name='accounts[Oracle].locCode'>
<Expansion>
<switch>
<ref>location</ref>
<case>
<s>Austin</s>
<s>AUS</s>
</case>
<case>
<s>Houston</s>
<s>HOU</s>
</case>
<case>
<s>Dallas</s>
<s>DAL</s>
</case>
</switch>
</Expansion>
</Field>
The <Expansion> element is part of the Form XML language and can contain an expression. When this field is processed, the expression in the <Expansion> element is evaluated to determine the value of the field.
In this example, this element performs the reverse of the mapping performed by the location field. This field is also hidden by the absence of an assigned Display class. This lack of Display class prevents the field from being displayed in the form, but the field is still considered to be an active part of the form and will generate values for resource attributes through its <Expansion> expression.
Note
For all forms except the User view, Expansion rules are run whenever the page is recalculated or the form is saved. For the User view, an <Expansion> tag runs when the userform is first loaded as well.
Workflow Transition Conditions
When defining a workflow process, you must specify the rules by which control passes from one workflow activity to another. A path between two activities is called a transition. A rule that governs the use of the transition is called a transition condition.
For example, consider the following activity definition:
<Activity name='Check Results'>
<Transition to='Log Errors'>
<gt> <ref>ERROR_COUNT</ref> <i>0</i> </gt>
</Transition>
<Transition to='end'/>
</Activity>
This activity defines two distinct transitions to separate activities: an activity named Log Errors and another named end. When workflow processes this activity, it will take the first transition for which the transition condition returns true.
In this example, the first transition has a condition that tests the value of the variable ERROR_COUNT to see if it is greater than zero. That transition is taken only if there is a positive error count. The second transition has no condition, and consequently will always be taken if the first transition condition is false.
Workflow Actions
A workflow activity can perform one or more actions. One possible action is the evaluation of an XPRESS expression, as shown in the example below.
<Activity name='Increment Counter'>
<Action>
<expression>
<set name='counter'>
<add> <ref>counter</ref> <i>1</i> </add>
</set>
</expression>
</Action>
<Transition to='Next'/>
</Activity>
When a workflow action is implemented in XPRESS, an XPRESS expression is wrapped in an expression element that is then placed within an Action element. In this example, the expression references the current value of a variable named counter, adds one to that value, then assigns the incremented value to the variable with the same name.
Invoking Java Methods from Workflow Actions
Complex workflow actions can be implemented in Java. Typical examples of complex workflow actions include storing data in a relational database or sending a message to a help desk system. These Java classes can be integrated with workflow using XPRESS.
<Activity name='Log Status'>
<Action>
<expression>
<invoke name='logStatus'
class='custom.OracleStatusLog'>
<ref>accountId</ref>
<ref>email</ref>
<ref>status</ref>
</invoke>
</expression>
</Action>
<Transition to='Next'/>
</Activity>
In this example, the XPRESS invoke function is used to call a static method named logStatus, which is defined in the custom Java class custom.OracleStatusLog. Three arguments are passed to this method, the values of which are taken from workflow variables.
In these types of cases, the primary computation is performed in the Java class, while XPRESS acts to integrate the class into the workflow.
Testing Expressions
Testing expressions involves two steps:
Checking Expression Syntax with lh Command
To check the XML syntax of expressions without actually evaluating their logic:
- Confirm that you have %WSHOME%\bin in your PATH environment variable. (For information on changing environment variables to work with Identity Manager, see the section of Identity Manager Installation that describes using command-line tools.)
If %WSHOME%\bin is not in your path, then you must change to %WSHOME%\bin before you can run the tools.
- From the command line, enter lh xmlparse <xpress_file> where xpress_file represents the name of the file that contains the XML you want to test. This command parses the file for XML correctness and displays error messages in the console.
Tracing XPRESS Evaluation
Once you have written and successfully stored an expression in the repository, you can turn on XPRESS tracing to determine if the expression is functioning correctly. XPRESS trace messages are sent to the standard output device. Since XPRESS is typically evaluated within the application server, the trace messages are sent to the console window or log file that was active when the application server was started.
There are two forms of XPRESS tracing:
Typically, block-level tracing is preferable because it reduces the amount of trace output, which is then easier to analyze.
Enabling Tracing
To enable global trace, set a Waveset.properties file entry named xpress.trace to the value true. If you change the Waveset.properties file while the application server is running, you must either restart the application server, or go to the Debug Page and click Reload Properties.
To perform block-level trace, wrap the expressions you want to trace in a <block> expression and include the attribute trace='true' in the block start tag.
<block trace='true'>
<invoke name='getTime' class='java.util.Date'/>
</block>
or
<Default>
<block trace = 'true'>
<ref>global.accountId</ref>
</block>
</Default>Invalid Examples
Do not use the <block> element in the following ways.
<block trace='true'>
<Field name ='field1'>
…</Field>
</block>
or
<Field name='Field2'>
<block trace='true'>
<Default>
<ref>global.accounts</ref>
</Default>
</block>
</Field>The trace messages include the names of the functions, the values of each argument, and the return values.
To turn tracing off for XPRESS, set the xpress.trace value to false, and reload the Waveset.properties file.
FunctionsIdentity Manager ships with a library of XPRESS functions that can be used in expressions. These functions are classified into the following categories:
- Value constructor expressions
- Arithmetic expressions
- Logical expressions
- String manipulation expressions
- List manipulation expressions
- Conditional, iteration, and block expressions
- Variable and function definition expressions
- Object manipulation expressions
- Java and JavaScript expressions
- Debugging and testing expressions
Value Constructor Expressions
In XPRESS, literal values are written as text contained with an XML element. The element name is the name of a function, and the literal text is the argument to the function. The following functions are provided for constructing simple atomic data types.
array Function
Builds a value of type list by evaluating each of the argument expressions and concatenating the return values. The expression can take multiple arguments. Null values are not filtered.
Example
<array>
<s>apples</s>
<s>oranges</s>
<s>wiper blades</s>
</array>
i Function
Constructs an integer value. The function takes one argument, which must be literal text. The text should contain only numeric digits and can be optionally preceded by a plus or minus.
Example 1
<i>0</i>
Example 2
<i>42</i>
Example 3
<i>-1234</i>
list Function
Builds a value of type list by evaluating each of the argument expressions and concatenating the return values. The expression can take multiple arguments. Null values will be filtered.
Example
<list>
<s>apples</s>
<s>oranges</s>
<s>wiper blades</s>
</list>map Function
Creates a map that consists of the key-value pairs of each subexpression.
Example
<map>
<!--Key 1-->
<!--Value 1-->
<!--Key n-->
<!--Value n-->
</map>
null Function
Constructs a null value.
Example 1
<null/>
Example 2
<null></null>
s Function
Constructs a string value. The function takes one argument, which must be literal text. (Length is constrained only by the amount of contiguous memory available in your Java environment.)
Example
<s>Now is the time</s>
Arithmetic Expressions
Use the following functions to perform arithmetic processing within expressions.
add Function
Performs integer summation over the values of all arguments. Arguments that are not integers are coerced to integers.
Example
The following expression results in an integer (42).
<add> <i>40</i> <i>1</i> <s>1</s> </add>
div Function
Performs successive integer division over the values of all arguments. Arguments that are not integers are coerced to integers.
Example
The following expression results in an integer (42).
<div> <i>84</i> <i>2</i> </div>
mod Function
Performs successive integer modulo over the values of all arguments. Arguments are coerced to integers. Arguments of type null are ignored.
Example
The following expression results in an integer (42).
<mod> <i>142</i> <i>100</i> </mod>
mult Function
Performs successive integer multiplication over the values of all arguments. Arguments that are not integers are coerced to integers.
Example
The following expression results in an integer (42).
<mult> <i>7</i> <i>3</i> <i>2</i> </mult>
sub Function
Performs successive integer subtraction over the values of all arguments. Arguments that are not integers are coerced to integers.
Example
The following expression results in an integer (42).
<sub> <i>50</i> <i>6</i> <i>2</i> </sub>
Logical Expressions
Use the following functions to perform logical operations within expressions. Most logical functions return 1 and 0 to indicate true or false. The exceptions are cmp, ncmp, and, and or.
and Function
Takes any number of arguments and returns zero if any argument values are logically false. If one child evaluates to false, the function does not evaluate subsequent children. If all arguments are logically true, the function returns the value of the last argument. Zero (<i>0</i> or <s>0</s>) and <null> are considered logically false.
Example 1
The following expression returns zero.
<and> <i>42</i> <s>cat</s> <i>null</i> </and>
Example 2
The following expression returns cat.
<and> <i>42</i> <s>cat</s> </and>
cmp Function
Compares two string values. You can use this function to sort a list of strings
The function returns:
Arguments are coerced to strings, if necessary.
Example 1
The following expression returns -1.
<cmp>
<i>20</i>
<i>100</i>
</cmp>Example 2
The following expression returns -16. This expression returns a number that indicates the difference between the letters r and b when presented in alphabetical order. Since there are 16 letters between the letters b and r, when bob is compared to ray, the value is -16. Alternatively, if r were compared to b, the value returned would be 16.
<cmp>
<s>bob</s>
<s>ray</s>
</cmp>Example 3
The following expression returns 0 (zero).
<cmp>
<s>daryl</s>
<s>daryl</s>
</cmp>eq Function
Performs an equality test. The function can take multiple arguments, although typically it has only two. The data type of the first argument defines how the equality test is performed. If the first argument is of type:
This function returns:
0 – statement is logically false
1 – statement is logically true
Example
<eq> <ref>role</ref> <s>engineering</s> </eq>
gt Function
Takes two arguments.
This function returns:
Example
<gt>
<ref>age</ref>
<i>42</i>
</gt>gte Function
Takes two arguments.
This function returns:
Example
The following expression returns 1.
<gte>
<i>10</i>
<i>5</i>
</gte>isFalse Function
Used when referencing Boolean values that are represented with the strings true and false rather than the number 0 and 1. Takes one argument.
This function returns:
Example
The following expression returns 1.
<isFalse>
<s>false</s>
</isFalse>isnull Function
Takes one argument.
This function returns:
Example 1
The following expression returns 1.
<isnull> <null/> </isnull>
Example 2
The following expression returns 0.
<isnull> <i>0</i> </isnull>
isTrue Function
Used when referencing Boolean values that are represented with the strings true and false rather than the number 0 and 1. Takes one argument.
This function returns:
Example
The following expression returns 0.
<isTrue>
<s>false</s>
</isTrue>lt Function
Takes two arguments.
This function returns:
Example 1
The following expression returns 0 (zero).
<lt>
<i>10</i>
<i>5</i>
</lt>Example 2
The following expression returns 1.
<lt>
<i>5</i>
<i>10</i>
</lt>lte Function
Takes two arguments.
This function returns:
Example
<lte>
<ref>age</ref>
<i>42</i>
</lte>ncmp Function
Performs case-insensitive comparison of two string values.
This function returns:
Arguments are coerced to strings, if necessary.
Example
The following expression returns 0.
<ncmp>
<s>Daryl</s>
<s>daryl</s>
</ncmp>neq Function
Performs an inequality test. Its behavior is simply the negation of the equality test performed by the eq function.
This function returns:
Example
<neq>
<ref>role</ref>
<s>management</s>
</neq>not Function
Reverses the logic of the nested expression.
This function returns:
Example
The following example returns 1.
<not> <eq> <i>42</i> <i>24</i> </eq> </not>
or Function
Takes multiple arguments.
This function returns:
0 – all arguments are logically false
Value of the first argument expression that results in a logically true value
Example 1
The following expression returns 0, which is logically false.
<or> <i>0</i> <i>0</i> </or>
Example 2
The following expression returns the string cat, which is also logically true.
<or> <i>0</i> <s>cat</s> </or>
notnull Function
Takes one argument
This function returns:
0 – null argument
1 – non-null argument
Example 1
The value of the following expression is 1 if the firstname has been set or 0 (zero) if firstname is null.
<notnull>
<ref>firstname</ref>
</notnull>Example 2
The value of the following expression is 0 because the value is null.
<notnull><null/></notnull>
String Manipulation Expressions
Use the following functions to perform string manipulation within expressions.
indexOf Function
Returns the position of a string within another string.
Example
The following function returns 3.
<indexOf>
<s>abcabc</s>
<s>abc</s><s>l</s>
</indexOf>concat Function
Concatenates two or more string values.
Example
The following expression returns <s>Now is the time</s>.
<concat>
<s>Now </s><s>is </s><s>the </s><s>time</s>
</concat>downcase Function
Takes a single argument, which is coerced to a string. It returns a copy of the argument with all upper case letters converted to lower case.
Example
The following expression returns <s>abc</s>.
<downcase><s>ABC</s></downcase>
length Function
Returns the number of elements in the list. You can also use this function to return the length of a string.
first argument – list or string
Example 1
The following expression returns 2.
<length>
<list>
<s>apples</s>
<s>oranges</s>
</list>
</length>Example 2
<length>
<s>Hello world!</s>
</length>This expression returns a value of 11.
ltrim Function
Takes a single argument, which is coerced to a string.
It returns a copy of the argument with the leading white space removed.
Example
The following expression returns <s>hello</s>.
<ltrim><s> hello</s></ltrim>
match Function
Deprecated. Use the contains function instead.
message Function
Formats a message by message catalog key.
Example
<message severity-’ok’ name=’DEFAULT_MESSAGE’>
<!--message parameter 0-->
<!--message parameter n-->
</message>
pad Function
Pads a string with spaces so that it reaches a desired length.
first argument – the string to pad
second argument – desired length
third argument – (optional) specifies the pad character, which by default is a space
Example
The following expression results in <s> email </s>
<pad>
<s> email</s>
<i>10</i>
</pad>rtrim Function
Takes a single argument, which is coerced to a string. It returns a copy of the argument with the trailing white space removed.
Example
This example returns 0 (zero).
<cmp>
<s>hello</s><rtrim><s>hello </s></rtrim>
</cmp>
split Function
Splits a string into a list of strings.
first argument – string to be split
second argument – a set of one or more string delimiters. Each character in this string will cause a break.
A list is created that contains each substring between delimiters.
Example 1
<split>
<s>Austin City Limits</s>
<s> </s>
</split>This expression returns the following list.
<list>
<s>Austin</s>
<s>City</s>
<s>Limits</s>
</list>Example 2
The following expression uses multiple delimiters.
<split>
<s>(512)338-1818</s>
<s>()-</s>
</split>This expression returns the following list.
<list>
<s>512</s>
<s>338</s>
<s>1818</s>
</list>substr Function
Extracts ranges of characters from a string.
This function takes two forms:
For example, these two invocations are equivalent:
<substr>
<s>Hello World</s>
<i>3</i>
<i>4</i>
<substr>and
<substr s='3' l='4'>
<s>Hello World</s>
<substr>Both functions return the string lo W.
<block>
<substr s='3' l='4'>
<s>Hello World</s> --> Hello World
</substr> --> lo W
</block> --> lo WThe start and length parameters are optional. If the start argument is missing, either because only the string is specified as a child of the substr node as in
<substr>
<s>Hello World</s>
<substr>and the attribute s is also missing from the substr node, the start is assumed to be the beginning of the string. In other words, its value is zero if not specified explicitly.
first argument – string
second argument – starting position
third argument – number of characters to retrieve
Examples
The following expression returns <s>Now</s>.
<substr>
<s>Now is the time</s>
<i>0</i>
<i>3</i>
</substr>In the following example, the start attribute is missing, but is assumed to be 0:
<block>
<substr l='4'>
<s>Hello World</s> --> Hello World
</substr> --> Hell
</block> --> HellThe length argument is also optional. A missing length argument causes the function to extract the rest of the string. length can be unspecified when only the string and start arguments are specified a child nodes of substr such as:
<substr>
<s>Hello World</s>
<i>3</i>
<substr>or when the l attribute is missing from the substr node like. Note that the length argument is unspecified below, but the rest of the string starting from this start is returned:
<block>
<substr s='3'>
<s>Hello World</s> --> Hello World
</substr> --> lo World
</block> --> lo Worldtrim Function
Takes a single argument, which is coerced to a string.
It returns a copy of the argument with the leading and trailing white space removed.
Example
The following expression returns <s>hello</s>.
<trim><s> hello </s></trim>
upcase Function
Takes a single argument, which is coerced to a string.
It returns a copy of the argument with all lower case letters converted to upper case.
Example
The following expression returns <s>ABC</s>.
<upcase><s>abc</s></upcase>
ztrim Function
Returns the string value of the subexpression with leading zeros removed.
Example
<ztrim>
<s>00000sample</s>
</ztrim>
This function evaluates to <s>sample</s>.
List Manipulation Expressions
Most list manipulation functions have two forms depending upon whether the name attribute is included in the function element:
- If included in the function element, the name is expected to resolve to a variable containing a list. In this case, the referenced variable is destructively modified. The following example modifies the list stored in the someList variable and adds two elements:
<append name='someList'>
<s>Hello</s>
<s>World</s>
</append>
If the name is not included in the function element, a new list is constructed. In the following example, a new list is created by combining the elements of the list stored in the someList variable with two additional elements. The value of the someList variable is not modified.
<append>
<ref>someList</ref>
<s>Hello</s>
<s>World</s>
</append>Use the following functions to manipulate list elements.
append Function
Appends a value to a list. The argument list takes one of two forms depending on the presence of the name attribute. If name is not specified, then the first argument must be a list and the remaining arguments are elements to append to that list. A copy of the list is returned, the original list is not modified. If the name argument is used, then all arguments are considered objects to be appended to the list contained in the variable with that name. The list is modified without being copied.
Example 1
The following expression makes a copy of the list contained in the variable srclist then appends one element.
<append>
<ref>srclist</ref>
<s>oranges</s>
</append>Example 2
The following expression modifies an existing list by appending a value.
<set name= 'somelist'>
<List>
<s>We</s>
<s>say</s>
</List>
</set><append name= 'somelist'>
<s>Hello</s>
<s>World</s>
</append>
<ref>someList</ref>appendAll Function
Merges the elements in multiple lists. If the name attribute is specified, an existing list is modified. Otherwise, a new list is created.
Example 1
The following expression creates a new list by combining the elements in srclist with three additional elements.
<appendAll>
<ref>srclist</ref>
<list>
<s>apples</s>
<s>oranges</s>
<s>peaches</s>
</list>
</appendAll>Example 2
The following expression adds three elements to the list stored in the variable srclist.
<appendAll name='srclist'>
<list>
<s>apples</s>
<s>oranges</s>
<s>peaches</s>
</list>
</appendAll>contains Function
first argument – list or string
second argument – any object to search for in the list or a substring to search for in the string
This function returns:
1 -- list contains a given value or the string contains the given substring
Example 1
The following expression returns 1.
<contains>
<list>
<s>apples</s>
<s>oranges</s>
</list>
<s>apples</s>
</contains>Example 2
The following expression returns 1
<contains>
<s>foobar</s>
<s>foo</s>
</contains>
containsAll Function
Takes two list arguments.
This function returns:
1 -- the list contains all elements contained in another list
0 (zero) -- the list does not contain all elements contained in the second list
Example
The following expression returns 0.
<containsAll>
<ref>fruitlist</ref>
<list>
<s>oranges</s>
<s>wiper blades</s>
</list>
</containsAll>containsAny Function
first argument – list to be searched
second argument – an element or a list of elements to search for in the first list
This function returns:
1 -- first list contains any elements that are contained in a second list.
0 (zero) -- first list does not contain any elements that are contained in a second list.
Example
The following expression returns 1.
<containsAny>
<ref>fruitlist</ref>
<list>
<s>oranges</s>
<s>wiper blades</s>
</list>
</containsAny>filterdup Function
Filters duplicate elements from a list. Given a list, it returns a new list in which duplicate entries have been removed.
Example 1
<filterdup>
<list>
<s>apples</s>
<s>oranges</s>
<s>apples</s>
</list>
</filterdup>This expression returns the following list.
<list>
<s>apples</s>
<s>oranges</s>
</list>Example 2
You can also use this function to manipulate an existing list rather than creating a new list.
<filterdup name = 'namedlist'/>
filternull Function
Filters null elements from a list.
This function returns a single list removing all null elements (when given one list).
Example
<filternull>
<list>
<s>apples</s>
<null>
<s>oranges</s>
<null/>
</list>
</filternull>This expression returns the following list.
<list>
<s>apples</s>
<s>oranges</s>
</list>Example 2
You can also use this function to manipulate an existing list rather than creating a new list.
<filternull name = 'namedlist'/>
expand Function
Returns the string value of the subexpression with $() variable references expanded.
Example
<expand><s>$(sample)</s></expand>
get Function
Retrieves the value of the nth element in the list. The list indexes starts count from zero (0). Arguments are a list and an integer.
Example
<get>
<list>
<s>apples</s>
<s>oranges</s>
</list>
<i>1</i>
</get>This expression returns <s>oranges</s>
indexOf Function
first argument – a list value to search
second argument – value for which to search
third argument – (optional) starting index
This function returns either the ordinal position of a list element that matches a given value or -1 (the given value is not in the list).
Example 1
The following expression returns 1.
<indexOf>
<list>
<s>apples</s>
<s>oranges</s>
</list>
<s>oranges</s>
</indexOf>Example 2
The following expression returns 3.
<indexOf>
<list
<s>apples</s>
<s>oranges</s>
</list>
<s>oranges</s>
<i>2</i>
</indexOf>
insert Function
Inserts a value into the list. Elements following the insertion index down are shifted to make room for the new element.
first argument – a list to which an element is inserted
second argument – integer specifying position in the list at which to insert the new element
third argument – value to insert into the list
Example 1
<insert>
<list>
<s>apples</s>
<s>oranges</s>
</list>
<i>1</i>
<s>wiper blades</s>
</insert>This expression returns the following list.
<list>
<s>apples</s>
<s>wiper blades</s>
<s>oranges</s>
</list>This function can also take a named list.
<insert name='name_of_list'>
<! -- position in which to insert the list>
<! -- value to insert>
</insert>
Example 2
<insert name=’variable name of list’>
<!--the position at which to insert -->
<--!the value to insert -->
</insert>
length Function
Returns the number of elements in the list. You can also use this function to return the length of a string.
first argument – list or string
Example 1
The following expression returns 2.
<length>
<list>
<s>apples</s>
<s>oranges</s>
</list>
</length>Example 2
<length>
<s>Hello world!</s>
</length>This expression returns a value of 11.
remove Function
Removes one or more elements from a list. The argument list takes one of two forms depending on the presence of the name attribute. If name is not specified, then the first argument must be a list and the remaining arguments are elements that are removed from that list. A copy of the list is returned. (The original list is not modified.) If the name argument is used, then all arguments are considered objects to be removed from the list contained in the variable with that name. The list is modified without being copied.
Example 1
The following expression makes a copy of the list contained in the variable srclist, then removes one element and returns the copy of the list.
<remove>
<ref>srclist</ref>
<s>oranges</s>
</remove>Example 2
The following expression modifies an existing list by removing a value.
<set name= 'somelist'>
<List>
<s>We</s>
<s>say</s>
</List>
</set><remove name= 'somelist'>
<s>say</s>
<s>say</s>
</remove>
<ref>someList</ref>removeAll Function
Removes all elements contained in one list from another list. If the name attribute is specified, an existing list is modified. Otherwise, a new list is created.
Example 1
The following expression creates a new list by removing the elements in srclist along with three additional elements.
<removeAll>
<ref>srclist</ref>
<list>
<s>apples</s>
<s>oranges</s>
<s>peaches</s>
</list>
</removeAll>Example 2
The following expression removes three elements in the list stored in the variable srclist.
<removeAll name='srclist'>
<list>
<s>apples</s>
<s>oranges</s>
<s>peaches</s>
</list>
</removeAll>This expression results in the following list.
<list>
<s>wiper blades</s>
</list>retainAll Function
Computes the intersection of two lists, and returns elements contained in both lists.
This function has two variants.
Example 1
Sets a named list to an intersection of it and the another list.
<retainAll name=’variable name of list’>
<!-- the other list-->
</retainAll>
Example 2
Returns the intersection of two lists.
<retainAll>
<!-- the first list>
<!-- second list-->
</retainAll>
setlist Function
Assigns a value into a specified position in a list, overwriting its current value. If necessary, the list is extended to contain the indexed element. New elements created during list extension will be null.
first argument – list
second argument – integer specifying position in the list at which to insert the new element, starting with zero.
third argument – element
Example 1
<setlist>
<list>
<s>apples</s>
<s>oranges</s>
<s>wiper blades</s>
</list>
<i>2</i>
<s>bassoons</s>
</setlist>This expression results in the following list and returns null.
<list>
<s>apples</s>
<s>oranges</s>
<s>bassoons</s>
</list>Example 2
<setlist>
<list>
<s>apples</s>
<s>oranges</s>
<s>wiper blades</s>
</list>
<i>5</i>
<s>bassoons</s>
</setlist>This expression results in the following list and returns null.
<list>
<s>apples</s>
<s>oranges</s>
<s>wiper</>
</null>
</null>
<s>bassoons</s>
</list>Conditional, Iteration, and Block Expressions
Use these functions to perform conditional and block processing within expressions.
block Function
Groups more than one expression into a single expression. The value of the block function is the value of its last argument.
Note
The <set> function does not return a value. If the last line in a block statement involves a set operation, the block statement will not return a value. If you want the block statement to return the value of a variable, use <ref>variable_name</ref> on the last line of the block statement.
Example
<block>
<s>Hello there!</s>
<add> <i>100</i> <i>2</i> </add>
<i>42</i>
</block>The block returns a value of 42, the value of its last argument.
For an example of using block with a trace statement, see Debugging and Testing Expressions.
break Function
Forces early termination of an expression. A break can be used within the following expressions: block, dolist, while, and, or. The value of the break expression becomes the value of the containing expression. The break can cause the termination of several levels of expression when the optional block name is used.
Example 1
The following expression contains a simple break terminating a loop.
<dolist name='el'>
<ref>list</ref>
<cond><eq><ref>el</ref><s>000</s></eq>
<break>
<ref>el</ref>
</break>
</cond>
<null/>
</dolist>In this example, the dolist function iterates over the elements of a list looking for value 000. The value of the dolist function is a list formed by concatenating the values that are returned by the last subexpression in each iteration.
Example 2
The following expression demonstrates the use of a block name to break through more than one level.
<block name='outer block'>
<dolist name='el'>
<ref>listOfLists</ref>
<dolist name='el2'>
<ref>el</ref>
<cond><eq><ref>el</ref><s>000</s></eq>
<break name='outer block'>
<ref>el</ref>
</break>
</cond>
</dolist>
<null/>
</dolist>
</block>This is similar to the previous example except that there are two loops. The outer loop iterates over a list whose elements are themselves lists. The inner loop iterates over the element lists. When the value 000 is found, both loops are terminated by referencing the block name outer block in the break expression.
cond Function
Provides a way to conditionally select the value of one of two expressions. It is similar to the ternary conditional operator (a?b:c) in C and Java.
Example
The cond function allows three arguments. The first argument is called the condition. If the value of the condition is logically true, the value of the cond will be the value of the second argument. If the value of the condition is false, the value of the cond will be the value of the third argument. If the value of the condition is false, and the third argument not present, the value of the cond is null.
<cond>
<gt>
<ref>age</ref>
<i>40</i>
</gt>
<s>old</s>
<s>young</s>
</cond>dolist Function
Iterates over the elements of a list. The value of the name attribute will become the name of variable that can be referenced within the loop.
The value of this variable will be the value of successive list elements.
The first subexpression returns the list over which to loop. The remaining subexpressions are repeated once for each element in the list.
The value of the dolist function is a list formed by concatenating the values returned by the last subexpression in each iteration.
Example
The following expression creates a list called subset, which contains the subset of elements in srclist that exceed 10.
<set name='subset'>
<dolist name='el'>
<cond>
<gt>
<ref>el</ref>
<i>10</i>
</gt>
<ref>el</ref>
</cond>
</dolist>
</set>switch Function
first argument - any XPRESS expression
second arguments - series of <case> elements
The first argument is evaluated and compared against each of the <case> elements until a match is found. The <switch> function evaluates to the first <case> for which there is a match. If no match is found, the <switch> evaluates to the <case> element where default='true'.
Example
The following expression returns apples.
<switch>
<s>A</s>
<case default='true'>
<s>unknown</s>
</case>
<case>
<s>A</s>
<s>apples</s>
</case>
<case>
<s>B</s>
<s>oranges</s>
</case>
</switch>select Function
Returns the first non-null (and non-zero) value in a list.
Example
<select>
<ref>:display.session</ref>
<ref>context</ref>
</select>
If you have the following statement:
<select>
<ref>first/ref>
<ref>second</ref>
<ref>third</ref.
</select>
This statement would first check to see if first was null. If not, it would return the value of first, or move on to the next item until one returns true or all items are exhausted.
You can use this function when you need to obtain the correct context from, for example, a workflow or when calling a formUtil method.
Using select in this way allows you to call formUtil methods from anywhere in Identity Manager without knowing which variable houses the Lighthouse Context. In a form, you would specify the context with <ref>:display.session</ref>. However, for the same FormUtil call in a Workflow, you must instead use <ref>context</ref>.
while Function
Repeats a set of expressions until a condition is met. The first subexpression is called the conditional and will be evaluated each time through the loop. The loop terminates when the conditional is logically false. The value of the while expression is the value of the last expression in the loop during the last iteration.
Example
The following expression returns null.
<while>
<gt>
<ref>counter</ref>
<i>0</i>
</gt><set name='counter'>
<sub> <ref>counter</ref>
<i>1</i>
</sub>
</set>
</while>Variables and Function Definition Expressions
Use the following functions to reference and define variables and functions within expressions.
ref Function
References the value of a variable. The variable can either be an external variable supported by the host application or an internal variable defined with <defvar>.
Example 1
<ref>waveset.role</ref>
Example 2
<defvar name='milk'><s>milkvalue</s></defvar>
<defvar name='shake'><s>milk</s></defvar>
<ref><ref>shake</ref>
evaluates to <s>milkshake</s>
defvar Function
Defines a new variable. The variable can then be referenced by any expression within and below the containing expression in which the variable was defined. The variable must be given a name using the XML attribute name.
A defvar statement should not reference itself. If it does, it will cause a loop.
Note
Avoid the following constructions.
<defvar name='fullname'>
<ref>fullname</ref>
</defvar>or
<defvar name='counter'/>
<add><ref>counter</ref>
<i>0</i>
</add>
</defvar>
Example 1
The following expression defines a variable and initializes its value to a list of two elements.
<defvar name='theList'>
<list>
<s>apples</s>
<s>oranges</s>
</list>
</defvar>Example 2
The following expression defines a variable and initializes its value to the integer zero.
<defvar name='counter'>
<i>0</i>
</defvar>defarg Function
Defines an argument within a function defined with <defun>. Arguments are similar to variables, but they must be defined in the order in which arguments are passed to the function.
Example
<defarg name='arg1'/>
<defarg name='arg2'/>defun Function
Defines a new function. The <defarg> function must be used to declare the arguments to a function. Use the <call> function to execute the function. Functions are typically defined within forms.
Example
<defun name='add100'>
<defarg name='input'/>
<add>
<ref>input</ref>
<i>100</i>
</add>
</defun>call Function
Calls a user-defined function. The arguments to call are assigned to arguments with <defarg> in the so-called function. The order of the call arguments must match the order of the <defarg>s. In previous releases, the call function could be used to call rules. Now, use the rule function for that purpose.
Example
The following expression returns 142.
<call name='add100'>
<i>42</i>
</call>rule Function
Calls a rule. The arguments to rule are passed by name using the argument element. The value of an argument can be specified with the value attribute if it is a simple string. The argument value can also be calculated with an expression by omitting the value attribute and instead writing an expression within the body of the argument element.
A <rule> element can also call another rule that dynamically calculate the name of another rule to call.
For more information on creating or calling rules in forms and workflows, see the chapter titled Rules.
Examples
The following expression returns the employee ID of the designated user.
<rule name='getEmployeeId'>
<argument name='accountId' value='maurelius'/>
</rule>
<rule name='getEmployeeId'>
<argument name='accountId'>
<ref>username</ref>
</argument>
</rule>The following expression calls another rule that calculates the returned value.
<rule>
<cond>
<eq><ref>var2</ref><s>specialCase</s></eq>
<s>Rule2</s>
<s>Rule1</s>
</cond>
<argument name='arg1'>
<ref>variable</ref>
</argument>
</rule>Object Manipulation Expressions
Use the following functions to manipulate arbitrary object values within expressions.
get Function
Retrieves a value from within an object. The
first argument – Must be a List, Map, or Object.
second argument – Must be a String or Integer. If the first argument is a List, the second argument is coerced to an integer and used as a list index. If the first argument is a GenericObject, the second argument is assumed to be the name of a JavaBean property.
The function behaves differently if the first argument is a list. If the first argument is a list, then the second argument is an integer list index. The element at that index is returned.
Example
This expression returns a string that is the name of the currently assigned role for the user.
<get>
<!--List, Map, or Object -->
<!-- String -->
</get>This expression is equivalent to call userView.getRole() in Java code.
putmap Function
Assigns map elements to an object.
map – specifies the map.
key – specifies the map key.
value – specifies the value to assign to the map key.
Example
<putmap>
<ref>userView</ref>
<s>waveset.role</s>
<s>engineering</s>
</putmap>
setlist Function
Assigns list elements to an object.
list – specifies the list
index – specifies the order of elements in the list
value – specifies the value to assign to the list element
Example
<setlist>
<ref>myList</ref>
<i>s</i>
<s>accounts</s>
</setlist>
setvar Function
Set the value on the variable. This function accepts a static variable name.
name – identifies the name of the variable
value – specifies the value to assign to the variable
Example
<setvar>
<ref>var</ref>
<s>text</s>
</setvar>
instanceof
Identifies whether an object is an instance of the type specified in the name parameter.
name – identifies the object type you are checking against.
This function returns 1 or 0 (true or false) depending on whether the sub expression object is an instance of the type specified in the name parameter.
Example
The following expression returns 1 because ArrayList is a List
<instanceof name='List'>
<new class='java.util.ArrayList'/>
</instanceof>Java and JavaScript Expressions
Use the following functions to call and manipulate Java classes or JavaScript functions from within expressions.
invoke Function
Invokes a method on a Java object or class.
There are two forms of this function:
static method
<invoke class=’class name’ name=’method name’>
<!--method argument 0 -->
<!--method argument n-->
</invoke>
instance method
<invoke class=’method name’>
<!--the object to invoke the method on -->
<!--method argument 0 -->
<!--method argument n-->
</invoke>
To use this function, you must be familiar with the class and method names you want to call, the arguments they take, and the method’s actions. This function is frequently used to call the following Identity Manager classes:
For more information, see the available documentation for these classes.
new Function
Creates an instance of a Java class. The class name is provided in the XML class attribute and must be fully qualified with the class package name.
You can also use this function to create a new object and return it as the value of an expression or rule without necessarily invoking methods on it.
Example
<new class='classname'/>
<!--constructor argument 0-->
<!--constructor argument n-->
</new>
script Function
Encapsulates a fragment of JavaScript. When this expression is evaluated, the JavaScript interpreter is launched to process the script. The value of the expression is the value of the last JavaScript statement. Within the script, the object env can be used to access variables in the host application.
Avoid using JavaScript in performance-critical expressions such as <Disable> expressions in forms. Short XPRESS expressions are easier to debug using the built-in tracing facilities. Use JavaScript for complex logic in workflow actions.
Example
<script>
var arg1 = env.get('arg1');
arg1 + 100;
</script>
<script>
importPackage(Packages.java.util);
var cal Now = Calendar.getInstance();
cal Now.getTime()
</script>Debugging and Testing Expressions
Enabling tracing can result in a large amount of trace data.
Use the following functions to enable expression trace or print text to help diagnose problems in an expression.
Note
Globally enabling trace may result in a large amount of trace data being printed. If it is usually better to enable trace at the block level by setting the trace attribute of the block element to true.
trace Function
Enables or disables expression tracing. If the argument evaluates to true, tracing is enabled.
If tracing is enabled, it will go to standard output.
Example 1
<trace><i>1</i></trace>
Example 2
<trace><i>0</i></trace>
print Function
Prints the value of each subexpression to standard output.
Example
<print>
<s>Ashley World!</s>
</print>
Data TypesAll functions return a value that has one of the data types listed in the following table.
.
Table 4-1 Return Value Data Types
Data Type
Definition
integer
Represents a signed integral value. The precision of the value is at least 32 bits.
list
Represents ordered lists of other values. The values in a list are called elements. List elements can be null. A list lacking elements is not considered to have a null value.
null
Represents the absence of a value. A function might return null if it is called only for side effect, or if it cannot compute a meaningful value from the given arguments. The way a null value is handled depends on the function being passed a null argument. In general, a null value is considered to be logically false and is ignored in arithmetic expressions.
object
Represents references to arbitrary objects that are defined outside the XPRESS language.
string
Represents a string of characters. Since XML syntax is used, strings always use the Unicode character set. A string value can contain no characters. Such a string is considered empty, but it is not null.
Some functions treat the values of their arguments as being logically true or false. XPRESS does not use a Boolean data type. Instead, a value of null or an integer value of zero is considered false. Any other value is considered true.
Logical functions such as eq that return a Boolean value will return the integer zero to represent false and the integer 1 to represent true.