Previous Contents Index DocHome Next |
iPlanet Process Manager 6.0 (SP2) Process Builder's Guide |
Chapter 11 Advanced Techniques for Scripting
This chapter describes how to write your own scripts for use with Process Builder.This chapter has the following sections:
Introduction
Getting Information about the Current Process
Getting Information about Users and their Attributes
Logging Error and Informational Messages
Introduction
When writing a Process Manager script, consider the types of information your script will use. Process Manager scripts can use the following sources of information:
Information about the process in progress.
Information about the work item in progress.
- This data is stored in Process Manager's database, and is available through the processInstance object. This information includes data such as the date the process instance was created and the current value of fields such as the specialDiscount field.
Information about users.
- Information about the current work item is available through the workItem object. This information includes data such as the user to whom the work item is assigned.
Items stored in the content store.
- This information is stored in the Directory Server, and is available through the corporateDirectory object, discussed in Getting Information about Users and their Attributes. This data includes information about users, such as the assignee's address or the name of their manager.
- Scripts can access items stored in the content store by using the contentStore object (discussed in Accessing the Content Store).
Getting Information about the Current Process
Process Manager provides two JavaScript objects, processInstance and workItem, that scripts can use to access information about the process in progress:
processInstance holds information about the process instance in general, such as its creation date and the current values of any data fields. Scripts can use the global function getProcessInstance() to get the object. Scripts can then call methods on the processInstance to get and set data relevant to the process instance.
See Appendix , JavaScript API Reference for details on these methods.workItem holds information about the current work item, such as its assignee and its expiration date. Scripts can use the global function getWorkItem() to get the object. Scripts can then call methods on the workItem object to get and set data relevant to the work item.
Getting and Setting Data Field Values
When a user submits a form for a work item, the value of each data field in the form is put into the corresponding data field in Process Manager's database. For example, if the user sets the value of the field documentName to Jo Writer then when the form is submitted the field documentName in Process Manager's database gets the value "Jo Writer". (You could think of the field in the form as being a window to the field in the database.)There are several ways to verify the data that users enter in the form fields, as discussed in Verifying Form Input.
Scripts can use the following methods on the processInstance object to get and set data field values:
getData (fieldName)
The following function is an example of a completion script that gets and sets field values:
setData (fieldName, fieldValue)
- This method returns the value of the named field.
- This method sets the value of the named field to the given value. This method is particularly useful for setting values in automation scripts.
Getting Data Field Values in Decision Point and Automation Script Transitions
The value of a condition for a decision point or an automated script can be any expression that returns true or false.These expressions can use a shorthand notation to refer to field values by simply using the name of the field. For example:
getProcessInstance().getData("item_price") < 100
This expression evaluates to true if the value of the item_price field is less than 100, otherwise it evaluates to false.
Note that only scripts used in conditions can use this shorthand for accessing data fields.
Getting Information about Users and their Attributes
Scripts can use the global function getCorporateDirectory() to get an object that represents the corporate directory in the Directory Server that Process Manager uses.The Directory Server contains a database of users and their attributes, such as their distinguished name, their common name, their phone number, their address, their email address, and so on. Given the corporateDirectory object, scripts can get information about the users in the corporate directory.
Finding Users and Accessing their Attributes
The corporateDirectory object has three methods that allow scripts to search for users in the corporate directory:These methods all return a JavaScript object that represents the user if they can be found; otherwise the methods return null. The object has variables for all the user's attributes. See Appendix , JavaScript API Reference for details.
Scripts can also use the following two methods on the processInstance object to get user attributes from the Directory Server:
getCreatorUser() returns a JavaScript object containing the attributes of the user that created the process instance.
For example, the following assignment script assigns the work item to the user whose user id is the value of the peerReviewerID attribute of the person who created the process instance.getRoleUser(roleName) returns a JavaScript object containing the attributes of the user assigned to the given role.
Note that this script works only if the peerReviewerID attribute is defined in the Directory Server and is initialized for the creator user.
Modifying User Attributes
The corporateDirectory object has the following methods for adding, replacing, or deleting user attribute values in the Directory Server:
modifyUserById (userID, attrName, attrValue, operation)
These methods specify the user either by ID or common name as appropriate. The attrName parameter is the name of the attribute to be modified. If operation is ADD, the value attrValue is added to any existing values. If operation is REPLACE, all existing values are replace by attrValue. If operation is DELETE, then attrValue is deleted from the attribute. The functions return true if the operation is successful, otherwise they return false.For example, the following code puts the value nikki@company.com to the mail attribute of the user whose common name is Nikki Beckwell:
var corpdir = getCorporateDirectory();
corpdir.modifyUserByCN ("Nikki Beckwell", "mail", "nikki@company.com", "REPLACE");
Although scripts can modify attribute values, they cannot create attributes that have not already been defined in the Directory Server schema.
Adding and Deleting Users
The corporateDirectory object has the following methods for adding and deleting users to the corporate directory:
deleteUserByCN (userCN)
See Appendix AJavaScript API Reference for details.
Accessing the Content Store
Scripts can use the global function getContentStore() to get a contentStore connected to the content store for the process.The following global function is useful for constructing a file name when you want to add an item to the object store:
getBaseForFileName() returns the folder name that the current process instance uses to contain its stored content.
For more information about methods on the content store, see Appendix , JavaScript API Reference
Example of Accessing a Stored Item
For an example of accessing the content store, consider a process that writers use for submitting documents for review. Before starting the process, the writer must create a file containing a synopsis of the document.The entry point form contains a File data field named docDescription. The writer selects a file containing the document synopsis and uploads it by pressing the File icon in the form. The next activity after the entry point is an automated activity that uses the following automation script. This script gets the document synopsis by getting the content of the file that the writer selected. The script then puts the synopsis into the docSynopsis TextArea datafield. The intention here is that the next form in the process displays the synopsis to the users assigned to review the document.
Note. This script requires that the content store URL defined for the application is a valid URL, such as:
If the content store URL is not defined correctly, the store() method will not work.
Storing Files in the Content Store
Each Process Engine uses a series of directories named part0, part1, part2 and so on to contain items in the object store. Each process instance has a unique identity, such as pi0001. Each process instance uses a partn subdirectory to store all its content. For example, all the stored files associated with process instance pi0001 would be stored in PM_root/part0/pi0001. When part0 gets full, the Process Engine starts using part1, and so on.When a script needs to save content to the content store, it can use the getBaseForFileName() function to get the pathname for the content store directory for the current process instance. The script can then use the store() method on the contentStore object to save content to a file in the correct content store directory for the current process instance.
For example, the following automation script code creates a path name for the file myNewFile.html in the content store, then saves some content to a new file in the content store.
Logging Error and Informational Messages
Process Manager provides several global functions for providing messages. Scripts can use these functions to log error messages, to add entries to the history log, and to add informational messages for the user when a script fails.For more information about these global functions, see Appendix , JavaScript API Reference
Verifying Form Input
This section has the following subsection:
Verifying Form Input with Client-Side JavaScript
When you create a form in Process Builder, you place data fields on it. If the data field is in edit mode, it displays the current value, if any, and allows the user to modify the value. If a data field is in view mode, it displays the value of the field but does not allow the user to change it.When the user submits the form by pressing an action button, the values in the data fields in the form are put in the fields in the process instance's table in the database. By default, Process Manager verifies that the data entered in each field is the correct type, and if there are obvious errors, it rejects the work item or entry point and displays a warning dialog box. For example, if the user enters the string value "whenever" into a data field whose type is Date, Process Manager catches the error and rejects the work item. (Note however that the Date verification is not very strict, if the user enters 6666/7777/8 as a Date, Process Manager accepts it.)
There will be times when your form needs to perform additional data verification, such as checking that a number falls within a certain range of numbers. Process Manager provides the following way to verify that users enter valid data for a field:
use client-side JavaScript scripts to define onClick or onValueChange properties for those data fields that have them, or to define onSubmitForm scripts.
Using client-side scripts to check data field values allows you to write scripts that give the user a chance to fix the values before the form is submitted.If the data verification occurs in a completion script, then if the script fails the result is that the form disappears and the process is routed to an exception node.
Verifying Form Input with Client-Side JavaScript
Process Builder provides two ways to write client-side scripts to verify form input:
using an embedded script that defines an onSubmitForm function that gets invoked when the form is submitted.
For every data field represented in a form, the form contains a form element that has exactly the same name as the data field. Client-side scripts can access data field values as they are currently displayed in the form. The scripts do this by accessing form elements that have the same name as the data field.using onValueChange and onClick event handlers for specific form elements.
If the form contains an embedded client-side script that defines an onSubmitForm function, that function is invoked when the user presses an action button on the form. You can define an onSubmitForm function to check values of form elements and offer the user a chance to enter new values in cases where the current values are invalid. If the onSubmitForm function returns false, the form is not submitted. See the section onSubmitForm Example for a coded example of an onSubmitForm function.
You can also define client-side scripts to check the value of individual form elements. Some data fields have an onClick or onValueChange property. The value of this property is a JavaScript expression. These properties correspond to event handlers in the associated form elements. For information about form elements, see the "Forms" chapter in the HTML Tag Reference at:
http://developer.netscape.com/docs/manuals/htmlguid/index.htm
The onClick script is fired when the form element is clicked. For elements whose value is changed by clicking, such as radio buttons, the onValueChange script behaves just like an onClick script, and is fired whenever the user clicks the form element. For other elements, such as text fields, the onValueChange script is fired when the form element loses focus after its value has changed, which usually happens when the user presses the return key or clicks elsewhere in the form. To see exactly which data fields have onClick and onValueChange scripts, see the properties for the different kinds of data fields in Process Builder.
You can define onClick, onValueChange, and onSubmitForm scripts that display an alert box or a confirm box to warn the user that an invalid value has been entered. Use the alert() function to display an alert box, and use the confirm() function to display a confirm box.
To obtain information about JavaScript errors, enter the URL javascript: in your version of Netscape Communicator.
Event Handler Example
The following onValueChange script for a text field checks if the value of the text field is a number. If the value is not a number, it displays a dialog box with a warning and resets the page count value to 100 in case the user ignores the warning. If the value is a number, it does nothing. (Note that in event handlers, such as in client-side scripts, you must use single quotes instead of double quotes.)
var pageCountNum = parseInt (value);
if (isNaN (pageCountNum)) {
alert ('You must enter a number as the page count');
value = 100;
}Figure 11-1 shows the definition of this onValueChange event handler in the Inspector window in Process Builder.
Figure 11-1    A definition for an onValueChange event handler ![]()
Figure 11-2 shows a sample alert window in Process Express:
Figure 11-2    A sample alert window in Process Express ![]()
This script can be used directly as the value of the onValueChange property of the text field. The script uses parseInt() to convert the value of the text field from a string to a number. The value argument to the parseInt function is the name of a property of the text field. Since this script is used directly in the text field object, there is no need to say this.value, although the script would also work if written as:
var pageCountNum = parseInt (this.value);
For information about the parseInt() method, see Chapter 13, Global Functions in the JavaScript reference at:
http://developer.netscape.com/docs/manuals/communicator/jsref/
onSubmitForm Example
The following example shows an embedded client-side script that defines an onSubmitForm function. In this case, the script checks that the value entered in the daysForReview form element is a number. If not, the script displays a warning dialog box, sets the value of the daysForReview form element to 10, and returns false to give the user a chance to change the value and submit the form again.
Figure 11-3 shows an embedded client-side script that defines an onSubmitForm function in Process Builder:
Figure 11-3    A script that defines an onSubmitForm function ![]()
Verifying Form Data in Completion Scripts
When the user presses an action button to submit a form, the values of the data fields on the form are installed into the global processInstance object. When the completion script runs, it can access data field values by using the getData() method of the global processInstance object. However, if the completion script fails, the newly installed values are removed from the process instance, the previous values are re-installed and the process is routed to an exception node.
Initializing and Shutting Down Applications
When defining a process definition, you can write initialisation and shutdown scripts for the application. The initialisation script is invoked when the application first starts, and the shutdown script is invoked when the application is shut down. Note that the initialization and shutdown scripts are not invoked each time a process instance starts or finishes, but only when the application starts or finishes. The application lifespan (start to finish) is defined within the scope of each Java engine running within the application server. Therefore, the initialization scripts are invoked on a per-engine basis.Initialization scripts and shutdown script are not associated with individual process instances, therefore they cannot use processInstance or workItem objects. They can however use the methods on the contentStore object. For example, the initialisation script could use the store() method on the contentStore object to create a file that can be accessed by all process instances in the application.
You can use the initialization script to perform tasks that need to be done once in the lifetime of the application, such as creating files or initiating connections to be shared by all process instances.
The shutdown script should close any connections that were opened in the initialization script. Other uses for a shutdown script include cleaning up external database tables, sending email to the administrator, releasing other resources, and performing any tasks that need to be done when the application is shut down.
Debugging Hints
To check for syntax errors in your scripts, enter javascript: as your URL. In addition, this section provides hints on debugging and troubleshooting scripts. It has the following subsections:
Displaying the Progress of a Script
There are several global functions for printing messages that are very useful for debugging scripts. The logErrorMsg() function adds an entry to the error log. The logInfoMsg() function adds an entry to the informational log. The logSecurityMsg() function adds an entry to the security log.To view these logs, go to the Process Administrator page (Administrator.apm). For example, if Process Manager is installed at pm.company.com, go to:
pm.company.com/Administrator.apm/
This page displays Process Administrator. Select the Applications tab (if it is not already selected) to see the list of applications. Select View Logs from the pop up menu for the application of interest, then press the Apply button. You may need to enter your user name and password to gain access to Process Manager and the Enterprise Server.
When the View Logs Server Selector window appears, select the desired cluster, then press the View Log File button. In the View Application Logs window that appears, you can select the Error, Security, or Information log. After making your selection, press the View Log button.
Testing Expiration Setter and Handler Scripts
When Process Express displays work items in the work item list, it shows the expiration date for each work item. To test an expiration setter script, simply deploy the application and test it out. Check the expiration date for the relevant work item in the work item list in Process Express. For example, Figure 11-4 shows the due date in Process Express.
Figure 11-4    Testing a due date ![]()
At regular intervals (about once every minute) Process Manager tests for expired work items by comparing the expiration date and time of every work item to the current time. If the expiration time has passed for any work item, Process Manager invokes the work item's expiration handler script if it has one.
If your expiration handler re-assigns the work item, you should view the details and history for the process instance to check if the re-assignment worked in test mode. The title of the process does not change in test mode even if the assignee changes.
Sample Scripts
This section gives an example of the following kinds of scripts:
Assignment Script
The following assignment script assumes that the process instance has data fields reviewer1 and reviewer2 that contain the user IDs for two reviewers. If one or both of the reviewer1 and reviewer2 fields contain user IDs for valid users, the work item is assigned to the valid named reviewers. Otherwise it is assigned to the process instance creator.The default value for the reviewer1 and reviewer2 fields is an empty string. The script checks that the reviewers exist as users in the corporate directory, and if so, assigns the work item to them. If the array does not contain valid user IDS, the function assigns the work item to the creator of the process instance.
Expiration Setter Script
This expiration setter script gets the value of the pageCount field and uses it to determine whether reviewers need a long or short review period. If the page count is greater than 100, the review period is long (14 days), otherwise the page count is short (7 days).
Expiration Handler Script
This expiration handler script reassigns the work item to the creator.
Completion Script
The following completion script checks that the value of the pageCount data field is a number between 1 and 3000 inclusive. If the pageCount is too high, too low, or is not a number, the completion script logs an error message and returns false. The process instance is then routed to the appropriate exception node.
Automation Script
This script updates a link to a newly submitted document in a file that lists all documents available for review.This script could be used as an automation script in a process that enables writers to submit documents for review. In the entry point form, the writer uses a File attachment data field called docFileName to attach the document. Many different writers can use the application to submit documents. The file docList.html contains an active link for every document that has been submitted with this application. The file docList.html lives in the top level of the content store so that all process instances in the application can access it.
Two files are involved in the document list. The file docList.html is an HTML-formatted list of the documents with an active link for each document. The file showList.html contains opening HTML tags, the list of documents (which is the same as docList.html), and closing HTML tags. This script uses two files so that it can add the closing HTML tags after adding the information for the newly submitted document.
Figure 11-5 illustrates the showList.html web page. This page is updated each time a document is submitted for review.
Figure 11-5    A web page that is updated automatically ![]()
Previous Contents Index DocHome Next
Copyright © 2001 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated March 13, 2001