bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming BPM Plug-Ins

Defining Plug-In Components

This section explains how to define plug-in components. It includes the following topics:

- Overview

- PluginObject Interface

- Reading and Saving Plug-In Data

- Displaying the Plug-In GUI Component

- Executing the Plug-In

- Using Plug-In Run-Time Contexts

- Defining the Plug-In Component Value Objects

Overview

As described in How BPM Discovers a Deployed Plug-In, the plug-in is responsible for enabling the BPM to:

- Access the plug-in implementation to read, display, and save the plug-in within the design client

- Execute the plug-in

This functionality is provided by the plug-in component. The following table describes the plug-in component requirements for supporting the specified functionality.

Table 4-1 Plug-In Component Requirements

To enable the BPM to . . .

You must . . .

Read (parse) and save plug-in data in XML format

Implement the plug-in data interface.

For example, see EventNodeData.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory of the plug-in sample.

Display the plug-in GUI component within the design client

Define the plug-in panel class.

For example, see EventNodePanel.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory of the plug-in sample.

Execute the plug-in

Define the run-time component class.

For example, see EventNode.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory of the plug-in sample.

To enable the plug-in to read (parse) incoming data, both the plug-in data interface and run-time component class must implement the load() (parsing) method of their parent interface, com.bea.wlpi.common.plugin.PluginObject.

Lastly, you must define the plug-in component value object to describe the component data.

The following sections describe the PluginObject interface, explain how to define the plug-in component to support the functionality listed in the previous table, and define the plug-in component value object.

Note: For a summary of the steps that must be accomplished to define each type of plug-in component, see Plug-In Component Definition Roadmap.

PluginObject Interface

The com.bea.wlpi.common.plugin.PluginObject interface enables the plug-in to read (parse) the plug-in data.

This interface must be extended by:

- Plug-in data interface described in Reading and Saving Plug-In Data

- Run-time component class described in Executing the Plug-In

The PluginObject interface defines one method, load(), as shown in the following table.

Table 4-2 PluginObject Interface Method

