This section provides a detailed explanation of the technical elements of the workflow portlet. Since the default implementation relies heavily on the capabilities of jBPM, this section gives a technical overview of jBPM and explains how it integrates into Liferay using their JPDL formatted XMLs. It does not, however, give an in depth view of jBPM. For that, refer to the jBPM user guide (http://docs.jboss.com/jbpm/v3/userguide).
Before the workflow portlet can be used, business processes must be defined. Business processes in jBPM are defined by XML documents known as process definitions which are written in jBPM Process Definition Language (JPDL). These XMLs specify entities such as the process roles (known as swimlanes), the various states in the process (known as nodes), the tasks associated with each node, the roles associated with each task, the transitions from one node to the next, the variables associated with each task’s form, the external actions executed on entry or exit of a node, and many others. For an in depth understanding of process definitions and JPDL, refer to JBoss’ jBPM user guide at http://docs.jboss.com/jbpm/v3/userguide/jpdl.html.
There are three sample process definition XMLs that are packaged with the portlet. They can be found in jbpm-web.war/WEB-INF/definitions. An explanation of each is included in section 2.4. In addition, section 2.4 includes a “Notes” section that gives pointers on Liferay specific implementations of JPDL.
In JPDL, there are process roles called swimlanes. Swimlanes can be associated with Liferay users, groups, and roles via the IdentityAssignmentHandler class.
<swimlane name="approver"> <assignment class="com.liferay.jbpm.handler.IdentityAssignmentHandler" config-type="field"> <type>user</type> <companyId>liferay.com</companyId> <id>liferay.com.1</id> </assignment> </swimlane>
In the XML above, the “approver” swimlane is associated with the Liferay user that has a User ID of “liferay.com.1” and belongs to a Company ID of “liferay.com.” You can also associate a Liferay user with a swimlane by email address as shown in the following XML snippet.
<swimlane name="shipper"> <assignment class="com.liferay.jbpm.handler.IdentityAssignmentHandler" config-type="field"> <type>user</type> <companyId>liferay.com</companyId> <name>[email protected]</name> </assignment> </swimlane>
In the XML above, the “shipper” swimlane is associated with the Liferay user that has an email address of “[email protected]” and belongs to a Company ID of “liferay.com.”
<swimlane name="salesman"> <assignment class="com.liferay.jbpm.handler.IdentityAssignmentHandler" config-type="field"> <type>group</type> <companyId>liferay.com</companyId> <id>3</id> </assignment> </swimlane>
In the XML above, the “salesman” swimlane is associated with any Liferay user that belongs to a Group with the Group ID of “3” (which defaults to the “Support” community) and Company ID of “liferay.com.” In other words, the salesman swimlane is assigned to the pool of “Support” users. If one of these users were to manage a salesman task, he/she would automatically be assigned to all other salesman tasks in the workflow.
<swimlane name="accountant"> <assignment class="com.liferay.jbpm.handler.IdentityAssignmentHandler" config-type="field"> <type>group</type> <companyId>liferay.com</companyId> <name>Support</name> </assignment> </swimlane>
The XML above shows an alternative way to associate the “accountant” swimlane with the Support community using the actual community’s name. Since community names must be unique per Company ID, this format accomplishes the same results as the previous XML.
<swimlane name="user_admin"> <assignment class="com.liferay.jbpm.handler.IdentityAssignmentHandler" config-type="field"> <type>role</type> <companyId>liferay.com</companyId> <id>1001</id> </assignment> </swimlane> <swimlane name="user_interviewer"> <assignment class="com.liferay.jbpm.handler.IdentityAssignmentHandler" config-type="field"> <type>role</type> <companyId>liferay.com</companyId> <name>User Interviewer</name> </assignment> </swimlane>
The two XML snippets above are very similar to the Group XML snippets. Both associate their respective swimlanes with a role, but the first XML does so using the Role ID and the second XML does so using the role’s unique name.
Currently, jBPM does not have support for variable data types. However, data types have been dealt with in the workflow portlet by incorporating them into the names of the controller variables. The table below shows the data types supported by the portlet and the syntax for the variable names:
Data Type | Syntax | Description |
Checkbox | checkbox:name:checkedValue | name = the caption next to the checkbox checkedValue = the value assigned to the variable if the checkbox is checked |
Date | date:name | name = the caption next to the date selector object |
email:name | name = the caption next to the text input field | |
Number | number:name | name = the caption next to the text input field |
Password | password:name | name = the caption next to the text input field |
Phone | phone:name | name = the caption next to the text input field |
Radio Button | radio:name:option1,option2,…* | name = the caption next to the radio buttons option1,option2,…* = a comma-delimited list of options that represent the different radio button options |
Select Box | select:name:option1,option2,…* | name = the caption next to the select box option1,option2,…* = a comma-delimited list of options that represent the different options in the select drop-down |
Text | text:name | name = the caption next to the text input field |
Textarea | textarea:name | name = the caption next to the textarea input field |
Note that for all name and option values, the values should be entered in the XML in lowercase with hyphens used between words. For example:
radio:are-you-hungry:yes,no,a-little-bit
In addition, you should register the corresponding display values in the Language.properties file. For example:
are-you-hungry=Are you hungry? yes=Yes no=No a-little-bit=A little bit
This will ensure that the values are displayed correctly in the portlet to the user. By default, all variables are readable and writable by the user. Therefore, they can be defined as follows:
<variable name="textarea:comments" />
However, if variables should only be readable or writable, or if variables are required, these must be specified in the variable definition:
<variable name="text:name" access="read,write,required" /> <variable name="date:birthday" access="read" />
Variables of data type Date, Number, Email, and Phone are validated in the service call. Also, required fields are validated to ensure a value of some kind was submitted. If invalid values are submitted, the user is returned to the original form and error messages are displayed next to the invalid input fields. Refer to the sample definition jbpm-web.war/WEB-INF/definitions/datatypes_definition.xml for examples of all data types in use in a single form.
The best way to understand JPDL is to look over the 3 sample PAR files included with the workflow portlet. They can be found in jbpm-web.war/WEB-INF/definitions/. Below is a quick summary of each:
datatypes_definition.xml – a good guide to follow to understand how to use each of the data types described in section 2.3
holiday_definition.xml – a simple workflow that allows an employee to make a holiday request with a start and end date, and then a manager can either approve, reject, or send the request back for review
websale_definition.xml – a more complex workflow that emulates an online auction site in which control of the workflow passes through various roles. It is the most complicated of the 3 workflows, but it demonstrates almost all of the BPM features offered by jBPM
Notes:
The JPDL definition XMLs can be created through a graphical design tool offered by JBoss, but that is beyond the scope of this document (see http://docs.jboss.com/jbpm/v3/gpd/ for a detailed explanation) and is also beyond the scope of the portal.
For nodes that have tasks associated with them, each of the variables in the controller will be converted to a form element that the user must update.
For nodes that have tasks associated with them, each of the transitions out of the node is represented as a button in the task’s form. The transition’s name attribute should always be in lowercase with hyphens between words and registered in Language.properties. The display value is used as the button’s name.
Many of the action handler classes found in the com.liferay.jbpm.handler package are just place holders that output relevant text to the console. Conceivably, these classes could perform operations such as sending out emails, initiating batch processes, updating legacy systems...etc.
The websale workflow demonstrates the following jBPM concepts, all of which are discussed in further detail in the jBPM user guide (http://docs.jboss.com/jbpm/v3/userguide/):
Events
Beanshell scripting
Swimlanes
Tasks
Assigment (User/Pool)
Controllers
Variables
Timers
Node Types
State
Task
Fork
Join
Decision
Transitions
Actions
If you have warning messages turned on for your server, in your console you may see some variant of the following message output several times when jBPM is called:
WARN [org.hibernate.engine.StatefulPersistenceContext] Narrowing proxy to class org.jbpm.graph.node.TaskNode - this operation breaks ==
According to the following post on the JBoss forums (from Koen Aers, one of the key contributors to the jBPM project), this is not an error and is not of significance. He explains the reason this warning is thrown: http://www.jboss.com/?module=bb&op=viewtopic&t=73123