Previous     Contents     Index     DocHome     Next     
Process Manager 6.0 (SP1) Programmer's Guide



Chapter 1   Writing Custom Activities


This chapter describes how to write and use custom activities. The sections in this document are:



Introduction

Process Manager lets you create custom activities as Java classes and bring them into your process definitions.

Custom activities are useful when you want to do more than can easily be done in an automation script, such as when the programming logic or data resides outside of Process Manager. For example, you might build a custom activity to interface with external applications and databases. Custom activities might also run local applications and then interact with mail gateways or FAX servers.


Comparison to Automated Activities

Custom activities are similar to automated activities. In both cases:

  • You place them on the process map by dragging and dropping them from the Palette.

  • They can have verification and completion scripts.

  • They are triggered as soon as the process instance reaches the activity, unless the activity is deferred. A deferred activity is triggered at its specified date and time.

Automated and custom activities have one main difference: an automated activity is carried out by an automation script, whereas a custom activity is carried out by a user-defined Java class.


Overview of Creating a Custom Activity

Creating and using a custom activity involves the following major steps:

  1. Write and compile a Java class that implements the ISimpleWorkPerformer interface.

  2. Define an XML description file for the activity.

  3. Package the Java class and the XML description file as a zip or jar file.

  4. Bring the custom activity into an application.



Implementing ISimpleWorkPerformer

The first step in creating a custom activity is to write a Java class that implements ISimpleWorkPerformer, an interface in the package com.netscape.pm.model.

ISimpleWorkPerformer defines a custom activity that:

  1. gets data field values as input

  2. performs some task

  3. sets data field values as output

Other than getting and setting data field values, your ISimpleWorkPerformer class has no access to information on the work item or the process instance. Note also that the ISimpleWorkPerformer class you create will be stateless.

Note: You can find the ISimpleWorkPerformer class in the pm60classes.jar file. If you have installed the Process Manager Builder, you can find this jar file in the directory builder-root\support\sdk. You may also be able to find it on the CD.

This section describes the following topics:


Methods of ISimpleWorkPerformer

ISimpleWorkPerformer has three methods:


The init( ) method

public void init (Hashtable environment) throws Exception

The init() method performs initialization tasks that the custom activity requires when the application starts. For example, use init() to set up database connections that are shared by all instances of the activity, or use init() to define variables that are constant across all instances of the activity.

The init() method does not execute each time a custom activity is created in a process instance. Instead, this method is called only once—when the application starts.

As its input argument, init() takes a hashtable of environment variables. A hashtable is a Hashtable object that contains a series of parameter-value pairs. The parameters in the environment hashtable are defined in the ENVIRONMENT section of an XML description file.

A process designer sets the values of the hashtable parameters while creating the process map.

For example, suppose a Language parameter is defined in the environment hashtable of a custom activity. In Process Builder, the Language parameter would appear as a property for the custom activity (you would open the Inspector window and view the Properties tab).

In your Java class, define the init() method to perform the desired initialization tasks. Then, to obtain the value of a parameter in the environment hashtable, call the get() method on the environment hashtable. The get() method returns either the value of the parameter, or null if the parameter doesn't exist.


The perform( ) method

public void perform (Hashtable in, Hashtable out) throws Exception

The perform() method executes whatever tasks must be done for the activity. This method takes two Hashtable arguments. The input hashtable contains values taken from data fields, and the output hashtable contains values to put into data fields.

The parameters in the input and output hashtables are defined in the INPUT and OUTPUT sections, respectively, of an XML description file.


The Input Hashtable
To obtain the value of a parameter in the input hashtable, call the get() method on the input hashtable. The get() method returns either the value of the parameter, or null if the parameter doesn't exist. Note that the get() method returns a Java object, so you must cast this object to the object class type that your custom activity is expecting. For example:

String sizeOrder = (String) input.get("order");


The Output Hashtable
To set data field values, the perform() method must put values into the output hashtable by calling put() on the output hashtable. When the perform() method finishes executing, you then assign the values to the corresponding data fields.


The destroy( ) method

public void destroy()