Method | Description
--- | ---
public void load(org.xml.sax.XMLReader parser) | Notifies the plug-in to prepare to load its data from an XML document. The method parameter is defined as follows. parser: org.xml.sax.XMLReader object that specifies a valid SAX parser. To use multiple content handlers while parsing data (useful when parsing deeply nested elements , the plug-in can save this value and call the setContentHandler() method on the specified parser object.

The Plug-in Manager calls the load() method when it encounters the plug-in section (for example, a <plugin-data> element) in an XML document. This might happen, for example, when the Plug-in Manager opens a template, template definition, or plug-in configuration XML document in the WebLogic Integration Studio.

Note: For information about the BPM DTDs, see DTD Formats in Programming BPM Client Applications.

You must also implement required content handler methods, including the startElement() and endElement() methods. The Plug-in Manager sets the plug-in as the parser content handler, and uses the startElement() and endElement() methods as the first and last calls to the content handler when a <plugin-data> element is reached. The content handler uses the intervening SAX notifications to store the plug-in-specific data. For more information about the content handler methods, see the org.xml.sax Javadoc.

In the plug-in sample, a separate class file is provided for certain plug-in components that extends the PluginObject interface and defines the required methods. This file does not need to be defined separately. It is useful in this case, however, because it provides a single definition for the multiple classes in the example that share the file.

The following sections provide code examples showing how the PluginObject interface for plug-in Done and Start nodes is implemented.

In addition to these examples, refer to the following files in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory:

This file . . . | Illustrates PluginObject implementation for a . . .
--- | ---
EventObject.java | Plug-in event
CheckInventoryActionObject.java | Plug-in action
SendConfirmActionObject.java | Plug-in action

For more information about the plug-in sample, see BPM Plug-In Sample.

Done Node Example

The following code listing shows how to define a class that implements the PluginObject interface for a Done node. The input to the example code is a user response to a decision dialog box (yes or no). Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-1 Implementing the PluginObject Interface for a Done Node

>     package com.bea.wlpi.test.plugin;

>     import java.io.IOException;
>     import com.bea.wlpi.common.plugin.PluginObject;
>     import org.xml.sax.*;

>     public class DoneObject implements PluginObject
>     {

>        protected String yesOrNo = null;
>        protected static String YESORNO_TAG = "yesorno";
>        protected transient String        lastValue;

>        public DoneObject()
>        {
>        }

>        public DoneObject(String yesOrNo)
>        {
>           this.yesOrNo = yesOrNo;
>        }

>        public void load(XMLReader parser)
>        {
>        }

>        void setYesOrNo(String decision)
>        {
>           yesOrNo = decision;
>        }
>        String getYesOrNo()
>        {
>           return yesOrNo;
>        }

>        public void setDocumentLocator(Locator locator)
>        {
>        }

>        public void startDocument()
>        throws SAXException
>        {
>        }

>        public void endDocument()
>        throws SAXException
>        {
>        }

>        public void startPrefixMapping(String prefix, String uri)
>        throws SAXException
>        {
>        }

>        public void endPrefixMapping(String prefix)
>        throws SAXException
>        {
>        }

>        public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
>        throws SAXException
>        {
>           lastValue = null;
>        }

>        public void endElement(String namespaceURI, String localName, String name)
>        throws SAXException
>        {
>           if(name.equals(YESORNO_TAG))
>              yesOrNo = lastValue;
>        }

>        public void characters(char[] ch, int start, int length)
>        throws SAXException
>        {
>           String value = new String(ch, start, length);

>           if(lastValue == null)
>              lastValue = value;
>           else
>              lastValue = lastValue + value;
>        }

>        public void ignorableWhitespace(char[] ch, int start, int length)
>        throws SAXException
>        {
>        }

>        public void processingInstruction(String target, String data)
>        throws SAXException
>        {
>        }

>        public void skippedEntity(String name)
>        throws SAXException
>        {
>        }
>     }

Refer to the following related example listings:

- Implementing the PluginData Interface for a Done Node shows how to read and save the plug-in data in XML format. This example extends the class shown in the previous example.

- Defining the PluginPanel Class for a Done Node shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for a Done Node shows how to define the execution information for the plug-in.

Start Node Example

The following code listing is an excerpt from the plug-in sample that shows how to define a class that implements the PluginObject interface for a Start node. Note that the load(), startelement(), and endelement() method are defined. This excerpt is taken from the StartObject.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-2 Implementing the PluginObject Interface for a Start Node

>     public class StartObject implements PluginObject {
>     	.
>     	.
>     	.
>         public void load(XMLReader parser) {
>         }
>     	.
>     	.
>     	.
>         public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
>                 throws SAXException {
>             lastValue = null;
>         }

>         public void endElement(String namespaceURI, String localName, String name)
>                 throws SAXException {
>             if (name.equals(EVENTDESC_TAG))
>                 eventDesc = lastValue;
>         }
>          .
>          .
>          .

Refer to the following related example listings:

- Implementing the PluginData Interface for a Start Node shows how to read and save plug-in data in XML format. This example extends the class shown in the previous example.

- Defining the PluginTriggerPanel Class for a Start Node shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for a Start Node shows how to define the execution information for the plug-in.

- Using Plug-In Run-Time Contexts shows how to define the plug-in fields that can be referenced from an evaluator expression.

For more information about the plug-in sample, see BPM Plug-In Sample.

Reading and Saving Plug-In Data

To read (parse) and save plug-in data in XML format, you must implement the plug-in data interface.

Note: For each plug-in data interface class that is defined by a BPM plug-in value object via the KEY_DATA, KEY_PANEL, and KEY_RENDERER values, you must provide a public constructor that requires no arguments to support remote class loading on the client. This public constructor is not required to be supplied for the plug-in defined classes that are referenced by this class. For more information about using BPM plug-in value objects, see Plug-In Development Fundamentals.

This is a requirement for WebLogic Integration Release 2.1 Service Pack 1. If you do not provide a no-argument constructor for classes generated using an earlier release of WebLogic Integration, the classes will be instantiated, but you may receive exceptions if the client and server platforms are incompatible.

To enable the plug-in to read (parse) incoming data, the plug-in data interface class must implement the load() (parsing) method of its parent interface, com.bea.wlpi.common.plugin.PluginObject.

To enable the plug-in to save its data in XML format, you must implement one of the plug-in data interfaces defined in the following table based on the type of plug-in component being defined. Data must be saved in XML format, for example, when you are saving a template, template definition, or plug-in configuration XML document in the Studio.

Note: You do not need to implement the plug-in data interface to read and save data for the following plug-in components: functions, message types, and variable types.

Table 4-3 Plug-In Data Interfaces

To define the following plug-in . . . | You must implement . . .
--- | ---
Any plug-in component | com.bea.wlpi.common.plugin.PluginData to enable the plug-in component to save its data in XML format. When defining actions, you should implement the PluginActionData interface, which extends this interface.
Action | com.bea.wlpi.common.plugin.PluginActionData to enable the plug-in action to save its data in XML format. This class is used by the Action Plugin dialog box in the Studio, which provides generic support for subactions. Note: PluginActionData extends the PluginData interface defined previously in this table.

Note: For information about the BPM DTDs and examples of plug-in-specific output, see DTD Formats in Programming BPM Client Applications.

Each plug-in data interface is defined in more detail in the following sections.

Implementing the PluginData Interface

You must implement the com.bea.wlpi.common.plugin.PluginData interface to enable the plug-in component to save its data in XML format.

Note: When defining actions, you should implement the PluginActionData interface, as described in Implementing the PluginActionData Interface.

The following table describes the methods defined by the PluginData interface that you must implement.

Note: The contents of the PluginData interface methods may be empty or simply return a message to the log, but they must be implemented.

Table 4-4 PluginData Interface Methods

Method | Description
--- | ---
public java.lang.Object clone() | Clones the plug-in data. This method returns a java.lang.Object instance that specifies a deep (recursive) copy of the graph for this object.
public java.lang.String getPrintableData() | Gets a printable description of the plug-in data. This method is typically used when a template definition is printed out. This method returns a java.lang.String object that specifies the printable data. This value should be localized ujsing the locale specified in the plug-in data constructor.
public java.util.List getReferencedPublishables(java.util.Map publishables) | Gets the referenced publishable objects. Enables design-time clients to package a workflow definition with its dependencies so the resulting package can be imported and run. Publishable objects include: templates, template definitions, business calendars, business operations, event keys, and repository items. Plug-ins that contain references to these objects must declare them when this method is called. The user creating an export package can then specify which of the referenced objects should be included in the package. The method parameter is defined as follows. publishables: java.util.Map object that specifies a map of all publishable objects, keyed on the constants defined in the com.bea.wlpi.common.Publishable interface. The values in the map are homogenous java.util.List objects containing value objects of a type that matches their corresponding keys. The plug-in must add the appropriate objects in these lists to the returned list, as the design client expects a list of references to the actual objects. This method returns a list of com.bea.wlpi.common.Publishable objects. For more information about publishable objects, see Publishing Workflow Objects in Programming BPM Client Applications.
public void save(com.bea.wlpi.common.XMLWriter writer, int indent) throws java.io.IOException | Saves data in an XML document. The Plug-in Manager calls this method when it encounters the plug-in section (for example, a <plugin-data> element) in an XML document. This occurs, for example, when a template, template definition, or plug-in configuration XML document is being saved in the Studio. The method parameters are defined as follows: writer: com.bea.wlpi.common.XMLWriter object that specifies the XMLWriter to use to serialize the plug-in data. indent: Integer value that specifies the indentation level. You should use this value to create a correctly indented XML document. The default indentation is two spaces.

The following sections provide code examples showing how the PluginData interface is implemented.

Done Node Example

The following code listing shows how to define a class that implements the PluginData interface for a Done node. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-3 Implementing the PluginData Interface for a Done Node

>     package com.bea.wlpi.test.plugin;

>     import com.bea.wlpi.common.XMLWriter;
>     import com.bea.wlpi.common.plugin.PluginData;
>     import java.io.IOException;
>     import java.util.List;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class DoneNodeData extends DoneObject implements PluginData
>     {
>         public static int count = 0;
>         private int c;

>         public DoneNodeData()
>         {
>             c=count++;
>         }

>         public DoneNodeData(String yesOrNo)
>         {
>             super(yesOrNo);
>             c=count++;
>         }

>         public void save(XMLWriter writer, int indent) throws IOException
>         {
>             writer.saveElement(indent, YESORNO_TAG, yesOrNo);
>         }
>     }

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to read the plug-in data in XML format. This class is extended by the class shown in the previous example.

- Defining the PluginPanel Class for a Done Node shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for a Done Node shows how to define the execution information for the plug-in.

Event Node Example

The following code listing is an excerpt from the plug-in sample that shows how to define a class that implements the PluginData interface for an Event node. This excerpt is taken from the EventNodeData.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-4 Implementing the PluginData Interface for an Event Node

>     package com.bea.wlpi.tour.po.plugin;

>     import com.bea.wlpi.common.XMLWriter;
>     import com.bea.wlpi.common.plugin.PluginData;
>     import java.io.IOException;
>     import java.util.List;
>     import java.util.Locale;
>     import java.util.ResourceBundle;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class EventNodeData extends EventObject implements PluginData {
>         private SampleBundle bundle;

>         public EventNodeData() {
>             this(Locale.getDefault());
>         }

>         public EventNodeData(Locale lc) {
>             eventDesc = SamplePluginConstants.CONFIRM_EVENT;
>             bundle = new SampleBundle(lc);
>         }

>         public void save(XMLWriter writer, int indent) throws IOException {
>             writer.saveElement(indent, EVENTDESC_TAG, eventDesc);
>         }

>         public List getReferencedPublishables(Map publishables) {
>             return null;
>         }

>         public String getPrintableData() {
>             return bundle.getString("confirmOrderName");
>         }

>         public Object clone() {
>             return new EventNodeData(bundle.getLocale());
>         }
>     }

Refer to the following related example listings:

- EventObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to read the plug-in data in XML format. This class is extended by the class shown in the previous example.

- Defining the PluginTriggerPanel Class for an Event Node shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for an Event Node shows how to define the execution information for the plug-in.

For more information about the plug-in sample, see BPM Plug-In Sample.

Start Node Example

The following code listing is an excerpt from the plug-in sample that shows how to define a class that implements the PluginData interface for a Start node. This excerpt is taken from the StartNodeData.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-5 Implementing the PluginData Interface for a Start Node

>     package com.bea.wlpi.tour.po.plugin;

>     import com.bea.wlpi.common.XMLWriter;
>     import com.bea.wlpi.common.plugin.PluginData;
>     import java.io.IOException;
>     import java.util.List;
>     import java.util.Locale;
>     import java.util.ResourceBundle;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class StartNodeData extends StartObject implements PluginData {
>         private SampleBundle bundle;

>         public StartNodeData() {
>             this(Locale.getDefault());
>         }

>         public StartNodeData(Locale lc) {
>             eventDesc = SamplePluginConstants.START_ORDER_EVENT;
>             bundle = new SampleBundle(lc);
>         }

>         public void save(XMLWriter writer, int indent) throws IOException {
>             writer.saveElement(indent, EVENTDESC_TAG, eventDesc);
>         }

>         public List getReferencedPublishables(Map publishables) {
>             return null;
>         }

>         public String getPrintableData() {
>             return bundle.getString("startOrderLabel");
>         }

>         public Object clone() {
>             return new StartNodeData(bundle.getLocale());
>         }
>     }

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Start Node shows how to read plug-in data in XML format. This class is extended by the class shown in the previous example.

- Defining the PluginTriggerPanel Class for a Start Node shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for a Start Node shows how to define the execution information for the plug-in.

- Using Plug-In Run-Time Contexts shows how to define the plug-in fields that can be referenced from an evaluator expression.

For more information about the plug-in sample, see BPM Plug-In Sample.

Workflow Template Properties Example

The following code listing shows how to define a class that implements the PluginData interface for workflow template properties. The code reads and saves the user's response to a decision dialog box (yes or no). Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-6 Implementing the PluginData Interface for Workflow Template Properties

>     package com.bea.wlpi.test.plugin;

>     import com.bea.wlpi.common.XMLWriter;
>     import com.bea.wlpi.common.plugin.PluginData;
>     import java.io.IOException;
>     import java.util.List;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class TemplatePropertiesData extends DoneObject implements PluginData {

>         public TemplatePropertiesData() {
>         }

>         public TemplatePropertiesData(String yesOrNo){
>             super(yesOrNo);
>         }

>         public void save(XMLWriter writer, int indent) throws IOException {
>             writer.saveElement(indent, YESORNO_TAG, yesOrNo);
>         }

>         public List getReferencedPublishables(Map publishables) {
>             return null;
>         }

>         public String getPrintableData() {
>             return null;
>         }
>     }

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to read the plug-in data in XML format. This class is extended by the class shown in the previous example.

- Defining the PluginPanel Class for Workflow Template Properties shows how to display the plug-in GUI component in the design client.

Workflow Template Definition Properties Example

The following code listing shows how to define a class that implements the PluginData interface for workflow template definition properties. The code reads and saves the user's response to a decision dialog box (yes or no). Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-7 Implementing the PluginData Interface for Workflow Template Definition Properties

>     package com.bea.wlpi.test.plugin;

>     import com.bea.wlpi.common.XMLWriter;
>     import com.bea.wlpi.common.plugin.PluginData;
>     import java.io.IOException;
>     import java.util.List;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class TemplateDefinitionPropertiesData extends DoneObject implements PluginData
>     {

>         public TemplateDefinitionPropertiesData()
>         {
>         }

>         public TemplateDefinitionPropertiesData(String yesOrNo)
>         {
>             super(yesOrNo);
>         }

>         public void save(XMLWriter writer, int indent) throws IOException
>         {
>             writer.saveElement(indent, YESORNO_TAG, yesOrNo);
>         }

>         public List getReferencedPublishables(Map publishables) {
>             return null;
>         }

>         public String getPrintableData() {
>             return null;
>         }

>         public Object clone() {
>             return new TemplateDefinitionPropertiesData(yesOrNo);
>         }
>     }

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to read the plug-in data in XML format. This class is extended by the class shown in the previous example.

- Defining the PluginPanel Class for Workflow Template Definition Properties shows how to display the plug-in GUI component in the design client.

Implementing the PluginActionData Interface

You must implement the com.bea.wlpi.common.plugin.PluginActionData interface to enable the plug-in action to save its data in XML format.

Note: The PluginActionData interface extends the PluginData interface. For more information about the PluginData interface methods, see the table PluginData Interface Methods.

The following table describes the method defined by the PluginActionData interface that you must implement.

Note: The contents of the PluginActionData interface methods may be empty or simply return a message to the log, but they must be implemented.

Table 4-5 PluginActionData Interface Method

Method | Description
--- | ---
public java.lang.String getLabel() | Gets the formatted label of the plug-in action that is specified in the actions list.

The following code listing is an excerpt from the plug-in sample that shows how to define a class that implements the PluginActionData interface. This excerpt is taken from the CheckInventoryActionData.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Note: Refer to SendConfirmationActionData.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory for another example of how to define a class the implements the PluginActionData interface.

Listing 4-8 Implementing the PluginActionData Interface

>     package com.bea.wlpi.tour.po.plugin;

>     import com.bea.wlpi.common.XMLWriter;
>     import com.bea.wlpi.common.plugin.PluginData;
>     import com.bea.wlpi.common.plugin.PluginActionData;
>     import java.io.IOException;
>     import java.util.ResourceBundle;
>     import java.util.Locale;
>     import java.util.List;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class CheckInventoryActionData extends CheckInventoryActionObject
>             implements PluginActionData {
>         private SampleBundle bundle;

>         public CheckInventoryActionData() {
>             getBundle(Locale.getDefault());
>         }

>         public CheckInventoryActionData(Locale lc) {
>             getBundle(lc);
>         }

>         public CheckInventoryActionData(Locale lc, String inputVariableName,
>                                         String outputVariableName) {

>             super(inputVariableName, outputVariableName);

>             getBundle(lc);
>         }

>         public void save(XMLWriter writer, int indent) throws IOException {
>             writer.saveElement(indent, INPUTVARIABLE_TAG, inputVariableName);
>             writer.saveElement(indent, OUTPUTVARIABLE_TAG, outputVariableName);
>         }

>         private void getBundle(Locale lc) {
>             bundle = new SampleBundle(lc);
>         }

>         public List getReferencedPublishables(Map publishables) {
>             return null;
>         }

>         public String getPrintableData() {
>             return bundle.getString("checkInventoryDesc");
>         }
>         public Object clone() {

>             return new CheckInventoryActionData(bundle.getLocale(),
>                        new String(this.inputVariableName),
>                        new String(this.outputVariableName));
>         }

>         public String getLabel() {
>             return bundle.getString("checkInventoryDesc");
>         }
>     }

Refer to the following related example listings:

- CheckInventoryActionObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to read the plug-in data in XML format. This class is extended by the class shown in the previous example.

- Defining the PluginActionPanel Class shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for an Action shows how to define the execution information for the plug-in.

- Customizing an Action Tree shows how to customize the actions and/or action categories listed in the action trees that are displayed in various dialog boxes within the Studio.

For more information about the plug-in sample, see BPM Plug-In Sample.

Displaying the Plug-In GUI Component

To display the plug-in GUI component within the design client, all plug-ins must define a class that extends the plug-in panel class.

For example, in the figure Plug-In Example: Start Node, when a user selects the Start Order event as the Start node trigger, the Plug-in Manager loads the plug-in panel class, StartNodePanel, and it is instantiated by the Studio client using the no-argument constructor. The Studio client subsequently displays the plug-in GUI component in the Start Properties dialog box. (For more information about remote class loading, see Accessing the Plug-In Implementation.)

Note: For each plug-in GUI component class that is defined by a BPM plug-in value object via the KEY_DATA, KEY_PANEL, and KEY_RENDERER values, you must provide a public constructor that requires no arguments to support remote class loading on the client.This public constructor is not required to be supplied for the plug-in defined classes that are referenced by this class. For more information about using BPM plug-in value objects, see Plug-In Development Fundamentals.

This is a requirement for WebLogic Integration Release 2.1 Service Pack 1. If you do not provide a no-argument constructor for classes generated using an earlier release of WebLogic Integration, the classes will be instantiated, but you may receive exceptions if the client and server platforms are incompatible.

The following table describes the plug-in panel classes that you must extend based on the type of plug-in component being defined.

Note: You do not need to implement the plug-in panel interface to display a GUI component for the following plug-in components: functions and message types.

Table 4-6 Plug-In Panel Classes

To define the following plug-in . . . | The plug-in panel class must extend . . . | To define . . .
--- | --- | ---
Any plug-in component | com.bea.wlpi.common.plugin.PluginPanel | GUI component to be displayed in the design client. When an action, Start or Event node, or variable type, is being defined, the plug-in panel class defined for it (defined later in this table) extend this class.
Action | com.bea.wlpi.common.plugin.PluginActionPanel | GUI component for the plug-in action. This class is used by the Action Plugin dialog box in the Studio, which provides generic support for subactions. Note: PluginActionPanel extends the PluginPanel class defined previously in this table.
Start and Event node | com.bea.wlpi.common.plugin.PluginTriggerPanel | Start and/or Event node GUI component to be displayed in the design client. This class is used by the Start Properties and Event Properties dialog boxes in the Studio. Note: PluginTriggerPanel extends the PluginPanel class defined previously in this table.
Variable type | com.bea.wlpi.common.plugin.PluginVariablePanel | GUI component to be displayed in the design client so it is available to users for editing the plug-in variable type. This class is used by the Update Variable dialog box in the Studio. Note: PluginVariablePanel extends the PluginPanel class defined previously in this table.
com.bea.wlpi.common.plugin.PluginVariableRender | GUI component to display the value of a plugin-defined variable type in the cell of a javax.swing.JTable. This class is used by the Update Variable dialog box in the Studio.

Each plug-in panel class is defined in more detail in the following sections.

Defining the PluginPanel Class

To define the plug-in GUI component displayed in the design client, you must define a class that extends the com.bea.wlpi.common.plugin.PluginPanel class.

Note: When defining actions, Start or Event nodes, or variable types, you should extend the corresponding plug-in panel class defined in the table Plug-In Panel Classes, which extends the PluginPanel class.

The following table describes the class methods defined by the PluginPanel class.

Note: You can override any method that is not declared as final.

Table 4-7 PluginPanel Class Methods

Method | Description
--- | ---
public void exceptionHandlerRenamed(java.lang.String oldName, java.lang.String newName) | Renames the event handler. The method must update any direct references to the exception handler, and propagate the information to any com.bea.wlpi.evaluator.Expression objects owned by the plug-in panel. Subclasses must override this method if they refer to workflow event handlers and propogate updates to those handlers to ensure that the reference is maintained. Note: In plug-in nodes, where actions are supported by default, the Plug-in Manager propagates the changes throughout the action lists. The method parameters are defined as follows: oldName: java.lang.String object that specifies the old event handler name. newName: java.lang.String object that specifies the new event handler name.
public final com.bea.wlpi.common.plugin.PluginPanelContext getContext() | Gets the parent component in which the plug-in panel is displayed. This method returns a com.bea.wlpi.common.plugin.PluginPanelContext object that specifies the parent component. For more information about implementing the PluginPanelContext, see Using Plug-In Run-Time Contexts.
public final com.bea.wlpi.common.plugin.PluginData getData() | Gets the plug-in data. This method returns a com.bea.wlpi.common.plugin.PluginData object that specifies the plug-in data. For more information about implementing the PluginData object, see Implementing the PluginData Interface.
public java.lang.String getHelpIDString() | Gets the help topic ID for the plug-in panel. This method returns a java.lang.String object that specifies the help topic ID.
public java.lang.String getString(java.lang.String key) | Gets a localized display string. The resource bundle name must have been set by a prior call to the setResourceBundle() method (described later in this table). The method parameter is defined as follows. key: java.lang.String object that specifies the resource key. This method returns a java.lang.String object that specifies the display string.
public java.lang.String getString(java.lang.String key, java.lang.Object[] args) | Gets a localized display string. The resource bundle name must have been set by a prior call to the setResourceBundle() method (described later in this table). This method uses the object's ClassLoader to retrieve the string resource from the nominated resource properties file in its plugin-ejb.jar file. The method parameters are defined as follows: key: java.lang.String object that specifies the resource key. args: java.lang.Object object that specifies the arguments to be inserted into the message text. This method returns a java.lang.String object that specifies the display string.
public abstract void load() | Instructs the plug-in panel to initialize its user interface using the plug-in data. This method calls getData() to access the plug-in data, sends the result to the corresponding plug-in class, and calls the appropriate get methods to retrieve the display values. The Plug-in Manager ensures that this method is called exactly once per modal display cycle. Note: Plug-ins must not call this method.
public boolean referencesExceptionHandler(java.lang.String handler) | Checks whether the plug-in panel references the specified event handler. The method must check by name any direct references that the plug-in panel class holds to the specified exception handler. Subclasses must override this method if they make reference to workflow event handlers to avoid inadvertently deleting a referenced event handler. Note: In plug-in nodes, where actions are supported by default, the Plug-in Manager propagates the changes throughout the action lists. The method parameter is defined as follows. handler: java.lang.String object that specifies the event handler name. The method returns a Boolean value: true if the plug-in panel references the specified event handler, and false if it does not.
public boolean referencesVariable(java.lang.String variable) | Checks whether the plug-in panel references the specified variable. The method must check by name any direct references that the plug-in panel class holds to the specified variable. Subclasses must override this method if they make reference to a workflow variable, either directly, by name, or indirectly, via expression, to avoid inadvertently deleting the referenced variables. Note: In plug-in nodes, where actions are supported by default, the Plug-in Manager propagates the changes throughout the action lists. The method parameter is defined as follows. variable: java.lang.String object that specifies the variable. The method returns a Boolean value: true if the plug-in panel references the specified eventhandler, and false if it does not.
public final void setContext(com.bea.wlpi.common.plugin.PluginPanelContext context, com.bea.wlpi.common.plugin.PluginData data) | Sets the operating context for the plug-in panel. The Plug-in Manager calls this method before adding the plug-in panel to the design client dialog box. This method stores the owner and data parameters in the corresponding member variables. Note: Plug-ins must not call this method. The method parameters are defined as follows: context: com.bea.wlpi.common.plugin.PluginPanelContext object that specifies the design client dialog box context in which the plug-in panel is being displayed. For more information about implementing the PluginPanelContext object, see Using Plug-In Run-Time Contexts. data: com.bea.wlpi.common.plugin.PluginData object that specifies the plug-in data. For more information about implementing the PluginData object, see Implementing the PluginData Interface.
public void setResourceBundle(java.lang.String bundleName) | Sets the resource bundle to use when localizing strings and messages. The method parameter is defined as follows. bundleName: java.lang.String object that specifies the name of the resource bundle.
public abstract boolean validateAndSave() | Instructs the plug-in panel to validate the GUI control values and then save them. This method calls getData() to access the plug-in data, sends the result to the corresponding plug-in class, and calls the appropriate set methods to save the display values. This method returns a Boolean value: true if the panel was validated and subsequently saved, and false if it was not.
public void variableRenamed(java.lang.String oldName, java.lang.String newName) | Renames the variables. The method must update any direct references to the variable, and propagate the information to any com.bea.wlpi.evaluator.Expression objects owned by the plug-in panel. This can be accomplished by calling the variableRenamed() method, followed by the toString() method to get the updated expression text. Subclasses must override this method if they make reference to workflow variables, either directly, by name, or indirectly, via expressions, to ensure that the reference is maintained. Note: In plug-in nodes, where actions are supported by default, the Plug-in Manager propagates the changes throughout the action lists. The method parameters are defined as follows: oldName: java.lang.String object that specifies the old variable name. newName: java.lang.String object that specifies the new variable name.

The following sections provide code examples showing how the PluginPanel class is defined.

Done Node Example

The following code listing shows how to define the PluginPanel class for a Done node. The code displays a decision dialog box (yes or no) within the Done Properties dialog box. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-9 Defining the PluginPanel Class for a Done Node

>     package com.bea.wlpi.test.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import javax.swing.border.TitledBorder;
>     import javax.swing.border.EtchedBorder;
>     import java.util.List;
>     import java.util.Locale;
>     import com.bea.wlpi.common.plugin.PluginPanel;
>     import com.bea.wlpi.common.plugin.PluginPanelContext;
>     import com.bea.wlpi.client.studio.Studio;
>     import com.bea.wlpi.common.VariableInfo;

>     public class DoneNodePanel extends PluginPanel
>     {

>         JPanel ButtonPanel = new JPanel();
>         ButtonGroup YesNoButtonGroup = new ButtonGroup();
>         JRadioButton YesButton = new JRadioButton();
>         JRadioButton NoButton = new JRadioButton();
>         TitledBorder titledBorder = new TitledBorder(new EtchedBorder());

>        public DoneNodePanel()
>        {
>           super(Locale.getDefault(), "jackolantern");
>           setLayout(null);
>           setBounds(12,12,420,300);
>           setPreferredSize(new Dimension(420,300));
>           ButtonPanel.setBorder(titledBorder);
>           ButtonPanel.setLayout(null);
>           add(ButtonPanel);
>           ButtonPanel.setBounds(72,60,300,144);
>           YesButton.setText("Yes");
>           YesButton.setSelected(true);
>           YesNoButtonGroup.add(YesButton);
>           ButtonPanel.add(YesButton);
>           YesButton.setBounds(60,36,46,23);
>           NoButton.setText("No");
>           YesNoButtonGroup.add(NoButton);
>           ButtonPanel.add(NoButton);
>           NoButton.setBounds(60,60,46,23);
>           titledBorder.setTitle("Yes or No?");
>        }

>     public void load() {

>         DoneNodeData myData = (DoneNodeData)getData();
>         if(myData != null) {
>             if(myData.getYesOrNo() != null && myData.getYesOrNo().equals(TestPluginConstants.DONE_NO)) {
>                 NoButton.setSelected(true);
>             } else {
>                 YesButton.setSelected(true);
>             }
>         }
>     }

>        public boolean validateAndSave()
>        {
>         DoneNodeData myData = (DoneNodeData)getData();
>         if(myData != null) {
>             if(YesButton.isSelected()) {
>                 myData.setYesOrNo(TestPluginConstants.DONE_YES);
>             } else {
>                 myData.setYesOrNo(TestPluginConstants.DONE_NO);
>             }
>         }

>           return true;
>        }

The following figure illustrates the resulting PluginPanel GUI component.

Figure 4-1 PluginPanel GUI Component for a Done Node

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to read the plug-in data in XML format.

- Implementing the PluginData Interface for a Done Node shows how to read and save the plug-in data in XML format. This class extends the PluginObject class.

- Defining the Run-Time Component Class for a Done Node shows how to define the execution information for the plug-in.

Workflow Template Properties Example

The following code listing shows how to define the PluginPanel class for workflow template properties. The code displays a decision dialog box (yes or no) within the Workflow Template Properties dialog box. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-10 Defining the PluginPanel Class for Workflow Template Properties

>     package com.bea.wlpi.test.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import javax.swing.border.TitledBorder;
>     import javax.swing.border.EtchedBorder;
>     import java.util.List;
>     import java.util.Locale;
>     import com.bea.wlpi.common.plugin.PluginPanel;
>     import com.bea.wlpi.common.plugin.PluginPanelContext;
>     import com.bea.wlpi.client.studio.Studio;
>     import com.bea.wlpi.common.VariableInfo;

>     public class TemplatePropertiesPanel extends PluginPanel
>     {

>         JPanel ButtonPanel = new JPanel();
>         ButtonGroup YesNoButtonGroup = new ButtonGroup();
>         JRadioButton YesButton = new JRadioButton();
>         JRadioButton NoButton = new JRadioButton();
>         TitledBorder titledBorder = new TitledBorder(new EtchedBorder());

>        public TemplatePropertiesPanel()
>        {
>           super(Locale.getDefault(), "stpatty");
>           setLayout(null);
>           setBounds(12,12,420,300);
>           ButtonPanel.setBorder(titledBorder);
>           ButtonPanel.setLayout(null);
>           add(ButtonPanel);
>           ButtonPanel.setBounds(72,60,300,144);
>           YesButton.setText("Yes");
>           YesButton.setSelected(true);
>           YesNoButtonGroup.add(YesButton);
>           ButtonPanel.add(YesButton);
>           YesButton.setBounds(60,36,46,23);
>           NoButton.setText("No");
>           YesNoButtonGroup.add(NoButton);
>           ButtonPanel.add(NoButton);
>           NoButton.setBounds(60,60,46,23);
>           titledBorder.setTitle("Yes or No?");
>        }

>     public void load() {

>         TemplatePropertiesData myData = (TemplatePropertiesData)getData();
>         if(myData != null) {
>             if(myData.getYesOrNo() != null && myData.getYesOrNo().equals(TestPluginConstants.DONE_NO)) {
>                 NoButton.setSelected(true);
>             } else {
>                 YesButton.setSelected(true);
>             }
>         }
>     }

>        public boolean validateAndSave()
>        {
>         TemplatePropertiesData myData = (TemplatePropertiesData)getData();
>         if(myData != null) {
>             if(YesButton.isSelected()) {
>                 myData.setYesOrNo(TestPluginConstants.DONE_YES);
>             } else {
>                 myData.setYesOrNo(TestPluginConstants.DONE_NO);
>             }
>         }

>           return true;
>        }

The following figure illustrates the resulting PluginPanel GUI component.

Figure 4-2 PluginPanel GUI Component for Workflow Template Properties

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to define the PluginObject class to read the plug-in data in XML format.

- Implementing the PluginData Interface for Workflow Template Properties shows how to read and save the plug-in data in XML format. This class extends the PluginObject class.

Workflow Template Definition Properties Example

The following code listing shows how to define the PluginPanel class for workflow template definition properties. The code displays a decision dialog box (yes or no) within the Workflow Template Definition Properties dialog box. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-11 Defining the PluginPanel Class for Workflow Template Definition Properties

>     package com.bea.wlpi.test.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import javax.swing.border.TitledBorder;
>     import javax.swing.border.EtchedBorder;
>     import java.util.List;
>     import java.util.Locale;
>     import com.bea.wlpi.common.plugin.PluginPanel;
>     import com.bea.wlpi.common.plugin.PluginPanelContext;
>     import com.bea.wlpi.client.studio.Studio;
>     import com.bea.wlpi.common.VariableInfo;

>     public class TemplateDefinitionPropertiesPanel extends PluginPanel
>     {

>         JPanel ButtonPanel = new JPanel();
>         ButtonGroup YesNoButtonGroup = new ButtonGroup();
>         JRadioButton YesButton = new JRadioButton();
>         JRadioButton NoButton = new JRadioButton();
>         TitledBorder titledBorder = new TitledBorder(new EtchedBorder());

>        public TemplateDefinitionPropertiesPanel()
>        {
>           super(Locale.getDefault(), "valentine");
>           setLayout(null);
>           setBounds(12,12,420,300);
>           ButtonPanel.setBorder(titledBorder);
>           ButtonPanel.setLayout(null);
>           add(ButtonPanel);
>           ButtonPanel.setBounds(72,60,300,144);
>           YesButton.setText("Yes");
>           YesButton.setSelected(true);
>           YesNoButtonGroup.add(YesButton);
>           ButtonPanel.add(YesButton);
>           YesButton.setBounds(60,36,46,23);
>           NoButton.setText("No");
>           YesNoButtonGroup.add(NoButton);
>           ButtonPanel.add(NoButton);
>           NoButton.setBounds(60,60,46,23);
>           titledBorder.setTitle("Yes or No?");
>        }

>     public void load() {

>         TemplateDefinitionPropertiesData myData = (TemplateDefinitionPropertiesData)getData();
>         if(myData != null) {
>             if(myData.getYesOrNo() != null && myData.getYesOrNo().equals(TestPluginConstants.DONE_NO)) {
>                 NoButton.setSelected(true);
>             } else {
>                 YesButton.setSelected(true);
>             }
>         }
>     }

>        public boolean validateAndSave()
>        {
>         TemplateDefinitionPropertiesData myData = (TemplateDefinitionPropertiesData)getData();
>         if(myData != null) {
>             if(YesButton.isSelected()) {
>                 myData.setYesOrNo(TestPluginConstants.DONE_YES);
>             } else {
>                 myData.setYesOrNo(TestPluginConstants.DONE_NO);
>             }
>         }

>           return true;
>     }

The following figure illustrates the resulting PluginPanel GUI component.

Figure 4-3 PluginPanel GUI Component for Workflow Template Definition Properties

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to define the PluginObject class to read the plug-in data in XML format.

- Implementing the PluginData Interface for Workflow Template Definition Properties shows how to read and save the plug-in data in XML format. This class extends the PluginObject class.

Defining the PluginActionPanel Class

To define the GUI component displayed in the design client when defining a plug-in action, you must define a class that extends the com.bea.wlpi.common.plugin.PluginActionPanel class. In the Studio, the PluginActionPanel class is used by the Action Plugin dialog box, which provides generic support for subactions.

The PluginActionPanel class defines no additional methods.

Note: The PluginActionPanel class extends the PluginPanel class. For more information about the PluginPanel class methods, see the table PluginPanel Class Methods.

The following code listing is an excerpt from the plug-in sample that shows how to define the PluginActionPanel class. This excerpt is taken from the CheckInventoryActionPanel.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Note: Refer to the SendConfirmationActionPanel.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory for another example of how to define a PluginActionPanel class.

Listing 4-12 Defining the PluginActionPanel Class

>     package com.bea.wlpi.tour.po.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import java.util.List;
>     import java.util.Locale;
>     import com.bea.wlpi.common.VariableInfo;
>     import com.bea.wlpi.common.plugin.PluginActionPanel;
>     import com.bea.wlpi.common.plugin.PluginPanelContext;

>     public class CheckInventoryActionPanel extends PluginActionPanel {
>         private JLabel inputLabel = new JLabel();
>         private JLabel outputLabel = new JLabel();
>         private JComboBox inputComboBox = new JComboBox();
>         private JComboBox outputComboBox = new JComboBox();
>         private List variables = null;

>         public CheckInventoryActionPanel() {
>             this(Locale.getDefault());
>         }

>         public CheckInventoryActionPanel(Locale lc) {

>             super(lc, "checkinventory");

>             setLayout(null);
>             setBounds(12, 12, 420, 210);
>             setPreferredSize(new Dimension(420, 210));
>             add(inputLabel);
>             inputLabel.setBounds(12, 48, 96, 24);
>             add(outputLabel);
>             outputLabel.setBounds(12, 108, 166, 24);
>             add(inputComboBox);
>             inputComboBox.setBounds(190, 48, 212, 24);
>             inputComboBox.setEditable(true);
>             add(outputComboBox);
>             outputComboBox.setBounds(190, 108, 212, 24);
>             outputComboBox.setEditable(true);
>         }

>         public void load() {

>             setResourceBundle("com.bea.wlpi.tour.po.plugin.SamplePlugin");
>             inputLabel.setText(getString("inputLabel"));
>             outputLabel.setText(getString("outputLabel"));

>             CheckInventoryActionData myData = (CheckInventoryActionData)getData();

>             variables = getContext().getVariableList(VariableInfo.TYPE_INT);

>             // load is called before displaying this panel each time.  Make sure to
>             // remove items from the combo box before filling with currently
>             // defined variables.
>             inputComboBox.removeAllItems();

>             String inputVar = myData.getInputVariableName();
>             int n = variables == null ? 0 : variables.size();

>             for (int i = 0; i < n; i++) {
>                 VariableInfo varInfo = (VariableInfo)variables.get(i);

>                 inputComboBox.addItem(varInfo.getName());

>                 if (inputVar != null && inputVar.equals(varInfo.getName())) {
>                     inputComboBox.setSelectedIndex(i);
>                 }
>             }

>             if (inputVar == null && n > 0)
>                 inputComboBox.setSelectedIndex(0);

>             outputComboBox.removeAllItems();

>             String outputVar = myData.getOutputVariableName();

>             for (int i = 0; i < n; i++) {
>                 VariableInfo varInfo = (VariableInfo)variables.get(i);

>                 outputComboBox.addItem(varInfo.getName());

>                 if (outputVar != null && outputVar.equals(varInfo.getName())) {
>                     outputComboBox.setSelectedIndex(i);
>                 }
>             }

>             if (outputVar == null && n > 0)
>                 outputComboBox.setSelectedIndex(0);
>         }

>         public boolean validateAndSave() {

>             CheckInventoryActionData myData = (CheckInventoryActionData)getData();
>             String input = (String)inputComboBox.getEditor().getItem();

>             try {
>                 VariableInfo varInfo = getContext().checkVariable(input,
>                                            new String[]{ VariableInfo.TYPE_INT });

>                 if (varInfo == null)
>                     return false;

>                 if (!(varInfo.getType().equals(VariableInfo.TYPE_INT))) {
>                     JOptionPane.showMessageDialog(SwingUtilities.windowForComponent(this),
>                                                   getString("Message_100"),
>                                                   getString("variableErrorTitle"),
>                                                   JOptionPane.ERROR_MESSAGE);

>                     return false;
>                 }

>                 input = varInfo.getName();
>             } catch (Exception e) {
>                 JOptionPane.showMessageDialog(SwingUtilities.windowForComponent(this),
>                                               e.getLocalizedMessage(),
>                                               getString("variableErrorTitle"),
>                                               JOptionPane.ERROR_MESSAGE);

>                 return false;
>             }

>             String output = (String)outputComboBox.getEditor().getItem();

>             try {
>                 VariableInfo varInfo = getContext().checkVariable(output,
>                                            new String[]{ VariableInfo.TYPE_INT });

>                 if (varInfo == null)
>                     return false;

>                 if (!(varInfo.getType().equals(VariableInfo.TYPE_INT))) {
>                     JOptionPane.showMessageDialog(SwingUtilities.windowForComponent(this),
>                                                   getString("Message_100"),
>                                                   getString("variableErrorTitle"),
>                                                   JOptionPane.ERROR_MESSAGE);

>                     return false;
>                 }

>                 output = varInfo.getName();
>             } catch (Exception e) {
>                 JOptionPane.showMessageDialog(SwingUtilities.windowForComponent(this),
>                                               e.getLocalizedMessage(),
>                                               getString("variableErrorTitle"),
>                                               JOptionPane.ERROR_MESSAGE);

>                 return false;
>             }

>             if (input == null || output == null) {
>                 JOptionPane.showMessageDialog(null, getString("Message_101"),
>                                               getString("invalidDataTitle"),
>                                               JOptionPane.ERROR_MESSAGE);

>                 return false;
>             }

>             myData.setInputVariableName(input);
>             myData.setOutputVariableName(output);

>             return true;
>         }
>     }

The following figure illustrates the resulting PluginActionPanel GUI component.

Figure 4-4 PluginActionPanel GUI Component

Refer to the following related example listings:

- CheckInventoryActionObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to read the plug-in data in XML format.

- Implementing the PluginActionData Interface shows how to read and save the plug-in data in XML format. This class extends the CheckInventoryActionObject class.

- Defining the Run-Time Component Class for an Action shows how to define the execution information for the plug-in.

- Customizing an Action Tree shows how to customize the actions and/or action categories listed in the action trees that are displayed in various dialog boxes within the Studio.

For more information about the plug-in sample, see BPM Plug-In Sample.

Defining the PluginTriggerPanel Class

To define the GUI component to be displayed in the design client when defining a plug-in Start or Event node, you must defne a class that extends the com.bea.wlpi.common.plugin.PluginTriggerPanel class. In the Studio, the Start and Event node PluginTriggerPanel classes are used by the Start Properties and Event Properties dialog box, respectively.

The following table describes the class methods that are defined by the PluginTriggerPanel class.

Note: The PluginTriggerPanel class extends the PluginPanel class. For more information about the PluginPanel class methods, see the table PluginPanel Class Methods.

Table 4-8 PluginTriggerPanel Class Methods

Method | Description
--- | ---
public java.lang.String getEventDescriptor() | Gets a string that characterizes the plug-in event descriptor. The event descriptor defines the data for which the plug-in node is watching. The expression evaluator passes the event descriptor to any instances of the associated com.bea.wlpi.common.plugin.PluginField implementation class specified by the com.bea.wlpi.common.plugin.FieldInfo object. The FieldInfo object is supplied by the parent com.bea.wlpi.common.plugin.StartInfo or com.bea.wlpi.common.plugin.EventInfo object. The method returns a java.lang.String object that specifies the event descriptor. For the default implementation this method returns null. For information about defining the plug-in field to access the plug-in-specific external event, see Defining the Run-Time Component Class for a Message Type.
public java.lang.String[] getFields() | Gets a list of field names associated with the event (if known). If this list is not null, the associated Start Properties or Event Properties dialog box passes the list to the Expression Builder. The method returns an array of java.lang.String objects that specify the field names. For the default implementation this method returns null. For information about defining the plug-in field to access a plug-in-specific external event, see Defining the Run-Time Component Class for a Message Type.

The following sections provide code examples showing how the PluginTriggerPanel class is defined.

Start Node Example

The following code listing is an excerpt from the plug-in sample that shows how to define the PluginTriggerPanel class for a Start node. This excerpt is taken from the StartNodePanel.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-13 Defining the PluginTriggerPanel Class for a Start Node

>     package com.bea.wlpi.tour.po.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import javax.swing.border.TitledBorder;
>     import javax.swing.border.EtchedBorder;
>     import java.util.List;
>     import java.util.Locale;
>     import com.bea.wlpi.common.plugin.PluginTriggerPanel;
>     import com.bea.wlpi.common.plugin.PluginPanelContext;
>     import com.bea.wlpi.common.VariableInfo;

>     public class StartNodePanel extends PluginTriggerPanel {
>         private JLabel StartOrderLabel = new JLabel();
>         private JTextArea StartOrderText = new JTextArea();

>         public StartNodePanel() {
>             this(Locale.getDefault());
>         }

>         public StartNodePanel(Locale lc) {

>             super(lc, "startorder");

>             setLayout(null);
>             setBounds(12, 12, 420, 240);
>             setPreferredSize(new Dimension(420, 240));
>             add(StartOrderLabel);
>             StartOrderLabel.setFont(new Font("Dialog", Font.BOLD, 16));
>             StartOrderLabel.setBounds(120, 12, 156, 24);
>             StartOrderText.setLineWrap(true);
>             StartOrderText.setWrapStyleWord(true);
>             StartOrderText.setEditable(false);
>             add(StartOrderText);
>             StartOrderText.setBounds(30, 48, 348, 144);
>         }

>         public void load() {

>             setResourceBundle("com.bea.wlpi.tour.po.plugin.SamplePlugin");
>             StartOrderLabel.setText(getString("startOrderLabel"));
>             StartOrderText.setText(getString("startOrderText"));
>         }

>         public boolean validateAndSave() {
>             return true;
>         }

>         public String[] getFields() {
>             return SamplePluginConstants.ORDER_FIELDS;
>         }

>         public String getEventDescriptor() {
>             return SamplePluginConstants.START_ORDER_EVENT;
>         }
>     }

The START_ORDER_EVENT and ORDER_FIELDS field element values are included within the SamplePluginConstants.java class file. They define the plug-in Start node event descriptor and field element values as follows:

>     final static String START_ORDER_EVENT = "startOrder";
>     final static String[] ORDER_FIELDS = {
>     	"CustomerName", "CustomerID", "OrderStatus", "OrderID",
>     	"CustomerEmail", "ItemName", "ItemID", "ItemQuantity",
>     	"CustomerState"
>     };

For more information about defining the plug-in field to access a plug-in-specific external event, see Defining the Run-Time Component Class for a Message Type.

The following figure illustrates the resulting PluginTriggerPanel GUI component.

Figure 4-5 PluginTriggerPanel GUI Component for a Start Node

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Start Node shows how to read the plug-in data in XML format.

- Implementing the PluginData Interface for a Start Node shows how to read and save the plug-in data in XML format.

- Defining the Run-Time Component Class for a Start Node shows how to define the execution information for the plug-in.

- Using Plug-In Run-Time Contexts shows how to define the plug-in fields that can be referenced from an evaluator expression.

For more information about the plug-in sample, see BPM Plug-In Sample.

Event Node Example

The following code listing is an excerpt from the plug-in sample that shows how to define the PluginTriggerPanel class for an Event node. This excerpt is taken from the EventNodePanel.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-14 Defining the PluginTriggerPanel Class for an Event Node

>     package com.bea.wlpi.tour.po.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import java.util.Locale;
>     import com.bea.wlpi.common.plugin.PluginTriggerPanel;
>     import com.bea.wlpi.common.plugin.PluginPanelContext;
>     import com.bea.wlpi.common.VariableInfo;

>     public class EventNodePanel extends PluginTriggerPanel {
>         private JLabel confirmOrderLabel = new JLabel();
>         private JTextArea confirmOrderText = new JTextArea();

>         /**
>          * Create a new EventNodePanel.
>          */
>         public EventNodePanel() {
>             this(Locale.getDefault());
>         }

>         public EventNodePanel(Locale lc) {

>             super(lc, "confirmevent");

>             setLayout(null);
>             setBounds(12, 12, 420, 240);
>             setPreferredSize(new Dimension(420, 240));
>             add(confirmOrderLabel);
>             confirmOrderLabel.setFont(new Font("Dialog", Font.BOLD, 16));
>             confirmOrderLabel.setBounds(144, 12, 120, 24);
>             confirmOrderText.setRequestFocusEnabled(false);
>             confirmOrderText.setLineWrap(true);
>             confirmOrderText.setWrapStyleWord(true);
>             confirmOrderText.setEditable(false);
>             add(confirmOrderText);
>             confirmOrderText.setBounds(30, 48, 348, 144);
>         }

>         public void load() {

>             setResourceBundle("com.bea.wlpi.tour.po.plugin.SamplePlugin");
>             confirmOrderLabel.setText(getString("confirmOrderLabel"));
>             confirmOrderText.setText(getString("confirmOrderText"));
>         }

>         public boolean validateAndSave() {

>             // There are no UI controls on this panel which accept user input.
>             // Therefore, there is nothing to do in this method.
>             return true;
>         }

>         public String[] getFields() {
>             return SamplePluginConstants.CONFIRM_FIELDS;
>         }

>         public String getEventDescriptor() {
>             return SamplePluginConstants.CONFIRM_EVENT;
>         }
>     }

The CONFIRM_EVENT and CONFIRM_FIELD are included within the SamplePluginConstants.java class. They define the plug-in Event node event descriptor and field element values as follows:

>     final static String CONFIRM_EVENT = "confirmOrder";
>     final static String[] CONFIRM_FIELDS = { "Status", "TotalPrice" };

For more information about defining the plug-in field to access a plug-in-specific external event, see Defining the Run-Time Component Class for a Message Type.

The following figure illustrates the resulting PluginTriggerPanel GUI component.

Figure 4-6 PluginTriggerPanel GUI Component for a Event Node

Refer to the following related example listings:

- EventObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to implement the PluginObject interface to read plug-in data.

- Implementing the PluginData Interface for an Event Node shows how to read and save the plug-in data. This class extends the EventObject class.

- Defining the Run-Time Component Class for an Event Node shows how to define the execution information for the plug-in.

For more information about the plug-in sample, see BPM Plug-In Sample.

Defining the PluginVariablePanel Class

To define the GUI component displayed in the design client when defining a plug-in variable that enables users to edit a plug-in variable type, you must define a class that extends the com.bea.wlpi.common.plugin.PluginVariablePanel class. In the Studio, the PluginVariablePanel class is used by the Update Variable dialog box.

The following table describes the class methods that are defined by the PluginVariablePanel class.

Note: The PluginVariablePanel class extends the PluginPanel class. For more information about the PluginPanel class methods, see the table PluginPanel Class Methods.

Table 4-9 PluginVariablePanel Class Methods

Method | Description
--- | ---
public final java.lang.Object getVariableValue() | Gets the value of the plug-in variable. The method returns a java.lang.Object object that specifies the variable value.
public final void setContext(java.lang.Object variableValue) | Sets the operating context for the plug-in panel. The Plug-in Manager calls this method before adding the plug-in variable panel to the Update Variable dialog box. Note: Plug-ins must not call this method. The method parameter is defined as follows. variableValue: java.lang.Object object that specifies the variable value. You can obtain the variable value using the getVariableValue() method described previously in this table.

The following code listing shows how to define the PluginVariablePanel class. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-15 Defining the PluginVariablePanel Class

>     package com.bea.wlpi.test.plugin;

>     import java.awt.*;
>     import javax.swing.*;
>     import javax.swing.border.TitledBorder;
>     import javax.swing.border.EtchedBorder;
>     import java.util.List;
>     import java.util.Locale;
>     import com.bea.wlpi.client.studio.Studio;
>     import com.bea.wlpi.common.VariableInfo;
>     import com.bea.wlpi.common.plugin.PluginVariablePanel;

>     public class VariablePanel extends PluginVariablePanel {
>         JTextField highField, lowField;

>         public VariablePanel() {
>             super(Locale.getDefault(), "augustus");
>             setLayout(null);
>             setBounds(12,12,420,60);
>             highField = new JTextField();
>             highField.setLocation(20, 10);
>             highField.setSize(300, 20);
>             add(highField);
>             lowField = new JTextField();
>             lowField.setLocation(20, 40);
>             lowField.setSize(300, 20);
>             add(lowField);
>         }

>         public void load() {
>             if (variableValue != null) {
>                 highField.setText(((MySpecificObject)variableValue).getHigh());
>                 lowField.setText(((MySpecificObject)variableValue).getLow());
>             } else {
>                 highField.setText("");
>                 lowField.setText("");
>             }
>         }

>         public boolean validateAndSave() {
>             try {
>                 variableValue = new MySpecificObject(lowField.getText(), highField.getText());
>             } catch (Exception e) {
>                 return false;
>             }
>             return true;
>         }
>     }

The following figure illustrates the resulting PluginVariablePanel GUI component.

Figure 4-7 PluginVariablePanel GUI Component

Refer to the related example listing, Defining the PluginVariableRenderer Class, which shows how to display the value of a plugin-defined variable type in the cell of a javax.swing.JTable.

Defining the PluginVariableRenderer Class

To display the value of a plugin-defined variable type in the cell of a javax.swing.JTable, implement the com.bea.wlpi.common.plugin.PluginVariableRenderer interface.

Note: Classes implementing this interface must be subclasses of java.awt.Component.

The following table describes the PluginVariableRenderer interface method that you must implement.

Table 4-10 PluginVariableRenderer Interface Method

Method | Description
--- | ---
public void setValue(java.lang.Object value) | Sets the variable to be displayed. The method parameter is defined as follows. value: java.lang.Object object that specifies the variable value to be displayed. This value can be either null or an instance of the class declared in the corresponding com.bea.wlpi.common.plugin.VariableTypeInfo object.

The following code listing shows how to display the value of a plugin-defined variable type in the cell of a javax.swing.JTable. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-16 Defining the PluginVariableRenderer Class

>     package com.bea.wlpi.test.plugin;

>     import java.io.Serializable;
>     import javax.swing.JLabel;
>     import com.bea.wlpi.common.plugin.PluginVariableRenderer;

>     public class VariableRenderer extends JLabel implements PluginVariableRenderer, Serializable {
>         public VariableRenderer() {
>         }

>         public void setValue(Object value) {
>             if (value == null)
>                 setText("null");
>             else
>                 setText(value.toString());
>         }
>     }

Refer to Defining the PluginVariablePanel Class, which shows how to display the plug-in GUI component in the design client.

Executing the Plug-In

To execute the plug-in, you must define the run-time component class for the plug-in.

The following table describes the plug-in component interfaces that you must implement based on the type of plug-in component being created. To enable the plug-in to read (parse) the incoming data, the run-time component class must implement the load() (parsing) method of its parent interface, com.bea.wlpi.common.plugin.PluginObject.

Note: The following two plug-in components do not need to define execution information: variable types, workflow template properties, or workflow template definition properties.

Table 4-11 Plug-In Run-Time Component Interfaces

To define the following plug-in . . . | You must implement . . . | To define . . .
--- | --- | ---
Action | com.bea.wlpi.server.plugin.PluginAction | Plug-in action execution information. Note: To support plug-in actions, you must also customize the actions and/or action categories listed in the action trees that are displayed in various dialog boxes within the Studio.
Done node | com.bea.wlpi.server.plugin.PluginDone | Plug-in Done node execution information. Note: The PluginDone interface extends the com.bea.wlpi.server.plugin.PluginTemplateNode interface. For more information, see PluginTemplateNode Interface.
Event node | com.bea.wlpi.server.plugin.PluginEvent | Plug-in event node execution information.
Function | com.bea.wlpi.common.plugin.PluginFunction | New evaluator function information.
Message type | com.bea.wlpi.server.plugin.PluginField | Plug-in-specific message types.
Start node | com.bea.wlpi.server.plugin.PluginStart2 | Plug-in Start node execution information. Note: The PluginStart2 interface extends the com.bea.wlpi.server.plugin.PluginTemplateNode interface. For more information, see PluginTemplateNode Interface.

Note: At run time you can use context interfaces that are passed by the Plug-in Manager to access the run-time context and services for the associated plug-in. For information about the context interfaces, see Using Plug-In Run-Time Contexts.

The following sections explain in detail how to define each of the plug-in run-time component classes.

Defining the Run-Time Component Class for an Action

To define the run-time component class for a plug-in action, you must:

- Implement the com.bea.wlpi.server.plugin.PluginAction interface to define the plug-in action execution information.

- Customize the actions and/or action categories listed in the action trees that are displayed in various dialog boxes within the Studio.

Defining the Execution Information for a Plug-In Action

To define the execution information for a plug-in action, you must implement the com.bea.wlpi.server.plugin.PluginAction interface and its methods, as described in the following table.

Table 4-12 PluginAction Interface Methods

Method | Description
--- | ---
public int execute(com.bea.wlpi.server.plugin.ActionContext actionContext, com.bea.wlpi.server.common.ExecutionContext execContext) throws com.bea.wlpi.common.WorkflowException | Executes the plug-in action and its business logic. The method parameters are defined as follows: actionContext: com.bea.wlpi.server.plugin.ActionContext object that specifies the action context. The action context provides action-level services, such as the execution of subactions and subworkflow instantiation. execContext: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. For more information about the action and execution contexts, see Using Plug-In Run-Time Contexts. This method returns one of the following com.bea.wlpi.server.common.ExecutionContext integer values, indicating the return code, that specifies whether or not processing should continue: EXIT_CONTINUE: Exit an error handler and permit processing of subsequent operations. EXIT_RETRY: Exit an error handler and request the retry of the failed operation. EXIT_ROLLBACK: Exit an error handler and request the rollback of the user transaction. STOP: Stop the plug-in execution.
public void fixup(com.bea.wlpi.evaluator.ExpressionParser parser) throws com.bea.wlpi.common.WorkflowException | Enables plug-in actions to compile the necessary expressions. The Plug-in Manager calls this method after parsing the template definition and storing it in memory, and prior to starting the workflow. The method parameter is defined as follows. parser: com.bea.wlpi.evaluator.ExpressionParser object that specifies the expression parser.
public void response(com.bea.wlpi.server.plugin.ActionContext actionContext, com.bea.wlpi.server.common.ExecutionContext execContext, java.lang.Object data) throws com.bea.wlpi.common.WorkflowException | Processes an asynchronous response directed to this action. Typically, this method is returned as a response to an external request that the action raised in a prior call to its execute() method (described earlier in this table). Plug-in actions can use this method to initiate, for example, the asynchronous execution of a subaction list. The Plug-in Manager calls this method when it receives a call to the com.bea.wlpi.server.worklist.Worklist.response() method or another overload method. The method parameters are defined as follows: actionContext: com.bea.wlpi.server.plugin.ActionContext object that specifies the action context. The action context provides action-level services such as the execution of subactions and subworkflow instantiation. execContext: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. data: java.lang.Object object that specifies the data object that the plug-in casts to a known type in order to extract the required information. For more information about the action and execution contexts, see Using Plug-In Run-Time Contexts.
public void startedWorkflowDone(com.bea.wlpi.server.plugin.ActionContext actionContext, com.bea.wlpi.server.common.ExecutionContext execContext, com.bea.wlpi.common.VariableInfo[] output) throws com.bea.wlpi.common.WorkflowException | Notifies the plug-in action that a subworkflow that it had previously started is now complete. The method parameters are defined as follows: actionContext: com.bea.wlpi.server.plugin.ActionContext object that specifies the action context. The action context provides action-level services, such as the execution of subactions and subworkflow instantiation. execContext: com.bea.wlpi.common.common.ExecutionContext object that specifies the execution context. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. output: com.bea.wlpi.common.VariableInfo array that specifies the output variables of the called workflow. For more information about the action and execution contexts, see Using Plug-In Run-Time Contexts.

The following code listing is an excerpt from the plug-in sample that shows how to define the run-time component class for an action. This excerpt is taken from the CheckInventoryAction.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Note: Refer to the SendConfirmationAction.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory for another example of how to define the plug-in action run-time component class.

Listing 4-17 Defining the Run-Time Component Class for an Action

>     package com.bea.wlpi.tour.po.plugin;

>     import java.io.IOException;
>     import com.bea.wlpi.server.plugin.PluginAction;
>     import com.bea.wlpi.common.WorkflowException;
>     import com.bea.wlpi.common.plugin.PluginException;
>     import com.bea.wlpi.common.Messages;
>     import com.bea.wlpi.common.VariableInfo;
>     import com.bea.wlpi.evaluator.Expression;
>     import com.bea.wlpi.evaluator.EvaluatorException;
>     import com.bea.wlpi.server.common.ExecutionContext;
>     import com.bea.wlpi.evaluator.ExpressionParser;
>     import com.bea.wlpi.server.plugin.ActionContext;
>     import org.xml.sax.*;

>     public class CheckInventoryAction extends CheckInventoryActionObject
>             implements PluginAction {
>         private Expression inputValueExpression;
>         static int[] quantities = {
>             250, 120, 5, 75, 0, 300, 550, 25, 16, 630, 3
>         };

>         public CheckInventoryAction() {
>         }

>         public void fixup(ExpressionParser parser) {

>             System.out.println("SamplePlugin: CheckInventoryAction.fixup called");

>             try {
>                 inputValueExpression =
>                     inputVariableName != null
>                     ? new Expression("$" + inputVariableName, parser) : null;
>             } catch (EvaluatorException ee) {
>                 System.out.println("EvaluationException ocurred in CheckInventoryAction");
>             }
>         }

>         public int execute(ActionContext actionContext, ExecutionContext context)
>                 throws WorkflowException {

>             System.out.println("SamplePlugin: CheckInventoryAction.execute called");

>             Object valueObject = inputValueExpression != null
>                                  ? inputValueExpression.evaluate(context) : null;

>             if (valueObject == null)
>                 throw new PluginException("Sample Plugin", "itemNo is null");

>             if (!(valueObject instanceof Long))
>                 throw new PluginException("Sample Plugin", "itemNo not an integer");

>             int itemNo = ((Long)valueObject).intValue();
>             int quantity = quantities[itemNo % quantities.length] + itemNo;

>             System.out.println("CheckInventoryAction: Output = " + quantity);
>             context.setVariableValue(outputVariableName, new Long(quantity));

>             return ExecutionContext.CONTINUE;
>         }

>         public void response(ActionContext actionContext, ExecutionContext execContext, Object data)
>                 throws WorkflowException {
>         }

>         public void startedWorkflowDone(ActionContext actionContext,
>                                         ExecutionContext context,
>                                         VariableInfo[] output) {
>         }

Refer to the following related example listings:

- CheckInventoryActionObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to read the plug-in data in XML format.

- Implementing the PluginActionData Interface shows how to read and save the plug-in data in XML format. This class extends the CheckInventoryActionObject class.

- Defining the PluginActionPanel Class shows how to display the plug-in GUI component in the design client.

- Customizing an Action Tree shows how to customize the actions and/or action categories listed in the action trees that are displayed in various dialog boxes within the Studio.

For more information about the plug-in sample, see BPM Plug-In Sample.

Customizing the Action Tree

To support plug-in actions, you must customize the actions and/or action categories listed in the action trees that are displayed in various dialog boxes within the Studio.

For example, the following figure illustrates the Add Action dialog box with a customized version of the action tree.

Figure 4-8 Customized Action Tree

As shown in the previous figure, the BPM action tree has been customized to add one new action category, Sample Actions, that provides the following plug-in actions:

- Checks available inventory for an item

- Sends Confirm Order Event

You can customize the action tree by performing the following steps:

1. Define a com.bea.wlpi.common.plugin.CategoryInfo object that, in turn, defines the custom plug-in actions and/or action categories.

   For information about creating a CategoryInfo object, see Defining Plug-In Value Objects.

2. Implement the com.bea.wlpi.server.plugin.Plugin remote interface getPluginCapabilitiesInfo() method to define the com.bea.wlpi.common.plugin.PluginCapabilitiesInfo object.

   Use the CategoryInfo object defined in step 1 to define the custom action tree characteristics.

When the Plug-in Manager calls the getPluginCapabilitiesInfo() method, it must pass the existing action category tree as a com.bea.wlpi.common.plugin.CategoryInfo object to enable the plug-in to traverse the tree and determine where to add the custom actions and/or action categories. Once the Plug-in Manager retrieves this valid tree structure, it merges the retrieved tree structure with the existing tree structure and assigns a new systemID to each new category.

The Plug-in Manager can call the getPluginCapabilitiesInfo() method multiple times, and you must return a newly initialized action tree each time. If you reuse an existing CategoryInfo object, the Plug-in Manager raises an IllegalStateException when it calls the setSystemID() method for the second time.

You can add new actions and/or subcategories to existing action categories at any leve., You cannot, however, remove actions or subcategories from an existing category.

The following code listing is an excerpt from the plug-in sample that shows how to define the following methods:

- getCategoryInfo() method, which lets you define a CategoryInfo object that, in turn, defines the custom plug-in actions and action categories.

- getPluginCapabilitiesInfo() method, which enables you to customize the action tree.

This excerpt is taken from the SamplePluginBean.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. The example defines both the Check Inventory and Send Confirmation actions. Notable lines of code are shown in bold.

Listing 4-18 Customizing an Action Tree

>     private CategoryInfo[] getCategoryInfo(SampleBundle bundle) {

>         ActionInfo checkInventoryAction =
>                 new ActionInfo(SamplePluginConstants.PLUGIN_NAME, 1,
>                         bundle.getString("checkInventoryName"),
>                         bundle.getString("checkInventoryDesc"), ICON_BYTE_ARRAY,
>                         ActionCategoryInfo.ID_NEW,
>                         ActionInfo.ACTION_STATE_ALL,
>                         SamplePluginConstants.CHECKINV_CLASSES);

>         ActionInfo sendConfirmAction =
>                 new ActionInfo(SamplePluginConstants.PLUGIN_NAME, 2,
>                         bundle.getString("sendConfirmName"),
>                         bundle.getString("sendConfirmDesc"), ICON_BYTE_ARRAY,
>                         ActionCategoryInfo.ID_NEW,
>                         ActionInfo.ACTION_STATE_ALL,
>                         SamplePluginConstants.SENDCONF_CLASSES);

>         ActionCategoryInfo[] actions =
>                 new ActionCategoryInfo[]{ checkInventoryAction, sendConfirmAction};

>         CategoryInfo[] catInfo =
>                 new CategoryInfo[]{ new CategoryInfo(SamplePluginConstants.PLUGIN_NAME,
>                         0, bundle.getString("catName"),
>                         bundle.getString("catDesc"),
>                         ActionCategoryInfo.ID_NEW,
>                         actions)};
>         return catInfo;
>     }

>     public PluginCapabilitiesInfo getPluginCapabilitiesInfo(Locale lc,
>             CategoryInfo[] info) {

>         PluginInfo pi;
>         FieldInfo orderFieldInfo;
>         FieldInfo confirmFieldInfo;
>         FieldInfo[] fieldInfo;
>         FunctionInfo fi;
>         FunctionInfo[] functionInfo;
>         StartInfo si;
>         StartInfo[] startInfo;
>         EventInfo ei;
>         EventInfo[] eventInfo;
>         SampleBundle bundle = new SampleBundle(lc);

>         log("getPluginCapabilities called");

>         pi = createPluginInfo(lc);

>         orderFieldInfo =
>                 new FieldInfo(SamplePluginConstants.PLUGIN_NAME, 3,
>                         bundle.getString("orderFieldName"),
>                         bundle.getString("orderFieldDesc"),
>                         SamplePluginConstants.ORDER_FIELD_CLASSES, false);

>         confirmFieldInfo =
>                 new FieldInfo(SamplePluginConstants.PLUGIN_NAME, 4,
>                         bundle.getString("confirmFieldName"),
>                         bundle.getString("confirmFieldDesc"),
>                         SamplePluginConstants.CONFIRM_FIELD_CLASSES, false);

>         fieldInfo = new FieldInfo[]{ orderFieldInfo, confirmFieldInfo};

>         ei = new EventInfo(SamplePluginConstants.PLUGIN_NAME, 6,
>                            bundle.getString("confirmOrderName"),
>                            bundle.getString("confirmOrderDesc"), ICON_BYTE_ARRAY,
>                            SamplePluginConstants.EVENT_CLASSES,
>                            confirmFieldInfo);

>         eventInfo = new EventInfo[]{ ei};

>         fi = new FunctionInfo(SamplePluginConstants.PLUGIN_NAME, 7,
>                 bundle.getString("calcTotalName"),
>                 bundle.getString("calcTotalDesc"),
>                 bundle.getString("calcTotalHint"),
>                 SamplePluginConstants.FUNCTION_CLASSES, 3, 3);

>         functionInfo = new FunctionInfo[]{ fi};

>         si = new StartInfo(SamplePluginConstants.PLUGIN_NAME, 5,
>                 bundle.getString("startOrderName"),
>                 bundle.getString("startOrderDesc"), ICON_BYTE_ARRAY,
>                 SamplePluginConstants.START_CLASSES, orderFieldInfo);

>         startInfo = new StartInfo[]{ si};

>         PluginCapabilitiesInfo pci = new PluginCapabilitiesInfo(pi,
>                 getCategoryInfo(bundle), eventInfo, fieldInfo, functionInfo, startInfo,
>                 null, null, null, null, null);

>         return pci;
>     }

Refer to the following related example listings:

- CheckInventoryActionObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to read the plug-in data in XML format.

- Implementing the PluginActionData Interface shows how to read and save the plug-in data in XML format. This class extends the CheckInventoryActionObject class.

- Defining the PluginActionPanel Class shows how to display the plug-in GUI component in the design client.

- Defining the Run-Time Component Class for an Action shows how to define the plug-in execution information.

For more information about the plug-in sample, see BPM Plug-In Sample.

Defining the Run-Time Component Class for a Done Node

To define the run-time component class for a Done node, implement the com.bea.wlpi.server.plugin.PluginDone interface.

Note: The PluginDone interface extends com.bea.wlpi.server.plugin.PluginTemplateNode. For more information about the PluginTemplateNode interface and its methods, see PluginTemplateNode Interface.

The PluginDone interface adds no other methods.

The following code listing shows how to define the run-time component class for a Done node. Notable lines of code are shown in bold.

Note: This class is not available as part of the plug-in sample.

Listing 4-19 Defining the Run-Time Component Class for a Done Node

>     package com.bea.wlpi.test.plugin;

>     import com.bea.wlpi.common.Messages;
>     import com.bea.wlpi.common.WorkflowException;
>     import com.bea.wlpi.evaluator.ExpressionParser;
>     import com.bea.wlpi.server.common.ExecutionContext;
>     import com.bea.wlpi.server.plugin.PluginDone;
>     import java.io.IOException;
>     import java.util.Map;
>     import org.xml.sax.*;

>     public class DoneNode extends DoneObject implements PluginDone {
>         public DoneNode() {
>         }

>         public int activate(ExecutionContext context)
>             throws WorkflowException {

>             System.out.println("TestPlugin: DoneNode activated");

>             // Initialize the plugin instance data.
>             Map instanceData = (Map)context.getPluginInstanceData(TestPluginConstants.PLUGIN_NAME);
>             if (instanceData != null) {
>                 Object started = instanceData.get(TestPluginConstants.INST_DATA_STARTED);
>                 System.out.println("instance data = " + started);
>             }

>             int stopMode;
>             if (yesOrNo.equals(TestPluginConstants.DONE_YES)) {
>                 System.out.println("TestPlugin: DoneNode = YES");
>                 stopMode = ExecutionContext.CONTINUE;
>             } else {
>                 System.out.println("TestPlugin: DoneNode = NO");
>                 stopMode = ExecutionContext.STOP;
>             }

>             return stopMode;
>         }

>         public void fixup(ExpressionParser parser) {
>         }

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Done Node shows how to read the plug-in data in XML format.

- Implementing the PluginData Interface for a Done Node shows how to read and save the plug-in data in XML format. This class extends the PluginObject class.

- Defining the PluginPanel Class for a Done Node shows how to define plug-in GUI component.

Defining the Run-Time Component Class for an Event Node

To define the run-time component class for an event node, implement the com.bea.wlpi.server.plugin.PluginEvent interface.

The following table describes the PluginEvent interface methods that you must implement as part of the run-time component class.

Table 4-13 PluginEvent Interface Methods

Method | Description
--- | ---
public int activate(com.bea.wlpi.server.common.EventContext eventContext, com.bea.wlpi.server.common.ExecutionContext execContext) throws com.bea.wlpi.common.WorkflowException | Activates the event. The Event Processor calls this method when the matching event is activated by an incoming transition from a predecessor node. Plug-ins then record an event watch to enable the Event Processor to match an incoming event to this particular node and workflow instance. Plug-ins can use the default event watch registration, addressed message handling, and the event matching facility by calling the activateEvent() method to the to the com.bea.wlpi.server.plugin.EventContext. Plug-ins are responsible for recording the necessary information and providing an event handler to preform the run-time matching based on the defined criteria. For more information about processing plug-in events, see Processing Plug-In Events. Note: If the plug-in does not rely on the BPM JMS event listener, then it is not required to provide an event handler. The method parameters are defined as follows: eventContext: com.bea.wlpi.server.plugin.EventContext object that specifies the event context. The event context provides access to run-time event-related services, such as event watch registration. execContext: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. For more information about the event and execution contexts, see Using Plug-In Run-Time Contexts. This method returns one of the following com.bea.wlpi.server.common.ExecutionContext integer values, indicating the return code, that specifies whether or not to processing should continue after the event is activated: CONTINUE: Continue processing. STOP: Stop processing.
public void fixup(com.bea.wlpi.evaluator.ExpressionParser parser) throws com.bea.wlpi.common.WorkflowException | Enables the plug-in node to compile the necessary expressions. The Plug-in Manager calls this method after parsing the template definition and storing it in memory, and prior to starting the workflow. The method parameter is defined as follows. parser: com.bea.wlpi.evaluator.ExpressionParser object that specifies the expression parser.
public int trigger(com.bea.wlpi.server.common.EventContext eventContext, com.bea.wlpi.server.common.ExecutionContext execContext) throws com.bea.wlpi.common.WorkflowException | Triggers the event. The Event Processor calls this method when it detects an incoming event that matches the criteria for this event node. Plug-ins that use the default event watch registration and matching services must call the removeEventWatch() method to the com.bea.wlpi.server.plugin.EventContext to place the event in the nonlistening state. Plug-ins that do not use the default event watch registration and matching services must deactivate whatever plug-in-supplied event watch record was established for this node in the prior activate() call. The plug-in must provide an event handler if the event arrives via the BPM JMS event listener. Otherwise, it must implement its own event listener service. For more information about defining an event handler, see Processing Plug-In Events. The method parameters are defined as follows: eventContext: com.bea.wlpi.server.plugin.EventContext object that specifies the event context. The event context provides access to run-time event-related services such as event watch registration. execContext: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. For more information about the event and execution contexts, see Using Plug-In Run-Time Contexts. This method returns one of the following com.bea.wlpi.server.common.ExecutionContext integer values indicating the return code that specifies whether or not to processing should continue after the event is triggered: CONTINUE: Continue processing. STOP: Stop processing.

The following code listing is an excerpt from the plug-in sample that shows how to define the run-time component class for an Event node. This excerpt is taken from the StartNode.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-20 Defining the Run-Time Component Class for an Event Node

>     package com.bea.wlpi.tour.po.plugin;

>     import java.io.IOException;
>     import com.bea.wlpi.server.plugin.PluginEvent;
>     import com.bea.wlpi.common.WorkflowException;
>     import com.bea.wlpi.common.Messages;
>     import com.bea.wlpi.evaluator.Expression;
>     import com.bea.wlpi.evaluator.EvaluatorException;
>     import com.bea.wlpi.server.common.ExecutionContext;
>     import com.bea.wlpi.server.plugin.EventContext;
>     import com.bea.wlpi.server.workflow.Workflow;
>     import com.bea.wlpi.server.workflow.Variable;
>     import com.bea.wlpi.evaluator.ExpressionParser;
>     import com.bea.wlpi.server.workflow.TemplateNode;
>     import org.xml.sax.*;

>     public class EventNode extends EventObject implements PluginEvent {

>         public EventNode() {
>         }

>         public int activate(EventContext eventContext, ExecutionContext execContext)
>                 throws WorkflowException {

>             System.out.println("SamplePlugin: EventNode activated");
>             eventContext.activateEvent(execContext,
>                                        SamplePluginConstants.CONTENTTYPE,
>                                        eventDesc, null, null);

>             return ExecutionContext.CONTINUE;
>         }

>         public int trigger(EventContext context, ExecutionContext execContext)
>                 throws WorkflowException {

>             System.out.println("SamplePlugin: EventNode triggered");
>             context.removeEventWatch(execContext);

>             return ExecutionContext.CONTINUE;
>         }

>         public void fixup(ExpressionParser parser) {
>         }
>     }

Refer to the following related example listings:

- EventObject.java in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory shows how to implement the PluginObject interface to read plug-in data.

- Implementing the PluginData Interface for an Event Node shows how to read and save the plug-in data. This class extends the EventObject class.

- Defining the PluginTriggerPanel Class for an Event Node shows how to display the plug-in GUI component in the design client.

For more information about the plug-in sample, see BPM Plug-In Sample.

Defining the Run-Time Component Class for a Function

To define the run-time component class for a function, implement the com.bea.wlpi.common.plugin.PluginFunction interface. The following table describes the PluginFunction interface method that you must implement.

Table 4-14 PluginFunction Interface Method

Method | Description
--- | ---
public java.lang.Object evaluate(com.bea.wlpi.evaluator.EvaluationContext context, java.lang.Object[] args ) throws com.bea.wlpi.common.plugin.PluginException | Evaluates the function. The expression evaluator calls this method when it needs to evaluate this function call. The plug-in function can calculate its return value from the contextual information supplied via the context parameter. This parameter provides access to event data and the workflow instance state (where appropriate). The method parameters are defined as follows: context: com.bea.wlpi.evaluator.EvaluationContext object that specifies the evaluation context. args: Array of java.lang.Object values that specifies the parameter values. The values are precalculated through the evaluation of the expressions that represent the function arguments in the source expression. This method returns a java.lang.Object object that specifies the function evaluation results.

The following code listing is an excerpt from the plug-in sample that shows how to define the run-time component class for a function. This excerpt is taken from the CalculateTotalPriceFunction.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-21 Defining a Run-Time Component Class for a Function

>     package com.bea.wlpi.tour.po.plugin;

>     import com.bea.wlpi.common.Messages;
>     import com.bea.wlpi.common.plugin.PluginFunction;
>     import com.bea.wlpi.common.plugin.PluginException;
>     import com.bea.wlpi.evaluator.*;
>     import com.bea.wlpi.tour.po.BadStateException;
>     import java.lang.NumberFormatException;

>     /**
>      * This sample function calculates the total price of an order.  The price is
>      * calculated using the itemID, quantity, and the State/Province of the order.
>      * The State/Province is used to look up the sales tax rate.
>      */
>     public class CalculateTotalPriceFunction implements PluginFunction {
>         static StateTax[] stateTax = {
>             new StateTax("AB", 0.07), new StateTax("AK", 0.06),
>             new StateTax("AL", 0.06), new StateTax("AR", 0.03),
>             new StateTax("AZ", 0.05), new StateTax("BC", 0.05),
>             new StateTax("CA", 0.04), new StateTax("CO", 0.08),
>             new StateTax("CT", 0.03), new StateTax("DC", 0.05),
>             new StateTax("DE", 0.05), new StateTax("FL", 0.00),
>             new StateTax("GA", 0.06), new StateTax("HI", 0.07),
>             new StateTax("IA", 0.07), new StateTax("ID", 0.08),
>             new StateTax("IL", 0.06), new StateTax("IN", 0.03),
>             new StateTax("KS", 0.05), new StateTax("KY", 0.07),
>             new StateTax("LA", 0.06), new StateTax("MA", 0.05),
>             new StateTax("MB", 0.05), new StateTax("MD", 0.04),
>             new StateTax("ME", 0.04), new StateTax("MI", 0.03),
>             new StateTax("MN", 0.05), new StateTax("MO", 0.06),
>             new StateTax("MS", 0.07), new StateTax("MT", 0.07),
>             new StateTax("NB", 0.08), new StateTax("NC", 0.07),
>             new StateTax("ND", 0.08), new StateTax("NE", 0.03),
>             new StateTax("NF", 0.06), new StateTax("NH", 0.09),
>             new StateTax("NJ", 0.03), new StateTax("NM", 0.06),
>             new StateTax("NV", 0.03), new StateTax("NY", 0.06),
>             new StateTax("NS", 0.08), new StateTax("NT", 0.07),
>             new StateTax("OH", 0.07), new StateTax("OK", 0.02),
>             new StateTax("ON", 0.08), new StateTax("OR", 0.08),
>             new StateTax("PA", 0.07), new StateTax("PE", 0.07),
>             new StateTax("PQ", 0.05), new StateTax("RI", 0.05),
>             new StateTax("SC", 0.05), new StateTax("SD", 0.04),
>             new StateTax("SK", 0.04), new StateTax("TN", 0.06),
>             new StateTax("TX", 0.06), new StateTax("UT", 0.07),
>             new StateTax("VA", 0.07), new StateTax("VT", 0.08),
>             new StateTax("WA", 0.07), new StateTax("WI", 0.07),
>             new StateTax("WV", 0.08), new StateTax("WY", 0.05),
>             new StateTax("YT", 0.07)
>         };
>         static double[] prices = {
>             29.95, 524.79, 33.21, 9.99, 12.28, 152.50, 43.55, 32.90, 328.55, 72.50,
>             87.50
>         };

>         public CalculateTotalPriceFunction() throws EvaluatorException {
>             System.out.println("CalculateTotalPriceFunction: constructor called");
>         }

>         public Object evaluate(EvaluationContext context, Object[] args)
>                 throws PluginException {

>             int itemNo;
>             int quantity;
>             String state;

>             System.out.println("CalculateTotalPriceFunction: evaluate called");

>             try {
>                 itemNo = ((Long)args[0]).intValue();
>             } catch (Exception e) {
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "Invalid ItemID argument");
>             }

>             try {
>                 quantity = ((Long)args[1]).intValue();
>             } catch (Exception e2) {
>                 e2.printStackTrace();

>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "Invalid Quantity argument");
>             }

>             if (!(args[2] instanceof String)) {
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "Invalid State argument");
>             }

>             state = (String)args[2];

>             int i;

>             // Find the state/province in the stateTax array
>             for (i = 0; i < stateTax.length; ++i) {
>                 if (stateTax[i].equals(state))
>                     break;
>             }

>             if (i == stateTax.length)
>                 throw new PluginException(new BadStateException("Invalid state abbreviation: "
>                         + state));

>             double total = (prices[itemNo % prices.length] + itemNo / prices.length)
>                            * quantity * (1 + stateTax[i].getTax());

>             return new Double(total);
>         }
>     }

>     class StateTax {
>         String abbrev;
>         double tax;

>         public boolean equals(String abbrev) {
>             return this.abbrev.equalsIgnoreCase(abbrev);
>         }

>         public double getTax() {
>             return tax;
>         }

>         public StateTax(String abbrev, double tax) {
>             this.abbrev = abbrev;
>             this.tax = tax;
>         }
>     }

For more information about the plug-in sample, see BPM Plug-In Sample.

Defining the Run-Time Component Class for a Message Type

To define the run-time component class for a message type, you must implement the com.bea.wlpi.common.plugin.PluginField interface to define a plug-in field. A plug-in field enables you to parse custom plug-in data that is associated with an external event received by a Start or Event node. The data can then be referenced from an evaluator expression. The plug-in determines the content type of the external event by accessing the associated event descriptor.

The plug-in framework uses the plug-in field data to populate the Expression Builder dialog box. For example, the following figure shows an Expression Builder dialog box in which the plug-in Fields category is selected, resulting in the display of a list of valid field elements.

Figure 4-9 Plug-In Fields Displayed in an Expression Builder Dialog Box

To define a plug-in field, implement the com.bea.wlpi.common.plugin.PluginField interface. The following table describes the PluginField interface methods that you must implement.

Table 4-15 PluginField Interface Methods

Method | Description
--- | ---
public java.lang.Object evaluate(com.bea.wlpi.evaluator.EvaluationContext context) throws com.bea.wlpi.common.plugin.PluginException | Evaluates the field. The expression evaluator calls this method when it needs to retrieve the value of the field referenced by this object from the event contained in the evaluation context parameter. When calculating its value, the plug-in field must take into account its field qualifiers. The method parameter is defined as follows. context: com.bea.wlpi.evaluator.EvaluationContext object that specifies the evaluation context. This method returns a java.lang.Object object that specifies the field evaluation results.
public void init(java.lang.String name, java.lang.String eventDescriptor) throws com.bea.wlpi.common.plugin.PluginException | Initializes the values for the field name and event descriptor. The Plug-in Manager uses the name of the field whose value is requested in the context of the event descriptor. A field type can support one or more message types. If multiple message types are supported, the field type uses the event descriptor to distinguish between types. The method parameters are defined as follows: name: java.lang.String object that specifies the field name. eventDescriptor: java.lang.String object that specifies the field event descriptor.
public void setQualifier(com.bea.wlpi.server.plugin.PluginField qualifier) throws com.bea.wlpi.common.plugin.PluginException | Sets the field qualifier. The Plug-in Manager calls this method when the expression parser encounters a qualified field reference. This method provides the plug-in fields with an opportunity to access external data dictionary information and retrieve column details to be saved as part of the compiled expression. The method parameter is defined as follows. qualifier: com.bea.wlpi.common.plugin.PluginField object that specifies the field qualifier of the same class as this object.

The following code listing is an excerpt from the plug-in sample that shows how to define a run-time component class for a message type. The plug-in field processes a single message type containing data associated with a customer order. The data is in String format, and the individual data elements are separated by semicolons. The plug-in field expects the external event data to be provided as a string buffer containing values that are delimited by semicolons. In the execute() method, the class performs some simple validation of the event data, and returns the String object for the requested field name. This excerpt is taken from the OrderField.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-22 Defining the Run-Time Component Class for a Message Type

>     package com.bea.wlpi.tour.po.plugin;

>     import com.bea.wlpi.common.plugin.PluginException;
>     import com.bea.wlpi.common.plugin.PluginField;
>     import com.bea.wlpi.evaluator.EvaluationContext;
>     import com.bea.wlpi.server.eventprocessor.EventData;
>     import java.util.StringTokenizer;

>     /*
>      * This sample field type expects a string buffer with semicolon delimited
>      * field values.  The fields are in a fixed order.
>      */

>     public final class OrderField implements PluginField {
>         private String docType;
>         private String name;

>         public void init(String name, String eventDescriptor)
>                 throws PluginException {
>             this.name = name;
>             docType = eventDescriptor;
>         }

>         public void setQualifier(PluginField qualifier) throws PluginException {

>             System.out.println("OrderField.setQualifier(" + qualifier + ')');

>             throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                       "Qualifiers are not supported");
>         }

>         public Object evaluate(EvaluationContext context) throws PluginException {

>             // Get the event data and check that it is a String object.
>             EventData eventData = context.getEventData();

>             if (eventData == null)
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "The event data is null.");

>             docType = eventData.getEventDescriptor();

>             if (!docType.equals(SamplePluginConstants.START_ORDER_EVENT))
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "The event descriptor is invalid.");

>             Object object = eventData.getContent();

>             if (!(object instanceof String))
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "The event data is invalid.");

>             // Check to make sure the field name is valid
>             int i;

>             for (i = 0; i < SamplePluginConstants.ORDER_FIELDS.length; i++) {
>                 if (SamplePluginConstants.ORDER_FIELDS[i].equals(name))
>                     break;
>             }

>             // Was the field name found in the list of valid field names?
>             if (i == SamplePluginConstants.ORDER_FIELDS.length)
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "The field name " + name
>                                           + " is invalid.");

>             String data = (String)object;
>             StringTokenizer st = new StringTokenizer(data, ";");
>             String token = null;

>             while (st.hasMoreTokens() && i >= 0) {
>                 token = st.nextToken();

>                 i--;
>             }

>             // Did the data ran out of fields prior to finding the one required?
>             if (i >= 0) {
>                 throw new PluginException(SamplePluginConstants.PLUGIN_NAME,
>                                           "The event data is invalid.");
>             }

>             String value = token;

>             System.out.println("OrderField: name = " + name + ", value = " + value);

>             // Return the text value.
>             return value;
>         }
>     }

