The Web Application Toolkit includes resources to build workflow functionality into your Web applications, or to extend the existing workflow functionality in the FileNet P8 Workplace application. You can leverage the Toolkit framework and APIs to execute and manage workflows in the Process Engine, to store and manage versions of workflow definitions in the Content Engine, and to render UI, handle events, and manage state information in the Web application.
In a Web application, workflow-related operations are performed by what's generically referred to as a "Step Processor", a set of components that provide and process the information and resources that participants need to complete steps in a workflow. Technically, however, a Step Processor is one of two categories of processors that are used in sequence. First, a Launch Step Processor is used to begin a workflow: it contains the information necessary to initialize the workflow. Second, a Step Processor is used for each step in the workflow: it displays the instructions, the attachments retrieved from an object or file store, current field values, response options, or other resources to the workflow participant.
There are two type of processors you can develop for a Toolkit-build Web application: a zero-download HTML processor, and a downloadable Java™ processor (application or applet). (The FileNet P8 Workplace application includes out-of-the-box HTML and Java processors.) This topic shows you how to add custom HTML processors to the FileNet P8 Workplace application. Note that this information also applies to creating HTML processors for any Toolkit-based Web application.
See Also
System
Overview
Developing
HTML and Java Step Processors
Developing
Custom Java Processors - Applications vs. Applets
All processors, whether HTML or Java, must at a minimum perform the following basic operations. For general information on a particular operation, click the applicable link. For details on coding these operations in an HTML processor, see HTML Processors Development Procedure.
NOTE This operation is not covered in the HTML Processors Development Procedure because the procedure describes development of a custom HTML Step Processor for the FileNet P8 Workplace application, which establishes a Process session for you. However, Web Application Toolkit provides a default sign-in policy implementation that persists credentials required for Content Engine and Process Engine access.
This procedure explains how to develop a custom HTML Launch Processor and Step Processor for the FileNet P8 Workplace application. The procedure presents this information by describing the processor components in the FileNet P8 Web Application Toolkit Basic Step Processor Sample Code, v 4.0. This is a fully-functional processor sample that you can modify or run as-is and includes a workflow definition. You can download this sample from the IBM support site. For download instructions, see Accessing IBM FileNet documentation.
NOTE For the remainder of this topic, the FileNet P8 Web Application Toolkit Basic Step Processor Sample Code will be referred to as the "Basic Step Processor Sample".
After you have downloaded the Basic Step Processor Sample, you may develop HTML Processors as follows:
To develop, deploy, and test processor components:
javax.servlet.http
package. The JAR names vary between application servers, for example,
weblogic.jar in WebLogic, j2ee.jar in WebSphere, and javax.servlet.jar in JBoss.The components listed in the following table comprise a Launch Processor and Step Processor for a Toolkit-build Web application. As you can see, each processor consists of a framework page (event Java™Server Pages (JSP) and a UI JSP), a UI module, and a UI module JSP for rendering, although you could use XSL- or Java-based rendering instead. The CSS stylesheet defines the styles specified in the UI module JSP. Also listed are the FileNet P8 Workplace directories where you must deploy the components. Create new directories if they don't currently exist.
Note that these components are used in the Basic Step Processor Sample. For a description of a component, click on the applicable link. To view the entire source of the component, open the source file included with the sample.
Component | Deployment Directory | Name in Sample |
---|---|---|
Launch Processor: Event JSP | Workplace/eprocess/launchers/html/custom | CustomLaunch.jsp |
Launch Processor: UI JSP | Workplace/UI-INF/jsp/ui/eprocess/ launchers/html/custom |
CustomLaunch.jsp |
Launch Processor: UI Module | Workplace/WEB-INF/classes/com/filenet/ samples/processors/basic/apps/server/ui |
CustomLaunchModule.class |
Launch Processor: UI Module JSP
(for rendering) |
Workplace/UI-INF/jsp/modules/apps | CustomLaunchModuleJSP.jsp |
Step Processor: Event JSP | Workplace/eprocess/stepprocs/html/custom | CustomStep.jsp |
Step Processor: UI JSP | Workplace/UI-INF/jsp/ui/eprocess/ stepprocs/html/custom |
CustomStep.jsp |
Step Processor: UI Module | Workplace/WEB-INF/classes/com/filenet/ samples/processors/basic/apps/server/ui |
CustomStepModule.class |
Step Processor: UI Module JSP
(for rendering) |
Workplace/UI-INF/jsp/modules/apps | CustomStepModuleJSP.jsp |
CSS Stylesheet | Workplace/css | Processors.css |
As in all event JSP pages, the event
JSP page for a launch processor must declare the controller and modules,
and register the modules with the controller. As shown in the following
code fragment, a UI module and data provider module are declared. The UI
module (CustomLaunchModule) provides event handling and presentation, and
WcmEProcessDataProvider
provides application-level access to the Process Java API. Note that
WcmEProcessDataProvider is bound to CustomLaunchModule with the
addDataProvider(...)
call.
<%@ page errorPage="/WcmError.jsp" autoFlush="false" %>
<%-- UI Beans --%> <jsp:useBean id="customLaunchModule" class="com.filenet.samples.processors.basic.apps.server.ui.CustomLaunchModule" scope="request"> <jsp:setProperty name="customLaunchModule" property="name" value="customLaunchModule" /> </jsp:useBean> <%-- Data Provider Bean --%> <jsp:useBean id="eProcessDataProvider" class="com.filenet.wcm.toolkit.server.dp.WcmEProcessDataProvider" scope="request"> <jsp:setProperty name="eProcessDataProvider" property="name" value="eProcessDataProvider" /> </jsp:useBean> <%-- WcmController CONTROLLER --%> <jsp:useBean id="controller" class="com.filenet.wcm.apps.server.controller.WcmWorkplaceController" scope="request"> </jsp:useBean> <% customLaunchModule.addDataProvider(eProcessDataProvider); ... |
This is a typical UI JSP page in that
it contains HTML tags and invokes rendering of the HTML header tags and
body text. As shown in the following code fragment, the
WcmString is used to retrieve a
localized string—if any—that will be used in the HTML title element
of the output. The getHeaderModule(...)
method returns the HTML header
module registered with the controller, and the CSS stylesheet is set. The
renderHeaders(...)
method retrieves the
HTML header module, which renders
the headers onto the page. Lastly, the UI module is rendered through the
UI module JSP.
<%@ include file="/WEB-INF/jsp/WcmHeader.jsp" %>
<html> <head> <% WcmString topic = new WcmString ("server.properties_CustomLaunch_jsp.topic", "Custom Launch Processor"); WcmWorkplaceUi.getHeaderModule(request).addCssFile("css/Processors.css"); WcmWorkplaceUi.renderHeaders(request, out, true, topic); %> </head> <body class="proBody"> <% WcmUi.render(request, "customLaunchModule", out); %> </body> </html> |
The UI module for a Launch Processor creates the workflow, and, therefore, must retrieve the required parameters to do so. The UI module for a Launch Processor does not have to track the workflow state as does the UI module for the Step Processor.
Like all Toolkit UI modules, CustomLaunchModule includes the
initialize(...)
and onStartPage(...)
callbacks. For rendering,
CustomLaunchModule delegates to a JSP module. An event handler is required
to launch the workflow, and an event handler is provided to exit the
launch page without launching.
This section discusses the following methods in CustomLaunchModule:
initialize(...)
, onStartPage(...)
, onLaunch(...)
, onExit(...)
,
redirectTo(...)
, and getFormName()
.
initialize MethodAs shown in the listing below, the initialize(...) method does the following:
- Gets the WcmEProcessDataProvider that was bound to CustomLaunchModule in the event JSP.
- Sets the workflowVersion (required), attachmentID, and subject fields with values retrieved from the request. (These values are part of the workflow definition—CustomWorkflow.pep in the sample). The values are used in the
onStartPage(...)
method to create the workflow object.- Gets the
RETURN_URL
page parameter and caches it to the data store. This value is retrieved from the data store in theonLaunch(...)
andonExit(...)
methods.- Sets the JSP page to use for rendering, CustomLaunchModuleJSP.jsp.
public void initialize() throws Exception
{
WcmController controller = getController();
eProcessDataProvider = (WcmEProcessDataProvider)
queryDataProvider(WcmEProcessDataProvider.TYPE);
if (eProcessDataProvider == null)
{
throw new WcmException("server.CustomLaunchModule.dataProviderUndefined",
"WcmEProcessDataProvider undefined: {0}", getName());
}
// Get the url parameters that specify which workflow to launch,
// and if passed, the initiating attachment id
workflowVersion = WcmEncodingUtil.decodeLabel(controller.getPageParameter(WcmParameter.WORKFLOW_VERSION));
attachmentId = WcmEncodingUtil.decodeLabel(controller.getPageParameter(WcmParameter.ATTACHMENT_ID));
subject = WcmEncodingUtil.decodeLabel(controller.getPageParameter(WcmParameter.SUBJECT));
if ( workflowVersion != null && workflowVersion.length() > 0 ) // Must have a vwVersion
{
eProcessDataProvider.setClassProperty("workflowVersion", workflowVersion );
eProcessDataProvider.setClassProperty("attachmentId", attachmentId);
eProcessDataProvider.setClassProperty(WcmEProcessStateKeys.KEY_SUBJECT, subject);
}
else // Add for Attachment page changes
{
workflowVersion = (String) eProcessDataProvider.getClassProperty("workflowVersion");
attachmentId = (String) eProcessDataProvider.getClassProperty("attachmentId");
subject = (String) eProcessDataProvider.getClassProperty(WcmEProcessStateKeys.KEY_SUBJECT);
}
String returnURL = controller.getPageParameter(WcmParameter.RETURN_URL);
if (returnURL != null && returnURL.length() > 0)
{
eProcessDataProvider.setClassProperty("custlaunch.returnurl", returnURL);
}
// Edit this JSP file to change the rendering
setJSP("apps/CustomLaunchModuleJSP.jsp");
super.initialize();
}
onStartPage MethodAs shown in the listing below, the
onStartPage(...)
method does the following:
- The
doCreateWorkflow(...)
call creates the workflow object from the workflow definition. The data provider will cache the workflow; therefore, reinvoking CustomLaunchModule will reload the cache object.- The
doCreateWorkflow(...)
call also stores the VWStepElement object in the WcmStepElementState object. WcmStepElementState keeps the state of the VWStepElement object, which represents a step in a workflow. The VWStepElement object is referenced in the UI module JSP to provide data for rendering in the HTML form. The object is also referenced in theonLaunch(...)
method to process the form data.
public void onStartPage(HttpServletRequest request, HttpServletResponse response)
throws Exception
{
Document documentXML = (Document) eProcessDataProvider.doCreateWorkflow(workflowVersion,
subject, attachmentId);
super.onStartPage(request, response);
}
onLaunch MethodAs shown in the listing below, the
onLaunch(...)
method does the following:
- Launches the workflow by retrieving the HTML form data and saving the data in the VWStepElement object (
setParameterValue(...)
).- Sets step element parameter values on the Process Engine (
setStepElementParameters(...)
), then saves changes in the workflow and moves to the next workflow step, if any (doStepElementDispatch()
).- Retrieves the value of the return URL from the data store and redirects to that URL.
public void onLaunch(HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// Get the step element object from the state class
WcmStepElementState stepState = WcmStepElementState.getGlobalInstance(eProcessDataProvider);
VWStepElement stepElement = stepState.getVWStepElement();
// Get the step response (if there is one defined in the Workflow Definition)
String stepResponse = (String) request.getParameter("StepResponse");
// Save the form data into the step element object
if ( stepResponse != null )
stepElement.setSelectedResponse(stepResponse);
// Get the list of user defined data fields exposed on this step (no attachments
// or participants).
VWParameter parameters[] = stepElement.getParameters(VWFieldType.BASIC_FIELD_TYPES,
VWStepElement.FIELD_USER_DEFINED);
if ( parameters != null )
{
String parameterName; // The Data Field name
String formData; // The html form field value
// Loop through the list of custom data fields exposed on the workflow step,
// get the html form data (using the data field name as the form field name)
// and save the data into the step element
int size = parameters.length;
for (int index = 0; index < size; index++)
{
parameterName = parameters[index].getName();
formData = (String) request.getParameter(parameterName);
// Will do data type validation, and throw exception if there are problems
stepElement.setParameterValue(parameterName, formData, true);
}
}
// Finally, launch the workflow
eProcessDataProvider.setStepElementParameters(WcmXMLTagsProcessEngine.TYPE_ALL);
eProcessDataProvider.doStepElementDispatch();
eProcessDataProvider.resetClassProperties(true);
String destURL = (String) eProcessDataProvider.getClassProperty("custlaunch.returnurl");
redirectTo(destURL);
}
onExit MethodAs shown in the listing below, the
onExit(...)
method clears the step element data. It then retrieves the value of the return URL from the data store and redirects to that URL.
public void onExit(HttpServletRequest request, HttpServletResponse response)
throws Exception
{
eProcessDataProvider.resetClassProperties(false);
String destURL = (String) eProcessDataProvider.getClassProperty("custlaunch.returnurl");
redirectTo(destURL);
}
redirectTo MethodThis method is called by the
onLaunch(...)
andonExit(...)
methods. As shown in the listing below, theredirectTo(...)
method redirects to the return URL if specified, or closes the window if there is no return URL.
private void redirectTo(String destUrl)
throws Exception
{
if (destUrl != null)
{
WcmURLBuilder url = new WcmURLBuilder(destUrl);
String uri = url.getURI();
if (uri.indexOf("WcmCloseWindow.jsp") < 0 )
{
url = new WcmURLBuilder(
WcmUi.encodeWindowId(getController().getWindowId(),
getBasePath() + "/WcmCloseWindow.jsp") );
url.addParameter("refreshUrl", WcmEncodingUtil.encodeURL(destUrl) );
}
getController().sendRedirect(url.toString());
}
else // Invoked from direct URL, not Tasks tab in Workplace application
{
getController().closeWindow();
}
}
getFormName MethodThis method is called by the UI module JSP (CustomLaunchModuleJSP) and returns the name of the HTML form.
public String getFormName()
{
return "CustomLaunchModule";
}
The UI module JSP renders the Launch Processor HTML form. In the Basic Step Processor sample, the form is similar to the following screen shot.
CustomLaunchModuleJSP.jsp is specified as the rendering JSP in the initialize(...) method of the UI module. This section discusses the following tasks in rendering the launch processor: initialize strings to be rendered, get required objects, get values from workflow data fields, and render HTML.
Initialize Strings to be RenderedThe following code fragment shows the initialization of strings that will be rendered. Note that the WcmString class is used to retrieve localized UI strings from a resource bundle.
// Globalization strings displayed in the html form
String stepName = WcmString.localize("server.CustomLaunchModule_jsp.StepName", "Step Name");
String stepResponse = WcmString.localize("server.CustomLaunchModule_jsp.Response", "Response");
String selectResponse = WcmString.localize("server.CustomLaunchModule_jsp.Response", "Select a response");
String fields = WcmString.localize("server.CustomLaunchModule_jsp.Fields", "Fields");
String value = WcmString.localize("server.CustomLaunchModule_jsp.Value", "Value");
String field1 = WcmString.localize("server.CustomLaunchModule_jsp.Field1", "Field1: (String)");
String field2 = WcmString.localize("server.CustomLaunchModule_jsp.Field2", "Field2: (Float)");
String field3 = WcmString.localize("server.CustomLaunchModule_jsp.Field3", "Field3: (Integer)");
String field4 = WcmString.localize("server.CustomLaunchModule_jsp.Field4", "Field4: (Boolean)");
String field5 = WcmString.localize("server.CustomLaunchModule_jsp.Field5", "Field5: (Date, mm/dd/yyyy hh:mm:ss)");
String launch = WcmString.localize("server.CustomLaunchModule_jsp.Launch", "Launch");
String exit = WcmString.localize("server.CustomLaunchModule_jsp.Exit", "Exit");
Get Required ObjectsTo render, you need the instance of the UI module (CustomLaunchModule), and the instances of WcmEProcessDataProvider and VWStepElement instantiated in the UI module.
In the following statement, the instance of the UI module is returned.
CustomLaunchModule customLaunchModule = CustomLaunchModule)
WcmJSPModule.getCurrentModule(request);In the following statement, the WcmEProcessDataProvider object that is bound to CustomLaunchModule is returned.
WcmEProcessDataProvider eprocessDataProvider = (WcmEProcessDataProvider)
customLaunchModule.queryDataProvider(WcmEProcessDataProvider.TYPE);In the following statements, the instance of the WcmStepElementState is returned, and then used to retrieve the VWStepElement object.
WcmStepElementState stepState = WcmStepElementState.getGlobalInstance(eprocessDataProvider);
VWStepElement stepElement = stepState.getVWStepElement();
Get Values from Workflow Data FieldsData fields are defined in the workflow. They can be defined with or without default values, and may or may not be changed by the user. You get the values in the data fields with the VWStepElement object. The following statements assign the data field values to variables.
String dataField1 = (String)stepElement.getParameterValue("DataField1");
Double dataField2 = (Double)stepElement.getParameterValue("DataField2");
Integer dataField3 = (Integer)stepElement.getParameterValue("DataField3");
Boolean dataField4 = (Boolean)stepElement.getParameterValue("DataField4");
Date dateField = (Date)stepElement.getParameterValue("DataField5");
Render HTMLThis section of the JSP page consists of the HTML, including the HTML form tag that provides users with input fields. Many of the HTML elements include class attributes set to styles defined in the CSS stylesheet, Processors.css.
JSP expressions are used to insert values retrieved from the workflow data fields. The following HTML is for a single input field in the form.
<!-- Table data, display the hardcoded list of data fields, customize here as appropriate -->
<!-- The form field names used here must match the data field names exposed on the step element -->
<tr>
<td align="center" class="proFormRowEven" width="5%"> </td>
<td align="left" class="proFormRowEven" width="40%"><%=field1%></td>
<td align="left" class="proFormRowEven" width="55%">
<input type="text" name="DataField1" style="width:100%" value="<%=dataField1%>"/></td>
</tr>
Two links are rendered: Launch to submit the form input, and Exit to return to the previous page without submitting the input. As shown in the following code fragment, the links include JSP expressions for the form name, the URL, and the anchor text. The form name is set in the UI module and is returned via the getFormName() call. The URL is returned by getEventUrl(), a derived method of the UI module.
String formName = customLaunchModule.getFormName();
...
<a class="proFormLink" href="javascript:document.forms.<%=formName%>.action=
'<%=customLaunchModule.getEventUrl("Launch")%>';
document.forms.<%=formName%>.submit();"><%=launch%></a>
...
<a class="proFormLink" href="<%=customLaunchModule.getEventUrl("Exit")%>">
<%=exit%></a>
As in all event JSP pages, the event
JSP page for a step processor must declare the controller and modules, and
register the modules with the controller. As shown in the following code
fragment, a UI module and data provider module are declared. The UI module
(CustomStepModule) provides event handling and presentation, and
WcmEProcessDataProvider
provides application-level access to the Process Java API. Note that
WcmEProcessDataProvider is bound to CustomStepModule with the
addDataProvider(...)
call.
<%@ page errorPage="/WcmError.jsp" autoFlush="false" %>
<%-- UI Beans --%> <jsp:useBean id="customStepModule" class="com.filenet.samples.processors.basic.apps.server.ui.CustomStepModule" scope="request"> <jsp:setProperty name="customStepModule" property="name" value="customStepModule" /> </jsp:useBean> <%-- Data Provider Bean --%> <jsp:useBean id="eProcessDataProvider" class="com.filenet.wcm.toolkit.server.dp.WcmEProcessDataProvider" scope="request"> <jsp:setProperty name="eProcessDataProvider" property="name" value="eProcessDataProvider" /> </jsp:useBean> <%-- WcmController CONTROLLER --%> <jsp:useBean id="controller" class="com.filenet.wcm.apps.server.controller.WcmWorkplaceController" scope="request"> </jsp:useBean> <% customStepModule.addDataProvider(eProcessDataProvider); ... |
This is a typical UI JSP page in that
it contains HTML tags and invokes rendering of the HTML header tags and
body text. As shown in the following code fragment, the
WcmString is used to retrieve a
localized string—if any—that will be used in the HTML title element
of the output. The getHeaderModule(...)
method returns the
HTML header module registered with
the controller, and the CSS stylesheet is set. The renderHeaders(...)
method retrieves the HTML header module, which renders the headers onto
the page. Lastly, the UI module is rendered through the
UI module JSP.
<%@ include file="/WEB-INF/jsp/WcmHeader.jsp" %>
<html> <head> <% WcmString topic = new WcmString ("server.properties_CustomStep_jsp.topic", "Custom Step Processor"); WcmWorkplaceUi.getHeaderModule(request).addCssFile("css/Processors.css"); WcmWorkplaceUi.renderHeaders(request, out, true, topic); %> </head> <body class="proBody"> <% WcmUi.render(request, "customStepModule", out); %> </body> </html> |
CustomStepModule is similar to CustomLaunchModule in that it includes the
initialize(...)
and onStartPage(...)
callbacks, and delegates rendering to
a JSP module. However, whereas CustomLaunchModule creates a workflow and
launches it, CustomStepModule retrieves the workflow from a specified
queue, renders the data for a specified step, and provides an event
handler to save user input and dispatch the completed step to the Process
Engine.
This section discusses the following methods in CustomStepModule:
initialize(...)
, onStartPage(...)
, onComplete(...)
, onExit(...)
, and redirectTo(...)
. (The getFormName()
method is identical to the corresponding method in CustomLaunchModule.)
NOTE Typically a workflow would consist of multiple steps and, after a completed step, the next step would be routed to a different participant(s). However, the workflow definition in the Basic Step Processor Sample consists of only one step (in addition to the launch step). Therefore, when CustomStepModule dispatches the completed step, the workflow is removed from the system.
initialize MethodAs shown in the listing below, the initialize(...) method does the following:
- Gets the WcmEProcessDataProvider that was bound to CustomStepModule in the event JSP.
- Gets the work object number, which identifies the work item, and the queue name from the request. (These values are part of the workflow definition—CustomWorkflow.pep in the Basic Step Processor Sample). It then caches the values in the data store, using
eProcessDataProvider.setClassProperty(...)
. The values are used in theonStartPage(...)
method to retrieve the step element information from the Process Engine.- Gets the
RETURN_URL
page parameter and caches it to the data store usingeProcessDataProvider.setClassProperty(...)
. This value is retrieved from the data store in theonComplete(...)
andonExit(...)
methods.- Sets the JSP page to use for rendering, CustomStepModuleJSP.jsp.
public void initialize() throws Exception
{
WcmController controller = getController();
eProcessDataProvider = (WcmEProcessDataProvider)
queryDataProvider(WcmEProcessDataProvider.TYPE);
if (eProcessDataProvider == null)
{
throw new WcmException("server.CustomStepModule.dataProviderUndefined",
"WcmEProcessDataProvider undefined: {0}", getName());
}
// Get the url parameters that specify which step to display
and where to return when finished
wobNum = controller.getPageParameter(WcmParameter.WOB_NUM);
queueName = controller.getPageParameter(WcmParameter.QUEUE_NAME);
if ( (wobNum != null && wobNum.length() > 0 ) && (queueName != null && queueName.length() > 0 ))
{
// Set info into data provider so that other step processors can use it later to get the data
eProcessDataProvider.setClassProperty(WcmEProcessStateKeys.KEY_WOB_NUM, wobNum );
eProcessDataProvider.setClassProperty(WcmEProcessStateKeys.KEY_QUEUE_NAME, queueName);
}
// Get the url parameter that specifies where to return when finished
String returnURL = controller.getPageParameter(WcmParameter.RETURN_URL);
if (returnURL != null && returnURL.length() > 0)
{
eProcessDataProvider.setClassProperty("custstep.returnurl", returnURL);
}
// Edit this JSP file to change the rendering
setJSP("apps/CustomStepModuleJSP.jsp");
super.initialize();
}
onStartPage MethodAs shown in the listing below, the
onStartPage(...)
method does the following:
- The
getStepElement(...)
call on the data provider retrieves a VWStepElement object, which represents the workflow step specified by thewobNum
parameter.- The
getStepElement(...)
call also stores the VWStepElement object in the WcmStepElementState object. WcmStepElementState keeps the state of the VWStepElement object, which is referenced in the UI module JSP to provide data for rendering in the HTML form. The object is also referenced in theonComplete(...)
method to process the form data.
public void onStartPage(HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// Retrieve the actual step element object from the data provider.
// Making this call will also store the VWStepELement object in
// the WcmStepElementState object. You can reference this
// object later to do the rendering and process the form data.
Document documentXML = (Document) eProcessDataProvider.getStepElement(
queueName, wobNum, false);
super.onStartPage(request, response);
}
onComplete MethodAs shown in the listing below, the
onComplete(...)
method does the following:
- Gets the VWStepElement object and locks the work element associated with the step element.
- Gets the
StepResponse
parameter from the request, and sets the response setting in the VWStepElement object. (For the sample workflow, the response can either be "Accept" or "Reject".)- Retrieves the remaining HTML form data and saves the data in the VWStepElement object (
setStepParameterValue(...)
).- Sets step element parameter values on the Process Engine (
setStepElementParameter(...)
), then saves changes and moves to the next workflow step, if any (doStepElementDispatch()
).NOTE The sample workflow contains only one step; therefore, after the single step is dispatched, the workflow is removed from the system.
- Retrieves the value of the return URL from the data store and redirects to that URL.
public void onComplete(HttpServletRequest request, HttpServletResponse response)
throws Exception
{
// Get the step element object from the state class
WcmStepElementState stepState = WcmStepElementState.getGlobalInstance(eProcessDataProvider);
VWStepElement stepElement = stepState.getVWStepElement();
stepElement.doLock(true);
// Get the step response (if there is one defined in the Workflow definition)
String stepResponse = (String) request.getParameter("StepResponse");
// Save the form data into the step element object
if ( stepResponse != null )
stepElement.setSelectedResponse(stepResponse);
// Get the list of user defined data fields exposed on this step
// (no attachments or participants).
VWParameter parameters[] = stepElement.getParameters(VWFieldType.BASIC_FIELD_TYPES,
VWStepElement.FIELD_USER_DEFINED);
if ( parameters != null )
{
String parameterName; // The Data Field name
String formData; // The html form field value
// Loop through the list of custom data fields exposed on the workflow step,
// get the html form data (using the data field name as the form field name)
// and save the data into the step element
int size = parameters.length;
for (int index = 0; index < size; index++)
{
parameterName = parameters[index].getName();
formData = (String) request.getParameter(parameterName);
// Will do data type validation, and throw exception if there are problems
stepElement.setParameterValue(parameterName, formData, true);
}
}
// Finally, complete the step
eProcessDataProvider.setStepElementParameters(WcmXMLTagsProcessEngine.TYPE_ALL);
eProcessDataProvider.doStepElementDispatch();
eProcessDataProvider.resetClassProperties(true);
String destURL = (String) eProcessDataProvider.getClassProperty("custstep.returnurl");
redirectTo(destURL);
}
onExit MethodAs shown in the listing below, the
onExit(...)
method unlocks the work item associated with the step without updating the fields on the work item. It then retrieves the value of the return URL from the data store and redirects to that URL.
public void onExit(HttpServletRequest request, HttpServletResponse response)
throws Exception
{
eProcessDataProvider.doStepElementAbort();
eProcessDataProvider.resetClassProperties(false);
String destURL = (String) eProcessDataProvider.getClassProperty("custstep.returnurl");
redirectTo(destURL);
}
redirectTo MethodThis method is called by the
onComplete(...)
andonExit(...)
methods. As shown in the listing below, theredirectTo(...)
method redirects to the specified return URL if specified, or closes the window if there is no return URL.
private void redirectTo(String destUrl)
throws Exception
{
if (destUrl != null&& destUrl.length() > 0)
{
getController().closeWindow(); WcmURLBuilder url = new WcmURLBuilder(destUrl);
url.addParameter("refreshUrl", WcmEncodingUtil.encodeURL(destUrl));
getController().sendRedirect(url.toString());
}
else // Invoked from direct URL, not Tasks tab in Workplace application
{
getController().closeWindow();
}
}
The UI module JSP renders the Step Processor HTML form. In the Basic Step Processor Sample, the form is similar to the following screen shot. Note that because the sample workflow definition consists of only a single step (in addition to the launch step), the workflow is removed from the system after the one step is completed.
CustomStepModuleJSP.jsp is specified as the rendering JSP in the
initialize(...)
method of the UI
module. This section discusses the following tasks in rendering the step
processor: initialize strings to be rendered, get required objects, get
values from workflow data fields, and render HTML.
Initialize Strings to be RenderedThe following code fragment shows the initialization of strings that will be rendered. Note that the WcmString class is used to retrieve localized UI strings from a resource bundle.
// Globalization strings displayed in the html form
String stepName = WcmString.localize("server.CustomStepModule_jsp.StepName", "Step Name");
String stepResponse = WcmString.localize("server.CustomStepModule_jsp.Response", "Response");
String selectResponse = WcmString.localize("server.CustomStepModule_jsp.Response", "Select a response");
String fields = WcmString.localize("server.CustomStepModule_jsp.Fields", "Fields");
String value = WcmString.localize("server.CustomStepModule_jsp.Value", "Value");
String field1 = WcmString.localize("server.CustomStepModule_jsp.Field1", "Field1: (String)");
String field2 = WcmString.localize("server.CustomStepModule_jsp.Field2", "Field2: (Float)");
String field3 = WcmString.localize("server.CustomStepModule_jsp.Field3", "Field3: (Integer)");
String field4 = WcmString.localize("server.CustomStepModule_jsp.Field4", "Field4: (Boolean)");
String field5 = WcmString.localize("server.CustomStepModule_jsp.Field5", "Field5: (Date, mm/dd/yyyy hh:mm:ss)");
String complete = WcmString.localize("server.CustomStepModule_jsp.Complete", "Complete");
String exit = WcmString.localize("server.CustomStepModule_jsp.Exit", "Exit");
Get Required ObjectsTo render, you need the instance of the UI module, CustomStepModule, and the instances of WcmEProcessDataProvider and VWStepElement instantiated in the UI module.
In the following statement, the instance of the UI module is returned.
CustomStepModule customStepModule = (CustomStepModule) WcmJSPModule.getCurrentModule(request); In the following statement, the WcmEProcessDataProvider object that is bound to CustomStepModule is returned.
WcmEProcessDataProvider eprocessDataProvider = (WcmEProcessDataProvider)
customStepModule.queryDataProvider(WcmEProcessDataProvider.TYPE);In the following statements, the instance of the WcmStepElementState is returned, and then used to retrieve the VWStepElement object.
WcmStepElementState stepState = WcmStepElementState.getGlobalInstance(eprocessDataProvider);
VWStepElement stepElement = stepState.getVWStepElement();
Get Values from Workflow Data FieldsData fields are defined in the workflow. They can be defined with or without default values, and may or may not be changed by the user. You get the values in the data fields with the VWStepElement object. The following statements assign the data field values to variables.
String dataField1 = (String)stepElement.getParameterValue("DataField1");
Double dataField2 = (Double)stepElement.getParameterValue("DataField2");
Integer dataField3 = (Integer)stepElement.getParameterValue("DataField3");
Boolean dataField4 = (Boolean)stepElement.getParameterValue("DataField4");
Date dateField = (Date)stepElement.getParameterValue("DataField5");
Render HTMLThis section of the JSP page consists of the HTML, including the HTML form tag that provides users with input fields. Many of the HTML elements include class attributes set to styles defined in the CSS stylesheet, Processors.css.
JSP expressions are used to insert values retrieved from the workflow responses and data fields. The following HTML is for the drop-down box where the user selects either "Approved" or "Rejected". Note that the check for a selected response evaluates to false because the response was not available to be set in the launch step.
<tr>
<td align="center" class="proFormRowOdd" width="5%"> </td>
<td align="left" class="proFormRowOdd" width="40%"><%=stepResponse%>:</td>
<td align="left" class="proFormRowOdd" width="55%">
<select name="StepResponse" size="1" class="proLabel">
<option class="proFormText"><<%=selectResponse%>></option>
<%
String selectedResponse = stepElement.getSelectedResponse();
for (int i = 0; i < responses.length; i++)
{
if ( responses[i].equals(selectedResponse) )
{
%>
<option selected="true" class="proFormText" ><%=responses[i]%></option>
<%
}
else
{
%>
<option class="proFormText"><%=responses[i]%></option>
<%
}
}
%>
</select>
</td>
</tr>Two links are rendered: Complete to submit the form input, and Exit to return to the previous page without submitting the input. As shown in the following code fragment, the links include JSP expressions for the form name, the URL, and the anchor text. The form name is set in the UI module and is returned via the getFormName() call. The URL is returned by the getEventUrl(), a derived method of the UI module.
String formName = customStepModule.getFormName();
...
<a class="proFormLink" href="javascript:document.forms.<%=formName%>.action=
'<%=customStepModule.getEventUrl("Complete")%>';
document.forms.<%=formName%>.submit();"><%=complete%></a>
...
<a class="proFormLink" href="<%=customStepModule.getEventUrl("Exit")%>">
<%=exit%></a>
The CSS stylesheet, Processors.css, is used for both the Launch Processor and the Step Processor. Its use is specified in the UI JSPs of the processors. CSS definitions are based on class names rather than HTML element names; that is, HTML tags to which styles are applied include a class attribute. Many of the HTML tags in the UI module JSP pages include class attributes.
Register the HTML ProcessorsUsing the Process Configuration Console, you must register new processors with the Process Engine. This section summarizes the procedure.
To register the custom processors:
Your connection point setting must match the "Process Engine Connection Point" setting in the Workplace Site Preferences.
You create workflow definitions with the Process Designer. You can create a test workflow from scratch, or you can use the workflow provided in the Basic Step Processor Sample. This section summarizes both approaches.
To launch the Process Designer from the Workplace tree view, select Author/Advanced Tools, then choose Process Designer.
To create a workflow definition:
To use the sample workflow definition:
To test your custom Launch Processor and Step Processor:
The Transfer Workflow page is displayed.
The workflow is transferred to the Process Engine.
If you are using the workflow from the Basic Step Processor Sample, the HTML form for the launch step should be similar to the following screenshot.
This saves the workflow and dispatches the next work item to its assigned queue (as specified in the workflow definition). If you are using the sample workflow, the next work item appears in the Inbox on the Tasks page.
If you are using the workflow from the Basic Step Processor Sample, the HTML form for Step 1 should be similar to the following screenshot.