BEA Logo BEA WLI Release 2.1

  BEA Home  |  Events  |  Solutions  |  Partners  |  Products  |  Services  |  Download  |  Developer Center  |  WebSUPPORT

 

   WLI Doc Home   |   BPM Topics   |   Programming BPM Plug-Ins   |   Previous Topic   |   Next Topic   |   Contents   |   Index   |   View as PDF

Defining Plug-In Components

 

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

 


Overview

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

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 WLI_HOME/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 WLI_HOME/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 WLI_HOME/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:

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 WLI_HOME/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:

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 WLI_HOME/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:

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.

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:


 

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:

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 WLI_HOME/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:

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 WLI_HOME/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:

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:

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 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 WLI_HOME/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 WLI_HOME/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:

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 obtains an instance of the plug-in panel class, StartNodePanel, from the plug-in using object manufacturing, and returns the data to the Studio client. The Studio client subsequently displays the plug-in GUI component in the Start Properties dialog box. (For more information about object manufacturing, see Accessing the Plug-In Implementation (Object Manufacturing).)

The following table describes the plug-in panel class 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.


 

Note: All plug-in panel classes must provide a public constructor that requires no arguments, and that functions properly when invoked on the client side, picking up the locale by calling the getDefault() method to the java.util.Locale interface.

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:

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:

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:

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:


 

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:

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:

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:

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 WLI_HOME/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 WLI_HOME/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.wind

The following figure illustrates the resulting PluginActionPanel GUI component.

Figure 4-4 PluginActionPanel GUI Component


 

Refer to the following related example listings:

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.


 

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 WLI_HOME/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:

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 WLI_HOME/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:

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.


 

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 Run-Time Component Class for a Variable Type, which shows how to define the execution information for the plug-in.

 


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: workflow template properties, or workflow template definition properties.


 

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:

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.