The ORDER_FIELDS value is defined within the SamplePluginConstants.java class file as follows:

>     final static String[] ORDER_FIELDS = {
>          "CustomerName", "CustomerID", "OrderStatus", "OrderID",
>          "CustomerEmail", "ItemName", "ItemID", "ItemQuantity",
>          "CustomerState"
>     };

The figure Plug-In Fields Displayed in an Expression Builder Dialog Box shows the field elements populated within the Expression Builder dialog box.

For more information about the plug-in sample, see BPM Plug-In Sample.

Defining the Run-Time Component Class for a Start Node

To define the run-time component class for a Start node, implement the com.bea.wlpi.server.plugin.PluginStart2 interface. The following table describes the PluginStart2 interface method that you must implement.

Note: The PluginStart2 interface inherits methods from the com.bea.wlpi.server.plugin.PluginTemplateNode interface. For more information, see PluginTemplateNode Interface.

Table 4-16 PluginStart2 Interface Method

Method | Description
--- | ---
public void setTrigger(com.bea.wlpi.server.plugin.EventContext context, java.lang.String orgExpr, boolean orgIsExpression ) throws com.bea.wlpi.common.WorkflowException | Sets the event watch for this Start node. The template definition calls this method when the template definition is activated and saved. Plug-ins use this method to record an event watch. Using recorded event watches, the Event Processor can match an incoming event to this particular node and template definition. Plug-ins can use the default event watch registration, addressed message handling, and event matching facility by calling the com.bea.wlpi.server.plugin.EventContext.postStartWatch() method. Plug-ins must provide an event handler to perform run-time matching. Note: If a plug-in does not rely on the BPM JMS event listener, it is not required to provide an event handler. The method parameters are defined as follows: eventContext: com.bea.wlpi.server.plugin.EventContext object that specifies the Start node event context. The event context provides access to run-time event-related services, such as event watch registration. orgExpr:: java.lang.String object that specifies the expression used to generate the ID of the organization in which to instantiate the workflow. orgIsExpression:: Boolean value that indicates whether the specified organization is an expression (true) or not (false). For more information about defining an event handler to process plug-in events, see Processing Plug-In Events.

