|
|
|
|
|
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 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
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
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
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
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
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.windThe 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 WLI_HOME/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
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:
- 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 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:
- EventObject.java in the WLI_HOME/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
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.
Table 4-10 Plug-In Run-Time Component Interfaces
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-11 PluginAction Interface Methods