The destroy() method is called when the application that uses the custom activity is unloaded or removed. Typically, you use the destroy() method to clean up resources that were used by the init() method.


Sample Java Class

The following code samples are from HelloWorldPerformer.java, the class that implements the HelloWorld custom activity. HelloWorld is included in Process Manager as a sample custom activity, so you can view the source code directly.

HelloWorld constructs a welcome message in either French or English. The message value is derived from two things: the value of the customerName data field in the process instance, and the Language property of the HelloWorld activity instance. The HelloWorld activity puts the welcome message in the greeting data field.


Creating HelloWorldPerformer.java

Using your favorite Java editor and compiler, create and compile a Java class that implements the ISimpleWorkPerformer interface. When you use Process Builder to add a custom activity, Process Manager automatically places the custom activity's class file in the server's class path when the application is deployed.

Note. Don't define any constructors in classes implementing ISimpleWorkPerformer, because Process Manager does not use them. A Java exception will be thrown. Defining a class without any constructors is the same as defining one with just a default constructor.

Here are the steps for creating HelloWorldPerformer.java:

  1. Define a package for your class:

       package com.netscape.pm.sample;

  2. Import the required standard Java packages:


       import java.lang.*;

       import java.util.*;


  3. Define the class HelloWorldPerformer to implement com.netscape.pm.model.ISimpleWorkPerformer, as follows:


    public class HelloWorldPerformer

       implements com.netscape.pm.model.ISimpleWorkPerformer

    {


  4. Define two variables to hold the English and French parts of the greeting. Define another variable to hold the complete greeting when it has been derived (such as "Bonjour Nikki.")


    // Greeting Messages
    public static final String GREETING_FRENCH = "Bonjour";
    public static final String GREETING_ENGLISH = "Hello";

    // Holds the greeting message once the language is specified
    String mGreeting;

  5. Define the init() method to get the value of the Language environment variable and to set the language-specific part of the greeting. In addition, throw an exception if the language is not provided, or if the language is neither English nor French. For example:


    /**
    * The HelloWorld custom activity knows to generate both French
    * and English greetings. The Language argument defines which
    * language should be used.
    */

    public void init( Hashtable env ) throws Exception
    {
       String lang = (String) env.get( "language" );

       if( lang == null )
       {
             throw new Exception( "-- language not defined.") ;
       }

       else if ( lang.equalsIgnoreCase("French") )
       {
             mGreeting = GREETING_FRENCH;
       }

       else if ( lang.equalsIgnoreCase("English") )
       {
             mGreeting = GREETING_ENGLISH;
       }

       else
       {
             throw new Exception( "-- Unknown language:"+ lang +
             ". We currently support English or French--" ) ;
       }
    }


    Later, you will set the exact value of the Language environment. You'll do this in Process Builder, when you set up the custom activity in a process definition.

  6. Define the perform() method to construct a welcome message consisting of the language-specific part of the greeting and the user's name, for example "Hello Billy." The value of the userName parameter is derived later—from a data field in a process instance that uses the custom activity.

    Use the get() method on the input parameter to get the value of an input parameter.


    /**
    * Reads the userName element of the input hashtable,
    * generates greetings, and sets the Greeting element of out.
    */

    public void perform( Hashtable input, Hashtable output )
       throws Exception
    {
       // Read the userName attribute from the input hashtable
       String userName = (String) input.get( "userName" );

       if( userName == null )
       {
             throw new Exception("userName is not initialized!");
       }

       // Generate greetings
       String msg = mGreeting + " " + userName;

       /* Use the put() method on the output parameter to set
       * the value of an output parameter.
       */
       // Put the greeting into the welcomeMsg parameter of
       // the output hashtable.
       output.put( "welcomeMessage" , msg );
    }


  7. Finally, define the destroy() method, which is invoked when the application is unloaded from the application server. In this case, the method does nothing because no resource cleanup is needed.


    public void destroy( )
    {
    }
    // End of class }

  8. Compile HelloWorldPerformer.java to get a class file, HelloWorldPerformer.class.



Writing the XML Description File

After you write and compile the Java class that implements ISimpleWorkPerformer, the next step is to define an XML description file for the class. This XML file specifies the environment, input, and output parameters that the class uses. In addition, the XML file specifies some optional design parameters. Design parameters control the custom activity's appearance in Process Builder.

This section describes the following topics:


File Format

The XML description file starts with a tag indicating the XML version, such as:

   <?XML version = "1.0" ?>

The body of the description is contained between an opening <WORKPERFORMER> tag and a closing </WORKPERFORMER> tag. Within the WORKPERFORMER section you define four sections, as summarized in the following table.


ENVIRONMENT

Environment hashtable used by init() method.

INPUT

Input hashtable used by perform() method.

OUTPUT

Output hashtable used by perform() method.

DESIGN

Appearance of custom activity icons in Process Builder.


Here is the structural overview of an XML description file:


<?XML version = "1.0" ?>
<WORKPERFORMER >
<ENVIRONMENT>
   <PARAMETER> ... </PARAMETER> ...
</ENVIRONMENT>
<INPUT>
   <PARAMETER> ... </PARAMETER> ...
</INPUT>
<OUTPUT>
   <PARAMETER> ... </PARAMETER> ...
</OUTPUT>
<DESIGN>
   <PARAMETER> ... </PARAMETER> ...
</DESIGN>
</WORKPERFORMER>


WORKPERFORMER Tag

The <WORKPERFORMER> tag has four attributes: TYPE, NAME, CLASS_ID, and VERSION.

  • TYPE is the full package name for the Java class for this type of activity. For a simple custom activity, TYPE is always this:

       com.netscape.pm.model.ISimpleWorkPerformer

  • NAME is the name of the custom activity (which is the same as the name of the XML description file and the jar file that contains the custom activity). This name is not currently used anywhere.

  • CLASS_ID is the full package name for the Java class that implements the custom activity.

  • VERSION is the version of the custom activity. VERSION is currently unused, but you could use it to keep version information about the description file.

Here is a sample <WORKPERFORMER> tag:


<WORKPERFORMER
   TYPE="com.netscape.pm.model.ISimpleWorkPerformer"
   NAME="HelloWorld"
   CLASS_ID="com.netscape.pm.sample.HelloWorldPerformer"
   VERSION="1.1">


ENVIRONMENT Section

The <ENVIRONMENT> tag defines environment parameters that are constant within all instances of the custom activity. For example, suppose that in an application named HelloWorld, you set the value of the Language environment parameter to French. Then, the value is always French in every process instance of that application.

The ENVIRONMENT section contains embedded <PARAMETER> tags. Each <PARAMETER> tag describes a parameter in the environment hashtable—the argument used by the init() method. The <ENVIRONMENT> tag has a corresponding closing </ENVIRONMENT> tag , and each <PARAMETER> tag has a closing </PARAMETER> tag.

When you add the custom activity to the process map in Process Builder, each parameter in the <ENVIRONMENT> tag appears as a field in the Inspector Window.

Here's a sample ENVIRONMENT section:


<ENVIRONMENT>
   <PARAMETER NAME="Language">"French"</PARAMETER>
</ENVIRONMENT>

Warning. Parameter values (such as "French" in the example above) are actually JavaScript expressions, so you can supply the value as a string, integer, or function. However, be sure to quote any string expression. Note that French (without quotes) and "French" (with quotes) mean different things.

For details on the syntax of the <PARAMETER> tag, see the section "PARAMETER Tag".


INPUT Section

The <INPUT> tag contains embedded <PARAMETER> tags. Each <PARAMETER> tag describes a parameter in the input hashtable, the input argument of the perform() method. The<INPUT> tag has a corresponding closing </INPUT> tag , and each <PARAMETER> tag has a closing </PARAMETER> tag.

To set the value of the parameter to the value of a data field in the process instance, embed a call to getData() in the <PARAMETER> tag. For example, the following code sets the value of the userName parameter in the input hashtable to the value of the customerName data field in the process instance.


<INPUT>
   <PARAMETER
         NAME="userName"
         DISPLAYNAME="User Name"
         TYPE="java.lang.String"
         DESCRIPTION="Last Name">
   getData("customerName")
   </PARAMETER>
</INPUT>

For details on the syntax of the <PARAMETER> tag, see the section "PARAMETER Tag".

The corresponding code in your Java class file uses the perform() method to get the value of the userName parameter. Within the perform() method, you call the get() method. Here is a code fragment:


public void perform( Hashtable input, Hashtable output )
   throws Exception
{
   // Read the userName attribute from the input hashtable
   String userName = (String) input.get( "userName" );
   
   if( userName == null )
   {
          throw new Exception("userName is not initialized!");
   }
   
   // Generate greetings
   String msg = mGreeting + " " + userName;



OUTPUT Section

The <OUTPUT> tag contains embedded <PARAMETER> tags. Each <PARAMETER> tag describes a parameter in the output hashtable, the output argument of the perform() method. The <OUTPUT> tag has a corresponding closing </OUTPUT> tag, and each <PARAMETER> tag has a closing </PARAMETER> tag.

The output hashtable contains parameters whose values will be automatically installed in data fields in the process instance. For each parameter, embed a call to mapTo() to indicate which data field in the process instance is to receive the value of the parameter.

For example, the following code specifies that when the perform() method has finished executing, the value of the welcomeMsg parameter in the output hashtable is automatically installed in the greeting data field in the process instance.


<OUTPUT>
   <PARAMETER
         NAME="welcomeMsg"
         DISPLAYNAME="Welcome Message"
         TYPE="java.lang.String"
         DESCRIPTION="Greeting for the user">
   mapTo("greeting")
   </PARAMETER>
</OUTPUT>

For details on the syntax of the <PARAMETER> tag, see the section "PARAMETER Tag".

The corresponding code in your Java class file uses the perform() method to put a value in the welcomeMsg parameter of the output hashtable. Within the perform() method, call the put() method:

output.put( "welcomeMessage" , msg );


PARAMETER Tag

The <PARAMETER> tag has the attributes as summarized in the following table. When you define parameters within the DESIGN section of the XML description file, only the NAME and DESCRIPTION attributes apply. However, within the ENVIRONMENT, INPUT, or OUTPUT sections, all of the attributes apply.

Attribute

Meaning

NAME

Name of the parameter.

DESCRIPTION

The text for the tool tip (also called bubble help) that appears when you place the mouse over the item in Process Builder.

TYPE

The Java object class of the parameter. This attribute is optional. The value can be given as a complete class name, such as java.lang.String or com.netscape.pm.ShoppingCart.

VALUESET

A comma-delimited list of possible values for this parameter. These values appear as a pop up menu in the Inspector Window. This attribute is optional.

EDITOR

The type of editor window to use. For example, use this attribute to set a Browse button, text area, drop down list, dialog box. This attribute is optional.

EDITABLE

A boolean that determines whether the parameter value can be edited in the Inspector Window. The default is true. This attribute is optional.


DESIGN Section

The <DESIGN> tag contains embedded <PARAMETER> tags. The <DESIGN> tag has a corresponding closing </DESIGN> tag, and each <PARAMETER> tag has a closing </PARAMETER> tag.

Use the DESIGN section to define the custom activity's user interface within Process Builder. In the DESIGN section, the <PARAMETER> tag accepts two attributes: NAME and DESCRIPTION.

By setting the NAME attribute, you define a particular aspect of the custom activity's user interface. The following table summarizes the available values for the NAME attribute:

NAME Attribute

Meaning

Icon

The image file to use for the icon in the custom palette.

Label

A text label that appears under the icon.

BubbleHelp

The text for the tool tip that appears when the mouse pointer is over the icon.

HelpUrl

The URL for the online help for this custom activity, accessible from a right-click.

MapIcon

The image file to use for the icon in the process map. In typical usage, this is the same as Icon.

SelectedMapIcon

The image file to use for the icon in the process map, when the activity is selected.

TreeViewIcon

The file to use for a small image that represents the activity in the Application Tree View.


Sample XML Description File

The following code defines a file called HelloWorld.xml . Things to note are:

  • This file specifies userName as a parameter in the input hash table. However, the value of this parameter is obtained from the customerName data field in the process instance.

  • Similarly, the file specifies welcomeMsg as a parameter in the output hashtable, and maps its value back into the greeting data field in the process instance.

Here is the entire code for the HelloWorld.xml description file:


<?XML version = "1.0" ?>
<WORKPERFORMER
   TYPE="com.netscape.pm.model.ISimpleWorkPerformer"
   NAME="HelloWorld"
   CLASS_ID="com.netscape.pm.sample.HelloWorldPerformer"
   VERSION="1.1">
<ENVIRONMENT>
   <PARAMETER
      NAME="Language"
      VALUESET="'English','French'"
      TYPE="java.lang.String">
   'English'
   </PARAMETER>
</ENVIRONMENT>

<INPUT>
   <PARAMETER
      NAME="userName"
      DISPLAYNAME="User Name"
      TYPE="java.lang.String"
      DESCRIPTION="Last Name">
   getData("customerName")
   </PARAMETER>
</INPUT>
<OUTPUT>
   <PARAMETER
      NAME="welcomeMsg"
      DISPLAYNAME="Welcome Message"
      TYPE="java.lang.String"
      DESCRIPTION="Greeting for the user">
   mapTo("greeting")
   </PARAMETER>
</OUTPUT>

<DESIGN>
   <PARAMETER
      NAME="Icon"
      DESCRIPTION="A 32x32 icon that is placed on the palette">
      drap_uk2.gif
   </PARAMETER>
   <PARAMETER
      NAME="Label"
      DESCRIPTION="The DISPLAYNAME for this palette element.">
   Hello World
   </PARAMETER>

   <PARAMETER
      NAME="BubbleHelp"
      DESCRIPTION="Bubble help for the palette element">
   HelloWorld - A simple work performer Custom Activity.
   </PARAMETER>

   <PARAMETER
      NAME="HelpURL"
      DESCRIPTION="URL explaing this palette element">
   http://people.netscape.com/michal/
   </PARAMETER>

   <PARAMETER
      NAME="MapIcon"
      DESCRIPTION="Icon for the process map (48x48)">
   drap_uk2.gif
   </PARAMETER>

   <PARAMETER
      NAME="SelectedMapIcon"
      DESCRIPTION="Icon for the process map (48x48)">
   drap_fr2.gif
   </PARAMETER>

   <PARAMETER
      NAME="TreeViewIcon"
      DESCRIPTION="Icon for the tree view (48x48)">
   mailer_tree_view.gif
   </PARAMETER>
</DESIGN>
</WORKPERFORMER>



Packaging a Custom Activity



After you create the Java class file and the XML description file, the next step is to package the custom activity. A custom activity consists of the following files:

  • One or more Java classes. At least one of these classes must implement ISimpleWorkPerformer.

  • An XML description file.

  • Optional image files to use as icons in Process Builder.

Create a zip or jar archive that contains these files. The archive must have the same root name as the XML file. For example, if the XML file is HelloWorld.xml, then name the zip file HelloWorld.zip.

As you create the archive, check that the directory structure reflects the package structure of the class. For example, the HelloWorldPerformer class is in the package com.netscape.pm.sample. Therefore, the class file must be in the directory com/netscape/pm/sample, as shown in Figure 1-1. The HelloWorld.xml file must be at the top level.

Figure 1-1    Directory structure for the HelloWorld activity


Note the two image files, drap_fr2.gif and drap_uk2.gif. These images will be used by Process Builder in the process map. The images, shown in Figure 1-2, will correspond to the selected state of the Language property, either French or English.

Figure 1-2    Image files in the HelloWorld activity




Adding a Custom Activity to the Process Map



There are two ways to add a custom activity to the process map:

  • In one case you create a custom palette. This approach is useful if you intend to use a custom activity often, either within a single application or across several applications.

  • In the other case, you don't create a custom palette, and you simply use the Custom Activity icon provided with Process Builder. This approach might be better if you rarely use custom activities, and you don't want to create a custom palette for them.


Adding a Custom Activity from a Custom Palette

To use a custom activity from a custom palette, do the following:

  1. In the palette, right-click the area below the title bar, and choose "Add custom palette," as shown in Figure 1-3. This adds a new tab to the palette.

Figure 1-3    Adding a custom palette


  1. In the "New palette name" dialog box (shown in Figure 1-4), type the label for the new tab. For example, enter "HelloWorld".

Figure 1-4    Enter a name for the new palette


A new tab is added to the palette.

  1. Click your new custom tab to make it active. Note that the area contains no icons.

  2. Right-click in the empty area under the tabs, and select "Add Custom Activity ...". See Figure 1-5.

Figure 1-5    Add a custom activity to the palette


A file selection window appears.

  1. Using the file selection window, locate the archive file that represents the custom activity, and select the file. For example, Figure 1-6 show the selection of HelloWorld.zip:

Figure 1-6    Select the file that represents a custom activity


The custom activity is added to your new palette. For example, as shown in Figure 1-7, the HelloWorld activity appears on the palette like this:

Figure 1-7    A custom activity icon appearing on the HelloWorld custom palette


Note that the custom activity's appearance in Process Builder is controlled by the DESIGN section of the XML file. In the HelloWorld tab pictured above, you see the effects of setting the Icon, Label, and BubbleHelp parameters in the DESIGN section.

  1. To add the activity to your application, drag the icon from the custom palette to the process map.


Adding a Custom Activity without Using a Custom Palette

If you don't have a custom palette icon or don't want to create one, you can add a custom activity as follows:

  1. In the palette, drag the Custom Activity icon

    to the process map.

  2. Select the custom activity and open the Inspector window.

  3. On the Properties tab of the Inspector, locate the property named Custom Activity.

  4. Click the Browse button to bring up a file selection window, and locate the zip or jar file that represents the custom activity. An example is shown in Figure 1-8.

Figure 1-8    Setting the Custom Activity property


  1. Click Open to associate the selected file with the Custom Activity icon. The Custom Activity icon now has the characteristics defined by the file.



Working with a Custom Activity

After you place a custom activity on the process map, you can view or set its properties in the Inspector window. For example, Figure 1-9 shows the Inspector window's Input tab for HelloWorld.

Figure 1-9    Input properties for a custom activity


The Input tab shows the parameter names in the input hashtable, and shows how the value for each parameter is derived. In this case, the value for the input parameter userName is derived by getting the value of the customerName datafield.

The INPUT section of the XML description file determines the appearance of the Input tab in the Inspector window. For example, note that the userName parameter displays as "User Name," which was specified through the DISPLAYNAME attribute in the XML file.

Similarly, the Output tab shows the parameter names in the output hashtable, and shows how the value for each parameter is mapped back into the process instance. In this case, the value for the output parameter welcomeMsg is put in the greeting data field.

As you design the process, be sure to add the data fields that are used by the custom activity. For example, the HelloWorld activity uses two Textfields: greeting and customerName.



Implementation Tips



This section describes some design tips you should consider as you create and implement a custom activity.


Avoid Instance Data

A custom activity, like a custom data field, is a stateless entity. In effect, there is only one copy of each occurrence of a custom activity per application. All the process instances in an application effectively share the same custom activity instance for each occurrence of the custom activity class in the application. Because of this, it's recommended that you avoid using instance data in a class that implements a custom activity, particularly if the perform() method is likely to change this data. If you can't avoid using instance data, be sure to synchronize the data. With unsynchronized data, a variable set during one request might not exist for the next request.

For example, consider an application that employees use to request vacation days. Let's suppose this application has a custom activity that updates the corporate database with the new vacation balance.

The following code, which uses an instance variable called vacationBalance, shows how NOT to implement the custom activity:


// This is the WRONG way to implement a custom activity!!

public class RequestVacationPerformer
   implements com.netscape.pm.model.ISimpleWorkPerformer
{

int vacationBalance;

public void init (Hashtable environment) throws Exception
{
   ...
   // Get the employee's vacation balance from the database
   // Store it temporarily as instance data
   vacationBalance = getVacBalance(employeeID);
   ...
}

public void perform( Hashtable input, Hashtable output )
   throws Exception
{
   // Read the employee ID attribute from the input hashtable
   String employeeUD = (String) input.get( "employeeID" );

   // Get the num of requested vac days from the input hash table
   String vacRequested = (String) input.get("vacDaysRequested");

   // Update the vacationBalance instance variable
   vacationBalance = vacationBalance - vacationRequested;

   // Change the vacation balance in the database
   updateVacationInfo(employeeID, vacationBalance)
   ....


Fred is the first person to request a vacation using this Process Manager application and he wants to go river rafting for 2 days. Fred's init() method gets his vacation balance, which is 3 days, (Fred has already been scuba diving in Hawaii this year) and stores it in the vacationBalance instance variable. Fred's perform() method calculates his updated vacation balance, which is 1 day, and stores it in the vacationBalance instance variable.

Now Bob comes online and requests a vacation of 8 days. Bob has been saving his vacation days for a long time for his dream trip to climb Everest. However, since the application has already been initialized, init() does not run again. Bob's perform() method ends up accessing the vacationBalance that was set by Fred's perform() method, thus Bob ends up having a vacation balance of only 1 day, which is hardly enough time to fly to Nepal, let alone climb Everest and fly home again.

It is OK to use instance variables for data that is constant across all occurrences of a custom activity within an application. For example, the custom activity in the vacation request application might use a global variable that represents the number of company holidays per year. This number does not change from employee to employee, so it is OK to store this as an instance variable.

Another example of a situation where it is OK to use instance variables is if the custom activity needs the iAS engine context to call out to a connector such as an SAP connector. In this case, you could set the context inside init() and then re-use it inside perform(). The key thing to remember is that objects such as the context are considered to be immutable and hence will only be used, not changed, inside perform().

An application can contain multiple occurrences of a custom activity class. For example, an application might have custom activities called CheckVacationBalance and CheckVacationAccrual, which are both instances of the CheckVacationInfo custom activity class. When the application is running, these two activities operate completely independently. If the activities use instance data, that data would not be shared between them. For example, if the activities use an instance variable called DBTableName, the CheckVacationBalance instance could set it to VacBalTable while the CheckVacationAccrual could set it to VacAccTable, and there would be no confusion between the two.


Use Consistent Data Types

Watch for consistent data typing. Make sure that the data types you specify in the XML file are consistent with the corresponding values you pass to the input and output hashtables. Although Process Manager performs some basic data matching for you, inconsistent data is likely to generate an error.


Avoid Non-default Constructors

In classes that implement ISimpleWorkPerformer, avoid defining non-default constructors (meaning constructors with non-zero arguments). Otherwise, you may encounter problems during dynamic loading. The problem may arise because Process Manager dynamically loads the class that implements your custom activity. In other words, Process Manager has no prior awareness of non-default constructors and therefore cannot call them.


When to Use a Custom Activity

Custom activities are useful when you want to integrate an existing legacy process into a Process Manager process through a well-defined interface. For example, use a custom activity in a Process Manager process that exchanges data with external resources such as a CORBA server, a CICS system, or the business logic in an EJB component.

By contrast, custom activities are not a good solution if you must represent a complex data structure from an external source. For example, to represent result sets or other data types from Oracle databases or SAP R/3 systems, you are better off using a custom field. Reserve custom activities for situations where data can be easily parsed and stored (either directly in a data field or in the content store).



Example Custom Activity



The AdvancedOfficeSetup sample application that ships with the Process Builder includes an example of a custom activity.

The AdvancedOfficeSetup application has a custom activity that automatically schedules a new employee to attend a company orientation training.

The day of the training depends on which department the employee is joining and what day they start work at the company. For more details, see Chapter 3 "Advanced Office Setup Application."


Previous     Contents     Index     DocHome     Next     
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.

Last Updated November 02, 2000