The following code listing is an excerpt from the plug-in sample that shows how to define the run-time component class for a Start node. This excerpt is taken from the StartNode.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-23 Defining the Run-Time Component Class for a Start Node

>     package com.bea.wlpi.tour.po.plugin;

>     import java.io.IOException;
>     import com.bea.wlpi.server.plugin.PluginStart2;
>     	.
>     	.
>     	.
>     public class StartNode extends StartObject implements PluginStart2 {

>         public StartNode() {
>         }
>     	.
>     	.
>     	.
>         public void setTrigger(EventContext context, String orgExpr,
>                                boolean orgIsExpr)
>                 throws WorkflowException {

>             System.out.println("SamplePlugin: StartNode - setTrigger called");
>             context.postStartWatch(SamplePluginConstants.CONTENTTYPE, eventDesc,
>                                    null, null);
>         }

>         public void fixup(ExpressionParser parser) {
>         }
>     }

Refer to the following related example listings:

- Implementing the PluginObject Interface for a Start Node shows how to read the plug-in data in XML format.

- Implementing the PluginData Interface for a Start Node shows how to read and save plug-in data in XML format. This example extends the StartObject class.

- Defining the PluginTriggerPanel Class for a Start Node shows how to display the plug-in GUI component in the design client.

- Using Plug-In Run-Time Contexts shows how to define the plug-in fields that can be referenced from an evaluator expression.

For more information about the plug-in sample, see BPM Plug-In Sample.

PluginTemplateNode Interface

The com.bea.wlpi.server.plugin.PluginTemplateNode interface provides methods for activating Done and Start nodes, and compiling their expressions.

The PluginTemplateNode interface is extended by the following interfaces:

- com.bea.wlpi.server.plugin.PluginDone

- com.bea.wlpi.server.plugin.PluginStart2

The following table describes the PluginTemplateNode interface methods that you must implement as part of the run-time component class when defining a Done or Start node.

Table 4-17 PluginTemplateNode Interface Methods

Method | Description
--- | ---
public void activate(com.bea.wlpi.server.common.ExecutionContext context) throws com.bea.wlpi.common.WorkflowException | Activates the node. The plug-in framework calls this method when the matching node is activated by an incoming transition from a predecessor node. The method parameter is defined as follows. execContext: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. For more information about the execution context, see Using Plug-In Run-Time Contexts.
public void fixup(com.bea.wlpi.evaluator.ExpressionParser parser) throws com.bea.wlpi.common.WorkflowException | Enables the plug-in node to compile the necessary expressions. The Plug-in Manager calls this method after parsing the template definition and storing it in memory, and prior to starting the workflow. The plug-in Start and Done nodes should perform all expensive initialization steps at this time. The method parameter is defined as follows. parser: com.bea.wlpi.evaluator.ExpressionParser object that specifies the expression parser.

For more information about the PluginTemplateNode interface, see the com.bea.wlpi.server.plugin.PluginTemplateNode Javadoc.

Using Plug-In Run-Time Contexts

To define the run-time execution information for the plug-in, you must implement a run-time interface for the plug-in component, as defined in Executing the Plug-In. At run time, the plug-in communicates with the process engine using a process called context passing: the Plug-in Manager obtains an instance of the plug-in component run-time interface and passes the context to it.

The following figure illustrates context passing.

Figure 4-10 Context Passing

Each context interface provides restricted access to the Plug-in Manager functionality, enabling the plug-in to execute and manage its own application logic, and introduce the plug-in instance data into the BPM run-time environment.

The following table describes the plug-in run-time context interfaces.

Table 4-18 Plug-In Run-Time Context Interfaces

The following context . . . | Provides . . .
--- | ---
com.bea.wlpi.server.plugin.ActionContext | Run-time context and services associated with an action.
com.bea.wlpi.evaluator.EvaluationContext | Run-time evaluation parameters for elements in an expression.
com.bea.wlpi.server.plugin.EventContext | Run-time context and services associated with an event.
com.bea.wlpi.server.common.ExecutionContext | Execution context of a running workflow instance.
com.bea.wlpi.common.plugin.PluginPanelContext | Client-side context for the BPM design client.

The following section describes the context interfaces in more detail.

Action Context

The com.bea.wlpi.server.plugin.ActionContextinterface provides the run-time context and services for plug-in actions. This context is passed via the com.bea.wlpi.server.plugin.PluginAction interface execute() method.

The following table describes the ActionContext interface methods that you can use to access information about the action context.

Table 4-19 ActionContext Interface Methods

Method | Description
--- | ---
public int executeSubActionList(int index, com.bea.wlpi.server.common.ExecutionContext context) throws com.bea.wlpi.common.WorkflowException | Executes each subaction on a list. The method parameters are defined as follows: index: Integer value that specifies the index of the subaction list to execute. This value equates to the index of the classNames array that corresponds to the com.bea.wlpi.common.plugin.ActionInfo object. execContext: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context that is passed by the caller. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. This method returns one of the following com.bea.wlpi.server.common.ExecutionContext integer values, indicating the return code, that specifies whether or not processing should continue: CONTINUE: Continue processing. STOP: Stop processing. In this case, the caller must return immediately and pass this return value. For more information about the execution context, see Execution Context.
public java.lang.String getActionId() throws com.bea.wlpi.common.WorkflowException | Gets the ID that uniquely defines this action. This ID is required to support asynchronously executed callbacks to plug-in actions. The ID must be passed to the com.bea.wlpi.server.worklist.Worklist interface response() method. This method returns a java.lang.String object that specifies the action ID.
public java.lang.String instantiateWorkflow(com.bea.wlpi.server.common.ExecutionContext context, java.lang.String orgID, java.lang.String templateID, com.bea.wlpi.common.VariableInfo[] initialValues, java.util.Map pluginData) throws com.bea.wlpi.common.WorkflowException public java.lang.String instantiateWorkflow(com.bea.wlpi.server.common.ExecutionContext context, java.lang.String orgID, java.lang.String templateID, com.bea.wlpi.common.VariableInfo[] initialValues, java.util.Map pluginData, boolean start) throws com.bea.wlpi.common.WorkflowException | Creates a new workflow instance. The method parameters are defined as follows: context: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context that is passed by the caller. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. For more information about the execution context, see Execution Context. orgID: java.lang.String object that specifies the ID of the organization in which the workflow should be instantiated. templateID: java.lang.String object that specifies the ID of the workflow template to instantiate. intialValues: Array of com.bea.wlpi.common.VariableInfo objects that specifies the ID of the workflow template to be instantiated. pluginData: java.util.Map object that specifies a map of all plug-in instance data, keyed on the plug-in name. start: Boolean flag that specifies whether to start the new workflow instance immediately (true) or leave it in a suspended state (false). This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser.
public java.lang.String startWorkflow(com.bea.wlpi.server.common.ExecutionContext context, java.lang.String istanceID, com.bea.wlpi.server.eventprocessor.EventData eventData) throws com.bea.wlpi.common.WorkflowException | Starts a previously instantiated workflow. The workflow must have been instantiated in the suspended state. The method parameters are defined as follows: context: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context that is passed by the caller. The execution context provides access to the run-time context, including the template ID, template definition ID, workflow instance ID, event data, and various services related to the workflow execution. For more information about the execution context, see Execution Context. instanceID: java.lang.String object that specifies the ID of the workflow instance to be started. eventData: com.bea.wlpi.server.eventprocessor.EventData object to present to the called start nodes. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser.

Evaluation Context

The com.bea.wlpi.evaluator.EvaluationContextinterface provides the run-time evaluation parameters for the elements in an expression. This context is passed via the evaluate() method to the com.bea.wlpi.server.plugin.PluginField interface and the com.bea.wlpi.server.plugin.PluginFunction interface.

The following table describes the EvaluationContext interface methods that you can use to access information about the evaluation context.

Table 4-20 EvaluationContext Interface Methods

Method | Description
--- | ---
public final int getCalendarType() | Gets the type of calendar to use when performing date arithmetic. This method returns an integer value that specifies one of the following calendar types, as defined by the com.bea.wlpi.evaluator.ExecutionContext interface: CALTYPE_ASSIGNEE (1): Task assignee calendar. CALTYPE_GREGORIAN (3): Gregorian calendar. CALTYPE_ORG (0): Instance organization calendar. CALTYPE_SPECIFIC (2): Specific calendar.
public final com.bea.wlpi.server.eventprocessor.EventData getEventData() | Gets the data for the current event. This method returns a com.bea.wlpi.server.eventprocessor.EventData object that specifies the current event data.
public final com.bea.wlpi.server.common.ExecutionContext getExecutionContext() | Gets the execution context within which to evaluate the expression. This method returns an com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context. For more information about the execution context, see Execution Context.
public final java.lang.String getTaskID() | Gets the user ID of the current task, if any. This method returns a java.lang.String object that specifies the task ID.
public final java.lang.String getUserID() | Gets the user ID that made the current top-level API call. This method returns a java.lang.String object that specifies the user ID.

Event Context

The com.bea.wlpi.server.plugin.EventContextinterface provides the run-time context and services to plug-in events. This context is passed via the following methods:

- activate() and trigger() methods to the com.bea.wlpi.server.plugin.PluginEvent interface

- settrigger() method to the com.bea.wlpi.server.plugin.PluginStart2 interface

The following table describes the EventContext interface methods that you can use to access information about the event context.

Table 4-21 Event Context Interface Methods

Method | Description
--- | ---
public void activateEvent(com.bea.wlpi.server.common.ExecutionContext context, java.lang.String contentType, java.lang.String eventDescriptor, java.lang.String keyValue, java.lang.String condition) throws com.bea.wlpi.common.WorkflowException | Performs default event activation. Checks whether the Event Processor has received and persisted a message addressed to this workflow instance or template. If no message exists, an event watch record is posted. If a message exists, the matching event is consumed and the event node is triggered if the following criteria are met: Message contains the required content type and event descriptor. Key value matches the key value specified by the caller (if specified). Conditional expression evaluates to true (if specified). If passing a content type other than text/xml, it is the plug-in's responsibility to ensure that a matching event key expression is registered in the event key table. This can be accomplished using the addEventKey() method to the com.bea.wlpi.server.admin.Admin interface. The plug-in should also provide a plug-in field to evaluate a key value from incoming data of this content type and format. For more information about defining a plug-in field, see Defining the Run-Time Component Class for a Message Type. The method parameters are defined as follows: context: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context that is passed by the caller. For more information about the execution context, see Execution Context. contentType: java.lang.String object that specifies the MIME content type that describes the basic data type of the message. eventDescriptor: java.lang.String object that specifies the event descriptor in a format that is compatible with the contentType value, or null. keyValue: java.lang.String object that specifies the key value required to trigger this call, or null. condition: java.lang.String object that specifies the conditional expression to evaluate against the event, or null. This condition must evaluate to true before the event can be triggered.
public void checkEventKey(java.lang.String contentType, java.lang.String eventDescriptor, java.lang.String keyExpr) throws com.bea.wlpi.common.WorkflowException | Ensure that a suitable event key exists. The method calls getFieldInfo() method to the parent com.bea.wlpi.common.plugin.StartInfo or com.bea.wlpi.common.plugin.EventInfo object. It uses the FieldInfo object to check for the existence of a suitable event key, and to create or update one if necessary. The method parameters are defined as follows: contentType: java.lang.String object that specifies the MIME content type that describes the basic data type of the message. eventDescriptor: java.lang.String object that specifies the event descriptor in a format that is compatible with the contentType value, or null. keyExpr: java.lang.String object that specifies the expression to be used to extract the key value from an incoming message of the specified content type and event descriptor. This value can be set to null. If keyExpr is non-null, the method creates a new event key if it does not already exist, or updates an existing event key if its keyExpr does not match that supplied by the plug-in. If keyExpr is null and no matching event key exists, the method throws a WorkflowException with the code Messages#EVENT_KEY_MISSING. This method can only be called by a com.bea.wlpi.server.plugin.PluginStart2 or com.bea.wlpi.server.plugin.PluginEvent node. Note: This is an expensive call and plug-ins should take steps to minimize its use, typically by keeping a static flag to ensure that it is only called once per event key.
public java.lang.String getNodeId() | Gets the ID of the Event or Start node. This ID is required to support asynchronously executed callbacks to plug-in actions. The ID must be passed to the response() method to the com.bea.wlpi.server.worklist.Worklist interface. This method returns a java.lang.String object that specifies the action ID.
public java.lang.String getTemplateDefinitionID() | Gets the ID of the workflow template definition. This method returns a java.lang.String object that specifies the template definition ID.
public java.lang.String getTemplateID() | Gets the ID of the workflow template. This method returns a java.lang.String object that specifies the template ID.
public void postStartWatch(java.lang.String contentType, java.lang.String eventDescriptor, java.lang.String keyValue, java.lang.String condition) | Registers an Event Processor watch record for the specified message. Note: This method can only be called by a Start node. If passing a content type other than text/xml, it is the plug-in's responsibility to ensure that a matching event key expression is registered in the event key table. This can be accomplished using the addEventKey() method to the com.bea.wlpi.server.admin.Admin interface. The plug-in should also provide a plug-in field to evaluate a key value from incoming data of this content type and format. For more information about defining a plug-in field, see Defining the Run-Time Component Class for a Message Type. The method parameters are defined as follows: contentType: java.lang.String object that specifies the MIME content type that describes the basic data type of the message. eventDescriptor: java.lang.String object that specifies the event descriptor in a format that is compatible with the contentType value, or null. keyValue: java.lang.String object that specifies the key value required to trigger this call, or null. condition: java.lang.String object that specifies the conditional expression to evaluate against the event, or null. This condition must evaluate to true before the event can be triggered.
public void removeEventWatch(com.bea.wlpi.server.common.ExecutionContext context) | Unregisters the Event Processor watch record for the specified message. Note: This message should be called only by an Event node. The method parameter is defined as follows. context: com.bea.wlpi.server.common.ExecutionContext object that specifies the execution context that is passed to the caller. For more information about the execution context, see Execution Context.
public void removeStartWatch() | Unregisters the Event Processor watch record for the specified message. Note: This message should be called only by a Start node.

Execution Context

The com.bea.wlpi.server.common.ExecutionContextinterface provides the run-time context and services for a running workflow instance. This context is passed via the following methods:

- com.bea.wlpi.server.plugin.PluginAction interface execute(), response(), and startedWorkflowDone() methods

- com.bea.wlpi.server.plugin.PluginEvent interface activate() and trigger() methods

- com.bea.wlpi.server.plugin.PluginTemplateNode interface activate() method (used by the Start and Done nodes)

The following table describes the ExecutionContext interface methods that you can use to access information about the action context.

Table 4-22 ExecutionContext Interface Methods

Method | Description
--- | ---
public void addClientResponse(java.lang.String xml) | Appends an XML document to the API method return value. The method parameter is defined as follows. xml: java.lang.String object that specifies the XML document to be appended.
public java.lang.String getErrorHandler() throws com.bea.wlpi.common.WorkflowException | Gets the name of the current error handler. This method returns a java.lang.String object that specifies the current error handler.
public com.bea.wlpi.server.eventprocessor.EventData getEventData() | Gets the data associated with the current event, if any. This method returns a com.bea.wlpi.server.eventprocessor.EventData object that specifies the event data, or an empty string that specifies the system eventhandler.
public int getExceptionNumber() | Gets the message number of the error being handled by the eventhandler. This method returns an integer value that specifies the message number.
public java.lang.Exception getExceptionObject() | Gets the exception object being handled by the event handler. This method returns a java.lang.Exception object that specifies the exception object.
public int getExceptionSeverity() | Gets the exception severity code of the error being handled by the event handler. This method returns an integer value that specifies one of the following com.bea.wlpi.common.WorkflowException severity codes: ERROR_CUSTOM: Custom error raised either by an application or by a workflow executing the Invoke Error handler action. ERROR_SYSTEM: Fatal exception occurred while a user request was being processed. ERROR_UNKNOWN: Unknown error type (internal use only). ERROR_WORKFLOW: Fatal, illegal condition, such as inconsistent workflow state. WARNING_WORKFLOW: Nonfatal workflow condition that the user can rectify manually.
public java.lang.String getExceptionText() | Gets the message text of the exception being handled by the event handler. This method returns a java.lang.String object that specifies the message text.
public java.lang.String getExceptionType() | Gets the message type of the exception being handled by the event handler. This method returns a java.lang.String object that specifies the message text.
public java.lang.String getInstanceID() | Gets the ID of the current workflow instance. This method returns a java.lang.String object that specifies the ID.
public java.lang.String getOrg() throws com.bea.wlpi.common.WorkflowException | Gets the ID of the organization in which the current instance is running. This method returns a java.lang.String object that specifies the message text.
public java.lang.Object getPluginInstanceData(java.lang.String pluginName) throws com.bea.wlpi.common.WorkflowException | Gets the workflow instance data provided by the named plug-in. The method parameter is defined as follows. pluginName: java.lang.String object that specifies the plug-in name. This method returns a java.lang.Object object that specifies the plug-in instance data.
public java.lang.String getRequestor() | Gets the ID of the user that made the current API request. This method returns a java.lang.String object that specifies the requestor ID.
public boolean getRollbackOnly() | Determines whether the current user transaction has been marked for rollback only. This method returns true if the transaction is set for rollback only, and false otherwise.
public java.lang.String getTemplateDefinitionID() | Gets the ID of the current template definition. This method returns a java.lang.String object that specifies the template definition ID.
public com.bea.wlpi.common.plugin.PluginObject getTemplateDefintionPluginData(java.lang.String pluginName) | Gets the template definition data for the specified plug-in. The method parameter is defined as follows. pluginName: java.lang.String object that specifies the plug-in name. This method returns a com.bea.wlpi.common.plugin.PluginObject object that specifies the template definition data.
public java.lang.String getTemplateID() | Gets the ID of the current template. This method returns a java.lang.String object that specifies the template ID.
public com.bea.wlpi.common.plugin.PluginObject getTemplatePluginData(java.lang.String pluginName) | Gets the template data for the specified plug-in. The method parameter is defined as follows. pluginName: java.lang.String object that specifies the plug-in name. This method returns a com.bea.wlpi.common.plugin.PluginObject object that specifies the template data.
public com.bea.wlpi.common.VariableInfo getVariableInfo(java.lang.String name) | Gets information about the specified plug-in variable. The method parameter is defined as follows. name: java.lang.String object that specifies the variable name. This method returns a com.bea.wlpi.common.VariableInfo object that specifies the variable information.
public java.lang.Object getVariableValue(java.lang.String name) throws com.bea.wlpi.common.WorkflowException | Gets the variable value for the specified plug-in variable. The method parameter is defined as follows. name: java.lang.String object that specifies the variable name. This method returns a java.lang.Object object that specifies the variable information. Also refer to the getInstanceVariable() method to the com.bea.wlpi.server.admin.Admin interface, as described in Monitoring Run-Time Variables in Programming BPM Client Applications.
public java.lang.String instantiate(java.lang.String orgID, java.lang.String initialNode, java.lang.String parentTemplateDefinitionID, java.lang.String parentID, java.lang.String parentNodeID, com.bea.wlpi.server.eventprocessor.EventData eventData, java.util.List lVariableValues, java.util.Map pluginData) throws com.bea.wlpi.common.WorkflowException | Creates a new workflow instance The method parameters are defined as follows: orgID: java.lang.String object that specifies the organization ID that will be associated with the new instance. initialNode: java.lang.String object that specifies the ID of the Start node to be activated. parentTemplateDefinitionID: java.lang.String object that specifies the ID of the parent template definition (if a subworkflow is being instantiated). parentID: java.lang.String object that specifies the ID of the parent workflow instance (if a subworkflow is being instantiated). parentNodeID: java.lang.String object that specifies the ID of the node in the parent workflow to be notified of events in the lifecycle of the workflow (if a subworkflow is being instantiated). eventData: com.bea.wlpi.server.eventprocessor.EventData object that specifies the event data to pass to the called Start nodes in the workflow. (This parameter provides an alternative to using the lVariableValues value to set variable values explicitly.) lVariableValues: java.util.List object that specifies a list of com.bea.wlpi.common.VariableInfo objects that initialize the workflow instance variables. Note that non-null initial values for all mandatory input variables must be passed through this parameter. pluginData: java.util.Map object that specifies a map of all plug-in instance data, keyed on the plug-in name. This method returns a java.lang.String object that specifies the ID of the new workflow instance. Also refer to the instantiateWorkflow() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in Manually Starting Workflows in Programming BPM Client Applications.
public int invokeErrorHandler(java.lang.String handlerName, java.lang.Exception e) | Invokes the specified event handler. The method parametes are defined as follows: handlerName: java.lang.String object that specifies the name of the event handler to be invoked. e: java.lang.Exception object that specifies the event value to be thrown. This method returns an integer value that specifies the status of the call.
public boolean isAuditEnabled() | Determines whether or not auditing is enabled for the current workflow. This method returns true if auditing is enabled, and false otherwise.
public void setErrorHandler(java.lang.String handlerName) throws com.bea.wlpi.common.WorkflowException | Sets the current event handler. The method parameter is defined as follows. handlerName: java.lang.String object that specifies the one of the following: name of the event handler to set; null, to restore the previous event handler; or an empty string, to set the system event handler.
public void setPluginInstanceData(java.lang.String pluginName, java.lang.Object data) throws com.bea.wlpi.common.WorkflowException | Sets the workflow instance data for the specified plug-in. The method parameters are defined as follows: pluginName: java.lang.String object that specifies the plug-in name. data: java.lang.Object object that specifies the plug-in data. Also refer to the setInstanceVariable() method to the com.bea.wlpi.server.admin.Admin interface, as described in Monitoring Run-Time Variables in Programming BPM Client Applications.
public void setRollbackOnly() | Sets the user transaction for rollback only.
public void setVariableValue(java.lang.String name, java.lang.Object value) throws com.bea.wlpi.common.WorkflowException | Sets the value of a variable. The method parameters are defined as follows: orgID: java.lang.String object that specifies the organization ID that will be associated with the new instance. initialNode: java.lang.String object that specifies the ID of the Start node to be activated. Also refer to the setInstanceVariable() method to the com.bea.wlpi.server.admin.Admin interface, as described in Monitoring Run-Time Variables in Programming BPM Client Applications.
public java.lang.String taskAssign(java.lang.String instanceID, java.lang.String taskID, java.lang.String assigneeID, boolean bRole, boolean bLoadBalance) throws com.bea.wlpi.common.WorkflowException | Assigns a workflow task to a participant. The method parameters are defined as follows: instanceID: java.lang.String object that specifies the workflow instance ID. taskID: java.lang.String object that specifies the task ID. assigneeID: java.lang.String object that specifies the ID of the assignee (user or role). bRole: Boolean value that indicates whether the specified assignee is a role (true) or user (false). bLoadBalance: Boolean value that specifies whether or not load balancing should be applied across the members of a role. This parameter is ignored if bRole is set to false. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser. Also refer to the taskAssign() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in Managing Run-Time Tasks in Programming BPM Client Applications.
public java.lang.String taskDoIt(java.lang.String instanceID, java.lang.String taskID) throws com.bea.wlpi.common.WorkflowException | Executes a workflow task. The method parameters are defined as follows: instanceID: java.lang.String object that specifies the workflow instance ID. taskID: java.lang.String object that specifies the task ID. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser. Also refer to the taskExecute() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in Managing Run-Time Tasks in Programming BPM Client Applications.
public java.lang.String taskMarkDone(java.lang.String instanceID, java.lang.String taskID) throws com.bea.wlpi.common.WorkflowException | Marks a workflow task complete. The method parameters are defined as follows: instanceID: java.lang.String object that specifies the workflow instance ID. taskID: java.lang.String object that specifies the task ID. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications.The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser. Also refer to the taskMarkDone() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in Managing Run-Time Tasks in Programming BPM Client Applications.
public java.lang.String taskSetProperties(java.lang.String instanceID, java.lang.String taskID, int priority, boolean doneWithoutExecute, boolean executeIfDone, boolean unmarkDone, boolean modifiable, boolean reassignment) throws com.bea.wlpi.common.WorkflowException | Sets the properties for a workflow task. The method parameters are defined as follows: instanceID: java.lang.String object that specifies the workflow instance ID. taskID: java.lang.String object that specifies the task ID. priority: Integer value that specifies the task priority: 0 (low), 1 (medium), or 2 (high). doneWithoutExecute: Boolean value that specifies whether or not a user has permission to mark a task as complete using the taskMarkDone() method, described previously in this table. executeIfDone: Boolean value that specifies whether or not a user has permission to execute a task using the taskDoIt() method, described previously in this table. unmarkDone: Boolean value that specifies whether or not a user has permission to mark a task as incomplete using the taskUnmarkDone() method, described later in this table. modifiable: Boolean value that specifies whether or not a user has permission to set properties using this method. reassignable: Boolean value that specifies whether or not a user has permission to assign a task using the taskAssign() method, described previously in this table. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser. Also refer to the taskSetProperties() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in described in Managing Run-Time Tasks in Programming BPM Client Applications.
public java.lang.String taskUnassign(java.lang.String instanceID, java.lang.String taskID) throws com.bea.wlpi.common.WorkflowException | Unassigns a workflow task. The method parameters are defined as follows: instanceID: java.lang.String object that specifies the workflow instance ID. taskID: java.lang.String object that specifies the task ID. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser. Also refer to the taskUnassign() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in Managing Run-Time Tasks in Programming BPM Client Applications.
public java.lang.String taskUnmarkDone(java.lang.String instanceID, java.lang.String taskID) throws com.bea.wlpi.common.WorkflowException | Marks a workflow task as incomplete. The method parameters are defined as follows: instanceID: java.lang.String object that specifies the workflow instance ID. taskID: java.lang.String object that specifies the task ID. This method returns an XML document that is compliant with the Client Request DTD, ClientReq.dtd, as described in DTD Formats in Programming BPM Client Applications. The XML document contains information about the running instance, including the instance ID and template definition ID. It can be accessed by parsing the document using an XML parser, such as a SAX (Simple API for XML) parser. Also refer to the taskUnmarkdone() method to the com.bea.wlpi.server.worklist.Worklist interface, as described in Managing Run-Time Tasks in Programming BPM Client Applications.

For more information, see the com.bea.wlpi.server.common.ExecutionContextJavadoc.

PluginPanelContext

The com.bea.wlpi.common.plugin.PluginPanelContextinterface provides the run-time context and services for the design client (for example, the Studio), including:

- Access to plug-in template and template definition data

- Services to launch the Expression Builder, validate and manipulate expressions, and invoke the Add Variable dialog box.

Note: Not all methods are applicable in all dialog box contexts. If the plug-in invokes a method in an invalid context, a java.lang.UnsupportedOperationException exception is thrown.

You can access the plug-in panel context using the com.bea.wlpi.common.plugin.PluginPanel get and set methods defined in the table PluginPanel Class Methods.

The following table describes the PluginPanelContext interface methods that you can use to access information about the action context.

Table 4-23 PluginPanelContext Interface Methods

Method | Description
--- | ---
public int checkEventKey(java.lang.String contentType, java.lang.String keyExpr, boolean update) throws com.bea.wlpi.common.WorkflowException | Ensure that a suitable event key exists. The method calls the eventDescriptor method to the parent com.bea.wlpi.common.plugin.PluginTriggerPanel object, or the getFieldInfo() method to the parent com.bea.wlpi.common.plugin.StartInfo or com.bea.wlpi.common.plugin.EventInfo object. It uses the returned value to check for the existence of a suitable event key, and to create one if necessary. The method parameters are defined as follows: contentType: java.lang.String object that specifies the MIME content type that describes the basic data type of the message. keyExpr: java.lang.String object that specifies the expression to be used to extract the key value from an incoming message of the specified content type and event descriptor. This value can be set to null. update: Boolean value that specifies whether or not to create an event key if one does not exist or update an existing event key if keyExpr is non-null. If update is true, and keyExpr is null, the user is prompted to supply a value. Otherwise, the method creates a new event key, then displays a notification to that effect. If the event key already exists but keyExpr does not match the non-null keyExpr supplied by the plug-in, the method updates the event key and notifies the user. Note: It is only legal to call this method while a PluginTriggerPanel is displayed. This method returns one of the following values: EVENT_KEY_CREATED: event key did not exist and was created. EVENT_KEY_EXISTS: event key already existed. EVENT_KEY_NOT_EXISTS: event key does not exist. EVENT_KEY_UPDATED: event key did exist but was updated.
public com.bea.wlpi.common.VariableInfo checkVariable(java.lang.String name, java.lang.String[] validTypes) throws com.bea.wlpi.common.WorkflowException | Determines whether a variable exists. If not variable exists, this method invokes the Add Variable dialog box to enable a user to define a new workflow variable of a valid type specified by the caller. The method parameters are defined as follows: name: java.lang.String object that specifies the variable name. validTypes: Array of java.lang.String object that specifies either valid types for the specified variable, or null. For a list of valid types, see the com.bea.wlpi.common.VariableInfo Javadoc. This method returns a com.bea.wlpi.common.VariableInfo object that specifies the existing or new variable information, or null.
public java.util.Set getEventDescriptors() | Gets the set of event descriptors referenced by existing event keys. This method returns a java.util.Set object consisting of a set of event descriptor strings that are currently defined for the specified content type. This method is intended for populating lists and boxes.
public javax.naming.Context getInitialContext() | Gets the design client JNDI context. This method returns a javax.naming.Context object that specifies the JNDI context. This context contains the same security context used by the design client. Note: The caller must not close this context.
public com.bea.wlpi.common.PluginData getPluginTemplateData(java.lang.String pluginName) | Gets the plug-in data for the template associated with the specified template. The method parameter is defined as follows. pluginName: java.lang.String object that specifies the plug-in name. This method returns a com.bea.wlpi.common.plugin.PluginData object that specifies the plug-in template.
public com.bea.wlpi.common.PluginData getPluginTemplateDefinitionData(java.lang.String pluginName) | Gets the plug-in data for the template definition associated with the specified template. The method parameter is defined as follows. pluginName: java.lang.String object that specifies the plug-in name. This method returns a com.bea.wlpi.common.plugin.PluginData object that specifies the plug-in template definition.
public int getTemplateDefinitionID() | Gets the ID of the owner of the template definition. This method returns a java.lang.String object that specifies the template definition ID.
public int getTemplateID() | Gets the ID of the owner of the template. This method returns a java.lang.String object that specifies the template ID.
public java.util.List getVariableList() | Gets a list of variables and their types. This method returns a java.util.List object containing a list of com.bea.wlpi.common.VariableInfo objects that describe the variables.
public java.util.List getVariableList(java.lang.String type) | Gets a list of variables of the specified type. This method returns a java.util.List object containing a list of com.bea.wlpi.common.VariableInfo objects that describe the variables of the specified type.
public com.bea.wlpi.common.VariableInfo invokeAddVariableDialog() throws com.bea.wlpi.common.WorkflowException | Invokes the Add Variable dialog box to enable a user to define a new workflow variable. This method returns a com.bea.wlpi.common.VariableInfo object that specifies the new variable information, or null if the OK button was not selected to create the variable.
public com.bea.wlpi.common.VariableInfo invokeAddVariableDialog(java.lang.String name, java.lang.String[] validTypes) throws com.bea.wlpi.common.WorkflowException | Invokes the Add Variable dialog box to enable a user to define a new workflow variable of a valid type specified by the caller. The method parameters are defined as follows: name: java.lang.String object that specifies the variable name. validTypes: Array of java.lang.String object that specifies valid types for the specified variable, or null. For a list of valid types, see the com.bea.wlpi.common.VariableInfo Javadoc. This method returns a com.bea.wlpi.common.VariableInfo object that specifies the new variable information, or null if the OK button was not selected to create the variable.
public void invokeExpressionBuilder(javax.swing.text.JTextComponent txtInput, boolean condition, com.bea.wlpi.common.plugin.FieldInfo fieldInfo, java.lang.String[] fields, java.lang.String eventDescriptor) | Invokes the Expression Builder dialog box. The current expression must be displayed in a javax.swing.text.JTextComponent object, or an associated subclass, and the client initializes the Expression Builder from this text component. When the user selects OK in the Expression Builder dialog box, the client validates the expression, closes the dialog box, and updates the text component with the modified expression. The method parameters are defined as follows: txtInput: javax.swing.text.JTextComponent object that specifies the text input component containing the expression. condition: Boolean value that specifies whether or not to build a conditional expression. fieldInfo: com.bea.wlpi.common.plugin.FieldInfo object that specifies any plug-in field information. This parameter is required if the expression is permitted to reference fields. fields: Array of java.lang.String objects that represent valid plug-in field names that match those available to the component specified by the event descriptor. Field types that require qualifiers are not well suited to being specified with this parameter. eventDescriptor: java.lang.String object that specifies the event descriptor.
public boolean isVariableInExpression(java.lang.String expr, java.lang.String var) throws com.bea.wlpi.evaluator.EvaluatorExpression | Determines whether or not an expression references the specified variable. The method parameters are defined as follows: expr: java.lang.String object that specifies the expression. var: java.lang.String object that specifies the variable name. This method returns true if the variable is referenced and false otherwise.
public java.lang.String renameVariableInExpression(java.lang.String expr, java.lang.String oldName, java.lang.String newName) throws com.bea.wlpi.evaluator.EvaluatorExpression | Updates the expression references to a renamed variable. The method parameters are defined as follows: expr: java.lang.String object that specifies the expression. oldName: java.lang.String object that specifies the old variable name. newName: java.lang.String object that specifies the new variable name. This method returns a java.lang.String object that specifies the updated expression text.
public java.lang.String validateExpression(java.lang.String expression, boolean allowVariables, com.bea.wlpi.common.plugin.FieldInfo fieldInfo, java.lang.String eventDescriptor) throws com.bea.wlpi.evaluator.EvaluatorExpression | Updates the expression references to a renamed variable. The method parameters are defined as follows: expression: java.lang.String object that specifies the text of the expression to be validated. allowVariables: Boolean value that specifies whether or not the expression allows variables. fieldInfo: com.bea.wlpi.common.plugin.FieldInfo object that specifies the plug-in field type. eventDescriptor: java.lang.String object that specifies the event descriptor. This method returns a java.lang.String object that specifies the updated expression text.

For more information, see the com.bea.wlpi.server.plugin.PluginPanelContextJavadoc.

Defining the Plug-In Component Value Objects

The final step consists of defining the value object for the plug-in component to further define the component data. To define the plug-in component value object, use the associated constructor. Each of the plug-in value objects described in the table Plug-In Value Objects, provides one or more constructors for creating object data. The constructors for creating value objects are described in Plug-In Value Object Summary.

You must pass the plug-in value objects for each of the plug-in components when defining the com.bea.wlpi.common.plugin.PluginCapabilitiesInfo object, as described in the getPluginCapabilities() method description, in the table Remote Interface Plug-In Information Methods.

The following code listing is an excerpt from the plug-in sample that shows how to implement the getPluginCapabilitiesInfo() method. This excerpt is taken from the SamplePluginBean.java file in the SAMPLES_HOME/integration/samples/bpm_api/plugin/src/com/bea/wlpi/tour/po/plugin directory. Notable lines of code are shown in bold.

Listing 4-24 Implementing the getPluginCapabilitiesInfo() Method

>         public PluginCapabilitiesInfo getPluginCapabilitiesInfo(Locale lc,
>                 CategoryInfo[] info) {

>             PluginInfo pi;
>             FieldInfo orderFieldInfo;
>             FieldInfo confirmFieldInfo;
>             FieldInfo[] fieldInfo;
>             FunctionInfo fi;
>             FunctionInfo[] functionInfo;
>             StartInfo si;
>             StartInfo[] startInfo;
>             EventInfo ei;
>             EventInfo[] eventInfo;
>             SampleBundle bundle = new SampleBundle(lc);

>             log("getPluginCapabilities called");

>             pi = createPluginInfo(lc);
>             orderFieldInfo =
>                 new FieldInfo(SamplePluginConstants.PLUGIN_NAME, 3,
>                               bundle.getString("orderFieldName"),
>                               bundle.getString("orderFieldDesc"),
>                               SamplePluginConstants.ORDER_FIELD_CLASSES, false);
>             confirmFieldInfo =
>                 new FieldInfo(SamplePluginConstants.PLUGIN_NAME, 4,
>                               bundle.getString("confirmFieldName"),
>                               bundle.getString("confirmFieldDesc"),
>                               SamplePluginConstants.CONFIRM_FIELD_CLASSES, false);
>             fieldInfo = new FieldInfo[]{ orderFieldInfo, confirmFieldInfo };
>             ei = new EventInfo(SamplePluginConstants.PLUGIN_NAME, 6,
>                                bundle.getString("confirmOrderName"),
>                                bundle.getString("confirmOrderDesc"), ICON_BYTE_ARRAY,
>                                SamplePluginConstants.EVENT_CLASSES,
>                                confirmFieldInfo);
>             eventInfo = new EventInfo[]{ ei };
>             fi = new FunctionInfo(SamplePluginConstants.PLUGIN_NAME, 7,
>                                   bundle.getString("calcTotalName"),
>                                   bundle.getString("calcTotalDesc"),
>                                   bundle.getString("calcTotalHint"),
>                                   SamplePluginConstants.FUNCTION_CLASSES, 3, 3);
>             functionInfo = new FunctionInfo[]{ fi };
>             si = new StartInfo(SamplePluginConstants.PLUGIN_NAME, 5,
>                                bundle.getString("startOrderName"),
>                                bundle.getString("startOrderDesc"), ICICON_BYTE_ARRAYON,
>                                SamplePluginConstants.START_CLASSES, orderFieldInfo);
>             startInfo = new StartInfo[]{ si };

>             PluginCapabilitiesInfo pci = new PluginCapabilitiesInfo(pi,
>                                              getCategoryInfo(bundle), eventInfo,
>                                              fieldInfo, functionInfo, startInfo,
>                                              null, null, null, null, null);

>             return pci;
>         }