UEngine English Version Wiki

Uwiki

목차

User Manual

Open Source BPMS - uEngine Introduction

This manual tries to explain the whole processes of practical uses via uEngine open source BPMS which is available to everybody without charge. Therefore, anybody who is interested in making use of uEngine BPMS or providing services to others can experience useful processes much more directly.


The uEngine BPMS is the first professional open source product in Korea. It is designed that all components of the product can be easily embedded. Recently, many companies focus on adopting BPMS, with their existing software integration, duplicate functionality, and TCO(Total Cost of Ownership), these difficulties can be positively solved by the uEngine BPMS.


Figure 4-1 uEngine provides the most features that many commercial BPMS providers support with an integration between BI, portal, Web Services and proved many different open sources
Figure 4-1 uEngine provides the most features that many commercial BPMS providers support with an integration between BI, portal, Web Services and proved many different open sources


The core of uEngine consists of component framework which makes possible on special integration patterns such as new activity types, external organization charts, united data managements between external applications. It is a big difference that the “embedded uEngine’s BPMS” has the capability of handling various overheads during integrations and customization tasks while most existing BPM solution providers can not avoid these problems.


Embedded BPM

Since uEngine initially started developments based on component assembly architecture, it has experienced as an OEM provider integrated with various product suites from other companies. With history and technical based characteristic of the product, it helps users have not only a server/client mode, but also a library/framework mode which helps users integrate external organization charts via a callback implementation, data extraction through its engines’ event extraction, interfacing with external messenger or worklist as an implementation model. In addition, it provides an Activity wrapping functionality that users make use of various existing software products while modeling business processes.


Figure 4-2 uEngine provides a framework and plugin tools that help users add new activity types to existing software or software based architecture which is easily adaptable in BPM environment
Figure 4-2 uEngine provides a framework and plugin tools that help users add new activity types to existing software or software based architecture which is easily adaptable in BPM environment


Especially, this feature gives at lease impact on well structured existing application architectures (organization management(HR), approvals or groupware, EAI, in the case of standardization settled) . It can be a great choice for companies who want to internalize BPM. Those software companies who develop ERP, PDM, SCM, CRM, or existing management information systems can embed uEngines to their own software products under the LGPL license agreement with uEngine Solutions. It is effective that they make use of uEngine special features and able to upgrade or differentiate their own software products to be BPM based systems.

Practical Use of BPMS - Lifecycle

How to install and run uEngine

uEngine Download

Visit the page, http://sourceforge.net/projects/uengine/files/, and download the latest version of uEngine on the download page.

- Java 1.5 or higher versions must be installed in order to run uEngine.


Figure 5-1 uEngine Download
Figure 5-1 uEngine Download


uEngine installation and execution


Windows Environment
  1. Extract downloaded files in an appropriate folder.
  2. Set up JAVA_HOME in order to run the server properly.
    1. Click the “Environment Variables” under the “Advanced” tab menu in the System Properties. (Set up the folder path in which JDK is installed) [Figure 5-2]
    2. Set up the “System Variables” in the “Startup.bat” file. [Figure 5-3]
    3. Like [Figure 5-4] and [Figure 5-5] Run both DB and WAS.
Figure 5‑2 JAVA_HOME Configuration
Figure 5‑2 JAVA_HOME Configuration


Figure 5‑3 JAVA_HOME Configuration
Figure 5‑3 JAVA_HOME Configuration


Figure 5‑4 Demo DB Execution(runHSQLServer.bat)
Figure 5‑4 Demo DB Execution(runHSQLServer.bat)


Figure 5‑5 WAS Execution(startup.bat)
Figure 5‑5 WAS Execution(startup.bat)


Launch the web browser, type the url, http://localhost:8080/uengine-web. The part of url, ‘http://’ must be entered. Log in with the administrator account[ID:test / PW:test].


Figure 5‑6 uEngine Login Screen
Figure 5‑6 uEngine Login Screen


uEngine User Interface

uEngine’s User Interface consists of two frames. The first frame is the menu area located on upper region of the screen,and the other frame is the user area except for the menu area. The menu area consists of Home, WorkList, Strategy, Process, Monitor, Process Manager, Analysis, Organization that link with Portlet pages. By clicking along the pages, user working space can appear on the screen.

Portlet PageDescription
WorkListCurrently assigned work list according to the status of each task(in Progress, Completed, Cancelled).
ProcessNew work processes can be distinguished by field, and processes can be run in the page. It helps users understand the flow of the process at a glance.
Process ManagerBy using this menu, processes can be easily manageable. The current processes in progress can be easily displayed.
AnalysisBy using OLAP tool, users can view information in a preferred format such as table or chart.
OrganizationConfigure organizational structures via associate registration, responsibility management
Table 5‑1 uEngine Menu Structure


Figure 5‑7 uEngine Main Page
Figure 5‑7 uEngine Main Page


Process Automation – Process Enactment

Process automation is the functionality that users execute existing electronic processes(Process Definitions) by themselves without the help of IT department. It distributes and controls each defined task. The characteristics of process automation are following.

  • Users do not need to look for tasks. Tasks look for the people in charge of the assigned tasks instead.
  • It maximizes the synergy effect between various systems related to the process execution.


Initiate Work

In order for the end user to initiate a work process, the "Process Map" under the “Process” menu is useful. Like the following [Figure 5-8] and [Figure 5-9], by selecting “Issue Tracking Process” and clicking the ”Initiate this Process” the selected task can begin.

Figure 5‑8 Work Initiation Screen
Figure 5‑8 Work Initiation Screen


Figure 5‑9 Work Initiation Screen
Figure 5‑9 Work Initiation Screen


Work Progress

From the previous instruction, by clicking “Initiate this Process” the first task of the work, ‘Create New Issue’ screen(called as a workitem handler) is loaded. The following figure shows that users type the trouble description simply and click the “Confirm” button, therefore, the process is initiated immediately.

Figure 5‑10 The step of creating a new issue
Figure 5‑10 The step of creating a new issue


The next task is that the ‘Assignee’ who is chosen by the previous step of the task writes an issue report after understanding the issue, therefore, only the selected users should log in.

By using user main screen or WorkList menu, assigned tasks can be displayed. The new task, ‘Issue Tracking Process’ can be clicked if it exists. As a result of that, the following workitem handler is loaded. The current task progress can be analyzed and the issue handling plan or results can be entered. And then, by clicking “Confirm” button, the task is finally completed.

Figure 5‑11 The step of creating the issue report
Figure 5‑11 The step of creating the issue report

The next step is that the initiator who writes an issue checks the handling plan or result, so with the initiator account, the access can be permitted in order to complete the step. After reviewing the issue report, the completion can be made based on the result. (According to the selection, issue reports can be needed again, or issue handling result registration or closure can be made.)

Figure 5‑12 The step of approving the resolution report
Figure 5‑12 The step of approving the resolution report

Process Monitoring

Monitoring functionality such as flow chart, Gantt chart, and dashboard helps users make sure current task progresses which are sometimes hidden. It is a notification function that shows various critical elements, therefore, users are able to take an action against the difficulties.

  • Do not need to wait for incorrect task progress reports.
  • It makes possible to plan effective task distributions by task managers.
  • Overcome task delays due to emotional or political reasons in organization via a transparent task control.


Confirm Process Instance 'Progress' or 'Completion Status'

Visit the ‘Process Manager’ menu under the uEngine page.

Figure 5‑13 Process Manager
Figure 5‑13 Process Manager

Each instance whether it is in progress or completed can be shown on the “Process Instance List”. Current instances which are in progress are shown by clicking the instance like [Figure 5-13].

Figure 5‑14 Process Instance in Progress
Figure 5‑14 Process Instance in Progress


Like [Figure 5-14] shown above, it is an instance enacted by the “Issue Tracking Process” definition. It shows that the third task(handling the issue) is being executed. Moreover, users are able to check process variables and the information of participants .

Process Analysis

Process Analysis’s main goal is customer satisfactory resulted from the success of process bottleneck detection, optimized human resource allocation, and process execution outcomes that are critical issues in process operation.

With these analysis outcomes, the optimal elements that improve current process definitions can be brought up. BPM lifecycle can also be managed by continuous improvements of processes like the one mentioned earlier.


Process Analyzer Structure

In order to analyze processes, visit the “Analyzer” menu.

Figure 5‑15 Process Analysis
Figure 5‑15 Process Analysis


Figure 5‑16 Process Analyzer Structure
Figure 5‑16 The Structure of Process Analyzer


Process Analyzer consists of Menu Icons, OLAP Navigator, Pivot table, and Chart. OLAP Navigator is a design tool that displays the data generated from the Pivot table which is also extracted from instance data in any format. In addition, Pivot table shows the same data as OLAP Navigator has, and it is possible to drill down the detailed elements in a row or column, or swap the vertical and horizontal axes(Swap Axes). It is very similar to Excel’s Pivot functionality.

For various perspectives of data, the followings are the icons of OLAP Navigator which consists of multi-dimensions.

IconsFunctionality
파일:Column.jpgMove dimension to "Columns" area.
파일:Rows.jpgMove dimension to "Rows" area
파일:Filters.jpgMove dimension to "Filters" area.
파일:Updown.jpgMove dimension up/down in the current area
Table 5‑3 The Structure of OLAP Navigator Icons

The Columns and Rows of OLAP Navigator are criterions which display the data composed with vertical or horizontal elements for each table respectively. Filters are essential elements that construct data, but the only filtered data by the “Filters” will be resulted in tables, even though hidden data is a part of the whole data. After manipulating data by “Pivot Table”, users are able to create charts that reflect the “Pivot Table”. By clicking “Chart Config” icon, the types and shapes of the charts can be configured.

Practical Analysis of Trouble Ticket Task

First of all, let us practice with an analysis example that shows the total or average hours consumed for the task by participant’s age based on year 2007 data. These “Resource by Birthday”, “Processing Time (Sum)” , “Processing Time (Avg)” fields are required. The following table, [5-3] describes the requirements in a simple way.


Measures
ResourceByBirthday Processing Time(Sum) Processing Time(Avg)
1968
....
....
....
Table 5‑4 Pivot Table Example

In order to create the table above, we need to configure the OLAP Navigator as below.


Figure 5‑17 OLAP Navigator
Figure 5‑17 OLAP Navigator


Click the “OK” button and Run the OLAP Navigator. You will see the changes of the table as below.


Figure 5‑18 Pivot Table
Figure 5‑18 Pivot Table


In order for us to configure details in [Figure 5-18], click “Measures” on OLAP Navigator, and uncheck the “Cost”, and uncheck “All Resources” from “ResourceByBirthday”,but keep the child fields of “All Resources” checked. Additionally, check “2007” from “Time” category, and click the “OK” button. Finally, the “Pivot Table” is completed like the [Figure 5-19] shown below.


Figure 5‑19 Completed Pivot Table
Figure 5‑19 Completed Pivot Table


Configure charts based on the data filtered previously, click this icon, 파일:chart.jpg [Figure 5-21].

Figure 5‑20 Chart Configuration
Figure 5‑20 Chart Configuration


In [Figure 5-21] shown below, the completed analysis result can be obtained. According to the purpose of analysis, various charts can be configured.

Figure 5‑21 Completed Analysis Result
Figure 5‑21 Completed Analysis Result

Witam serdecznie!

Szukam i szukam i znalezc przyczyny nie moge... problem mam nastepujacy: moja strona (<a href=http://www.nieruchomosci-pila.net>mieszkania Piła wynajem</a>) raz sie otwiera innym razem z kolei dostaje jakies dziwne komunikaty albo w ogole przegladarka twierdzi, ze takiej strony nie ma. Do tego na niektorych kompad pod internet explorerem wyswietla mi sie wyszukiwarka binga - i tam pojawia sie na pierwszym miejscu link ktory... zazwyczaj otwiera strone. Macie jakies pomysly?

Bede wdzieczny za wszelkie propozycje, nagroda - szczegoly na PW!

Basic Process Modeling

How to Use Modeling tools

Process Definition Creation

Process Managers need to create a new folder if there is no related folder existing in the “Process Definition” tree. It is a good way to manage process definitions by related groups like file folders.


Figure 6‑1 New Folder Creation
Figure 6‑1 New Folder Creation


In order to create a new folder like the [Figure 6-1] shown above.

  • Under the root of “Definitions” tree, the toggle function which is working with the clicks of a mouse allows users to view the whole list of process definitions in active.
  • Open the whole list of process definitions by the right clicks of a mouse on the selected folder under the root of “Definitions” tree.
  • After right-clicking on the “Definitions” tree with your mouse, a shortcut menu appears on the screen, choose the “New” and click the “Child Folder”.
  • A small [Insert name] window pops up, enter a new folder name(for instance, “Test”)


Figure 6‑2 Double-check Folder Creation
Figure 6‑2 Double-check Folder Creation


Like the [Figure 6-2] shown above, we make sure that the “Test” folder is just created.

For creating new process definitions under the folder which we created previously, right-click on the folder, select the “New” menu, and select the “Process”, As a result of that, the “Process Designer”[Figure 6-3] is executed automatically.


Figure 6-3 Process Designer
Figure 6-3 Process Designer


The top region of the “Process Designer” which consists of various Activity types is also called Activity Type Palette. Among these activity types, “Human Work” Activity under the “Document” group can be clicked or drag and drop the Activity icon onto the “Flow Chart” region or Working space.


Figure 6-4 Activity Type
Figure 6-4 Activity Type


Like [Figure 6-5], the selected Activity is added into the center of “Flow Chart” region on the “Process Designer”


Figure 6‑5 Human Activity Addition
Figure 6‑5 Human Activity Addition


When removing added Activities, there are several ways to conduct the removal. The first one is that select the Activity which has a transparent rectangle with red dotted line around it and hit the “Delete” key. The second way is to right-click on the Activity and select the “Delete” button. Lastly, drag and drop the Activity into the “Trash Can” located on the bottom of the screen.

In order to configure properties for the selected Activity on the Flow Chart, double-click the Activity. In the case of “Human Work”, a new window pops up, and users are able to make changes on the properties of the selected “Human Work”. And then, we simply type “Trouble Ticket” for Activity name. The responsibility for the role can be “Initiator”. Finally, all the changes can be applied by clicking the “Apply” button.


Figure 6‑6 Human Work Properties
Figure 6‑6 Human Work Properties

If there are no error marks(파일:Error_icon.jpg) , all the properties are configured correctly. In case, there are errors, we can check the error messages using “Integrity” menu under the “Properties” tab.

Process Enactment

For executing Process Definitions created by users, server deployment is required through either clicking the icon(파일:Deployment_icon.jpg), located on the top tool bar or hitting the “Deploy” button on the bottom of the screen. As a result, a new dialog window appears on the screen. Type an appropriate process name for the task(For instance, subTest) and click the “Confirm” button. Finally, “Deployment” is completed


Figure 6-7 Deployment
Figure 6-7 Deployment


In order to make sure that the “Deployment” is successful, The [subTest] process must be created under the [Test] folder, and the “Set as a Production” button must be clicked, therefore, users are able to make use of the process that we just created.


Figure 6‑8 Created Process Definition Confirmation
Figure 6‑8 Created Process Definition Confirmation


For executing this Process Definition, like [Figure 6-9] the “Initiate” button must be clicked.


Figure 6‑9 Starting Process
Figure 6‑9 Starting Process


The following [Figure 6-10] shows the tasks in progress. By clicking the “Complete” button, the corresponding workitem is completed. So far, we have only one Activity, the whole process can be finished when clicking the “Complete” button.


Figure 6‑10 The Screen of WorkItem in progress
Figure 6‑10 WorkItem in progress


The following [Figure 6-11] shows the result of completed workitems. The execution information of finished processes or processes in progress can be checked by selecting the “Process Manager”. (We called as a process instance which resulted after executing processes.)


Figure 6-11 The Screen of Completed Workitem
Figure 6-11 Completed Workitem


<Figure 6-12> shown below describes that processes are currently executed or shows the information of completed process instance. In order to check the execution results of the completed “Trouble Ticket” instance, click the corresponding instance on the list of instances.


Figure 6‑12 List of Process Instances
Figure 6‑12 List of Process Instances


<Figure 6-13> shows the result of completed “Trouble Ticket” process after executing. The top of the screen allows users to view the step of executed instance via Flowchart tab menu along with process variables and participants’ role information.


Figure 6‑13 Completed Process Information
Figure 6‑13 Completed Process Information
Process Variable Configuration

This Process Definition does not request any tasks to users. We need to advance this process in order to receive or handle some type of data from users. For the purpose of this, the“Improve” button should be clicked, and the “Process Designer” is executed. Therefore, we are able to create process variables. Process variables can be created by these “Edit Variables” and “New” windows that appear on the screen accordingly after clicking near the “Variables” right next to the “Roles” on the bottom region of the “Process Designer”.


Figure 6‑14 Click the “Improve” button in order to Improve Processes
Figure 6‑14 Click the “Improve” button in order to Improve Processes


On [New Process Variable] window, Process Variables can be created like the [Figure 6-15] below


Figure 6‑15 Process Variable Creation
Figure 6‑15 Process Variable Creation


After typing all the information of Process Variable, click the “Update” button and close the “New Process Variable” window. With “Edit Variables” window like [Figure 6-16], users are able to view all the process variables that already created. Even they can view all the detailed information of the selected process variable by right-clicking on it which shows a popup menu, and select the “Open” from the menu.


Figure 6-16  Double-check Process Variable Creation
Figure 6-16 Double-check Process Variable Creation


After creating a Process Variable for “subTest” process for Trouble Ticket, users can configure the properties for the first “Report a Trouble” Activity of our example process. By clicking on the Activity, the second tab of the Human Work Activity, in the case of ‘Report a Trouble’ can be selected and scroll down its window, “Parameters” is placed in the bottom of the window. After then, click the “New” button right above the “Parameters” field, related process variables can be selected. The [Figure 6-17] shown below appears, therefore, the created process variable, “Trouble Type” can be selected.


Figure 6-17 Process Variable Addition into Activity
Figure 6-17 Process Variable Addition into Activity


After adding process variables to Activities, Another ‘Deployment’ is required. After then, a new version must be set into production in older versions, which are lower than ‘3.5.2’. From Process Definition List, select the “subTest” process for Trouble Ticket, and Hit the “Initiate” button.


Figure 6‑18 Initiating after Configuring Process Variables
Figure 6‑18 Initiating after Configuring Process Variables


Like the [Figure 6-19], the “Trouble Type” input box is created, and enter “System” value for the input box, and complete the task.


Figure 6‑19 User Interface for  the Configured Process Variable
Figure 6‑19 User Interface for the Configured Process Variable


The following [Figure 6-20] shows that “System” value is displayed that it differs from previously defined process at the beginning of this process before adding ‘Trouble Type’ process variable to the Activity.


Figure 6‑20 Completed Process Information
Figure 6‑20 Completed Process Information
Basic Example of Process
  1. The Goal of this Process Example
    Let us assume that we have a new work process in our organization. The work is called as “Trouble Ticket Process”, our users experience various system troubles while using our computer systems. The process conducts these works such as receiving troubles, solving the troubles by people in charge, giving feedbacks to the people who reported the troubles.

  2. A Scenario of this Process
    1. Users who experience troubles report the issues.
    2. Trouble handling manager reads the troubles, assigns appropriate people who can handle the troubles and forwards the description of the troubles.
    3. The people in charge write answers for the troubles.
    4. The answers are automatically delivered to the users who initially reported the troubles via email.


The following [Figure 6-21] depicts the whole steps of the process in an easy manner.


Figure 6‑21 Trouble-Ticket  Process
Figure 6‑21 Trouble Ticket Process
Process Definitions

After logging in, create a ‘Trouble-Ticket’ group folder in which we make some tests. Run the “Process Designer”, finally, we are ready to practice modelings. The followings are the steps in order to conduct modelings.

  1. Participant Definitions
  2. Process Variable Definitions
  3. Process Flow Definitions


These are three big parts. Each part works parallel if required

  • Participant Definitions

“Participant Definitions” is a step which defines responsibilities for participants’ roles in the process. The followings are the responsibilities for the current example, “Trouble Ticket Process”

  1. User: People who report troubles
  2. Manager: Receives the troubles and assigns people in charge of handling troubles.
  3. right Person: A practical person who solves the assigned troubles.


The following [Figure 6-22] shows the steps of assigning responsibilities.

Figure 6‑22 Defining Participants
Figure 6‑22 Defining Participants


  1. Click the “Roles” definition panel on the bottom of the screen
  2. Click the “New” button after opening “Edit Roles” window
  3. Type Role ID and Display Name for the Role

With those ways, assign User, Manager, and right Person as participant.

Role IDDisplay Name for the Role
UserUser
ManagerManager
RightpersonRight Person

Table 6‑1 Role Definition Configuration


Process Variable Definition

There are process variables needed in order for all Activities to send/receive data each other in modeling. The following variables are needed for “Trouble-Ticket Process” example.

  1. Trouble_desc
  2. Trouble_result
  3. Trouble_type


The following [Figure 6-23] shows the steps of creating variables.


Figure 6‑23 Process Variable Definition
Figure 6‑23 Process Variable Definition


  1. Click the “Variables” panel on the bottom of the screen
  2. Click the “New” button on the “Edit Variables” window
  3. Process Variable Name(ID), Data Type, Display Name for the Process Variable, and Inputter located in the “Advanced Options” tab menu can be configured.


Table 6‑2 Process Variable Definition Configuration

Process Variable ID (Delimiter which separates each process variable) Data Type(Process Variable Data Type) Process Variable Display Name(Easily recognized by this Display Name) Inputter (Users provide data according to this input control type)
Trouble_desc Text Problem Description TexetAreaInput(Cols : 80, Rows : 5)
Trouble_result Text Resolution TexetAreaInput(Cols : 80, Rows : 5)
Trouble_type Text Problem Type SelectInput(Values / Selections)
- System/Systemic Problem
- Hardware/Hardware Problem
- Req_for_improvements/ Request for improvements

When configuring each process variable, the input control type(Inputter) must be decided. The styles and properties of input control types are followings.


Select control – Option Selector

An option can be selected according to the task.

  1. Click the down arrow on the Select control
  2. Relevant option should be clicked

Properties

  • Selections: The name of the currently selected option displayed on the screen
  • Values: The value of the currently selected option

For instance, users select a trouble type on their screens, they click the down arrow, and select the relevant trouble type for the trouble ticket.


TextArea control

Users can describe troubles in the given TextArea.

Properties

  • Cols, Rows: Limit the size of columns and rows in the TextArea

For instance, when users need to explain their troubles, they can write detailed descriptions in the TextArea.


Figure 6‑24 Select and TextArea Controls
Figure 6‑24 Select and TextArea Controls


Radio Button Control

Radio buttons are very similar to “Select” control, they are mutually exclusive. The only difference between two is the way of displaying options. Radio button provides all the selections at once on the screen, while “Select” control displays available options by clicking the “Select” control. Click an appropriate one among several radio buttons

Properties

  • Selections: The name of the currently selected option displayed on the screen
  • Values: The value of the currently selected option

For instance, users select a trouble type on their screens, they click the relevant trouble type among various radio buttons.


Figure 6‑25 Radio Buttons
Figure 6‑25 Radio Buttons


Activity Declaration / Flow Configuration

So far, we have completed participant definitions and process variable definitions that are essentially declared in order to define a work flow. From now on, we need to define all the actual tasks for each Activity along with a complete flow between them.

The detailed behaviors of each separate task can be defined by using various Activity types selected from the “Activity Type Palette” located on the top of the “Process Designer”.


Previously we defined 4 steps for this ‘Trouble Ticket’ process. The first 3 steps are handled by people that we simply call it as “Human Work” Activity. For the last step, there is no human involved. Its task conducts an email delivery after finishing the third step of the process. Email Activity(local) located in Messaging group can be used for this purpose.


Step 1 – The Step of Trouble Report


The first 3 steps for the “Trouble Ticket” process are 1) Trouble Report, 2) Task Distribution to People in charge, 3) Trouble handling. These 3 tasks are treated as “Human Work”. The followings show how to define the whole process.

① Select the “Human Work” in Document group from Activity Type Palette.

② Double-click the recently added “Human Activity type” in the Flowchart.

The Human Activity Property window with ”HumanActivity” name appears over the “Process Designer”.

  • Configure Name and Description on the first Basic Properties tab menu, Role and Parameters on the second Human Work tab menu for the “Human Work”


The first step of the process is that users report troubles with the name, ‘Trouble Report’. We choose the ‘User’ which we already declared for the role. At this step, the process variables of “Problem Type” and “Problem Description” which are already declared get mapped through the “Parameters” on the second “Human Work” tab menu.


Figure 6‑26 Properties of Trouble Report Configuration
Figure 6‑26 Properties of Trouble Report Configuration



Step 2 – The step of selecting people in charge.


The second step conducts that the manager receives the contents from the previous first step. He/she reads the contents and distributes the tasks to appropriate people who can handle the troubles. Like the first step, simply add another “Human Work” and configure properties that are as follows


Activity Name: Assign a person in charge

Responsible Role: Manager

Parameters:

Variable Direction
Problem Type in
Problem Description in
[Role]Right Person


• If “Direction” for any Process Variable is set with “in” value, users are only able to read the value of the process variable. It means that users can not make changes on corresponding process variables. By default, “in-out” is set, therefore, users are able to read and write something in a provided input control.


In this situation, the Manager is configured by the special person who is already decided and different from either initiator or Right Person. (initiator is automatically mapped with a user who executes the process while Right Person is dynamically selected during conducting tasks.) For this, from the “Role” panel located on the bottom region of the “Process Designer”, the “New Role” window is launched by clicking the “Role” and a Role picker window is popped via the “[ ... ]” button right next to the “Role” field in the “Advanced Options” tab menu. After clicking the “By Role” tab menu, select an appropriate group and role accordingly.

• Role Picker is a tool supported within the “Process Designer”. It provides functionality that allows users to apply rules which help actual people in charge get mapped with roles at any task step of the process.


Figure 6‑27 User Mapping by Role Picker
Figure 6‑27 User Mapping by Role Picker


When the direction of a parameter is set with “in” value, users only can read the contents, but writing is not allowed. The corresponding field is read-only. In conclusion, the manager views entered information by the previous step. The last parameter for “[Role]Right Person” shown the table above is in active at the second step of the process, therefore, the manager is able to select an appropriate person for the task by using the “Role Picker”.


Step 3 – The step of Handling Troubles(Write Resolutions)

This third step of process provides a screen in which the selected person who gets mapped from the second step enters trouble resolutions for the trouble. The properties are as follows.

Activity Name: Handling troubles

Responsible Role: Right Person

Parameters:

Variable Direction
Problem Type in
Problem Description in
Resolution


Step 4 – The step of Handling Troubles(Write Resolutions)

Report the results to the user who opens the trouble ticket (Reply to the user)

At the last step, E-Mail Activity sends a notification email to the user who opened the trouble ticket. The email contains the trouble resolution written by the person in charge at the third step.


Figure 6‑28 Email Configuration Screen
Figure 6‑28 Email Configuration Screen


① Select the “E-Mail(local)” Activity in Messaging group from Activity type palette.

② Double-click the recently added “E-Mail(local)” Activity.

③ Configure Activity Name, Description, Sender Email Address, Recipient, Email Title, and Email Contents.


Table 6‑3 Human Work Property Configuration

Property Configuration Value
Activity Name Report the Result
Sender manager@uengine.org
Recipient User
Email Title This is the requested “Trouble Ticket” result.
Email Contents Hello,
This is the report of handling troubles.
The results after handling the requested trouble are as follows.:
<%=Trouble_result%>
For more additional questions or requests, we will appreciate, if you contact us.


How to Deploy Process Definitions

If there are no red error marks found, the process that we just created is well prepared for “Deployment”. So, we click the “Deploy” button located on the bottom right side of the “Process Designer” screen.


Figure 6‑29 Deployment Screen
Figure 6‑29 Deployment Screen


Figure 6‑30 Resulted Screen after Deployment
Figure 6‑30 Resulted Screen after Deployment
Process Enactment

Throughout the whole steps of the process, we have successfully created the “Trouble Ticket” process. From now on, any system user in our organization takes advantage of uEngine for creating new task processes. In order for end users to start any process created by administrator, the “Initiate” button located on the top of the “Process Definition” page must be pushed after clicking the process under the “Definitions” tree. After clicking any process on the “Process” page, the process flowchart can be displayed. Additionally, by clicking the “Initiate this Process”, the task just gets started.


Figure 6‑31 Starting Task Screen
Figure 6‑31 Starting Task



Figure 6‑32 Starting Task Screen
Figure 6‑32 Starting Task


Task Progress

Along the previous instructions, when the “Initiate this Process” button is clicked, the first task,”(Report Trouble)” of the “Trouble Ticket” process is being loaded. It is also called as a WorkItem handler. The following shows the steps of the process including entering trouble description, clicking the “Complete” button, and starting the process.


Figure 6‑33 Trouble Report Screen
Figure 6‑33 Trouble Report


At the next step of the process, managers distribute the tasks to appropriate people who can handle the troubles. Therefore, only authorized managers must be logged on to do so. However, this process is set to the same user for convenience. The inbox, “WorkList”, is the place where users receive assigned works to do. As a result, users are able to check what tasks are assigned so far. If any necessary work related to task assignment, appropriate people who can understand the progress for a given task must be selected for the task role after reading the contents requested by initial users. For an easier approach for this matter, we simply select the “Tester”. Otherwise, we keep logging out and logging in to keep continuing the process. Finally, the “Complete” button must be clicked for the task completion.


Figure 6‑34 The Screen of Assigning a right person
Figure 6‑34 Assigning a right person


The responsible user for this new step is the same user selected from the previous step. Without re-logging in, as a trouble handler, the trouble result or resolution must be entered and completes the task.


Figure 6‑35 Writing the Resolution
Figure 6‑35 Writing the Resolution


So far, all the human related works are completed. For the last task, an automatic email with the result of the task will be delivered to the user who opened the trouble ticket, so recipient email address must be checked for the successful email delivery.


Figure 6‑36 Email Result Notification
Figure 6‑36 Email Result Notification


If the recipient email address in organization chart is missing, we are not able to make sure that the email is successfully delivered, so, a test email address is needed and used for testing this “Trouble Ticket” process.

Processes using Forms
Trouble Ticket Implementation via Forms


In general, process task format styles are either web or general documents like Microsoft Office files. However, uEngine provides a form editor in which users create any task document forms by themselves comfortably. At this time, let us create a process by using the given form editor. From the “4. Basic Example Process”, we reconstruct the form based “Trouble Ticket” Process. First of all, users need to create desired forms and register the created forms as a “Process Variable” which is used in “FormActivity”.


The following [Figure 6-37] shows the process that we reconstruct.


Figure 6‑37  Form based Trouble-Ticket Process
Figure 6‑37 Form based Trouble-Ticket Process


Form Creation

For creating forms, we need to right-click on a preferred folder of the “Definitions” tree. A popup menu appears on the focused folder, select the “New” menu, and an extended cascading menu appears, and select the “Form” from the sub menu. As a result, the form editor is automatically executed. The form editor helps users either construct useful forms by drag and drop supported various controls onto the workspace below or write scripts directly onto the workspace in source mode. (For more detailed usage of writing scripts, see in the chapter 23)

Form Editor like [Figure 6-38] requires an “Alias”, so a unique form alias must be entered. After completing form design, the “Save Page” button needs to be clicked.


Figure 6‑38  Form Editor
Figure 6‑38 Form Editor


Trouble Description

This form receives trouble descriptions by users. In Figure [6-39] , necessary controls are placed in the form, and the controls are defined like the [Table 6-4] below. Assign “TroubleTicketForm”to the Alias of this "Trouble Ticket Form".


Table 6‑4 Trouble Description Form

Control Name Variable Name
Calendar Control(Receipt Date) receiptdate
Calendar Control(Due Date) duedate
Input Field(Department) part
Input Field(Name) name
Input TextArea(Trouble Description) difficulty(Columns: 80, Rows : 5)


Figure 6-39 Trouble Ticket Form
Figure 6-39 Trouble Ticket Form


People in Charge for the task


This form helps users select people in charge for the task. The ways to configure the form are the same way that the “Trouble Description” form has. Assign “RoleAssignmentForm” to this form’s alias.

Table 6‑5 The form of Selecting people in charge

Control Name Variable Name
Calendar Control(Receipt Date) receiptdate
Calendar Control(Due Date) duedate
Input Field(Receipt Department) part
Input Field(Name) name
Input TextArea(Trouble Description) difficulty(Columns: 80, Rows : 5)
Control of selecting People in charge rightperson


Figure 6-40 Role Assignment Form
Figure 6-40 Role Assignment Form


Trouble Ticket Resolution

From “4. Basic Example Process”, this form is related to the third step, “Role Assignment”(Assign people in charge). Receipt Date, Receipt Department, Trouble Description get mapped with the values of the form. More detailed value mappings will be brought up in the process configuration part. For this form, we give an alias name with "TroubleResolutionForm".


Table 6-6 Trouble Ticket Resolution Form

Control Name Variable Name
Calendar Control(Receipt Date) receiptdate
Calendar Control(Complete Date) duedate
Input Field(Receipt Department) part
Input Field(Name of Person in charge) rightperson
Input TextArea(Trouble Description) difficulty(Columns: 80, Rows : 5)
Input TextArea(Trouble Resolution) result(Columns: 80, Rows : 5)


Figure 6-41 Trouble Ticket Resolution Form
Figure 6-41 Trouble Ticket Resolution Form


After completing forms, the forms must be set into production by clicking the “Set As Production”. Therefore, users are able to make use of the forms, otherwise, the forms will not be displayed on the selection list of creating process variable.


Participant Definition

Participants can be configured with the same way that “4. Basic Example Process” did. Especially Manager gets mapped with any user(ex, “tester”) via “Role Picker”.

Table 6-7 Role Assignment

Participant ID Participant Name(For display)
Initiator Initiator
Manager Manager
rightperson Right Person


Process Variable Definition

Corresponding process variables must be registered in order for users to utilize useful forms created previously.


Table 6-8 Process Variable Registration

Process Variable Form Process Variable Name(for display)
TroubleTicketForm Trouble Ticket Form Trouble Ticket Form
TroubleResolutionForm Trouble Resolution Form Trouble Resolution Form
RoleAssignmenForm Role Assignment Form Role Assignment Form

In [Figure 6-42], select the related form and click the “Update” button. All necessary process variables are configured in the same way as below.


Figure 6-42 Registering Forms as Process Variables
Figure 6-42 Registering Forms as Process Variables


Activity Declaration / Flow Configuration

For utilizing Form based process configuration, “FormActivity” is useful. Add a “FormActivity” into the flowchart from the “Document” group from the Activity Type palette located in the top of the “Process Designer”. Activity Name, Roles, Form Process Variable must be configured.

  • Opening Trouble Ticket

Like [Figure 6-43], the elements of the “Trouble Ticket” Form must be mapped with Process Variables in order to make use of the form efficiently. In addition, Activity Name and Roles shown in Table 6-9 are configured accordingly.

Table 6-9 Activity Configuration

Activity Name Opening Trouble Ticket
Responsible Role Initiator
Form Process Variable Trouble Ticket Form


Figure 6-43 Trouble Ticket Description
Figure 6-43 Trouble Ticket Description


  • Trouble Ticket Receipt

At this step, managers select people in charge of resolving troubles by the manager after receving trouble tickets. Necessary Activitiy configuration is the same as previous step, ‘opening trouble ticket’. However, all necessary elements of this ‘Role Assignment Form’ need to get mapped with the elements of the previous form, ‘Trouble Ticket Form’. It is also known as Data Mapping.

The ways to conduct mapping between these 2 froms that include “Trouble Ticket Form” and “Role Assignment Form” are simply explained. The right hand side of the FormAcitivity receives the values of elements which link with relevant elements from the left hand side. The values of Receipt Date, Department, and Trouble Description for the “Role Assignment Form” are automatically shared by the “Trouble Ticket Form”. For the person in charge, the ‘rightperson’ process variable must be mapped with rightperson in the “Role Assignment Form”


Table 6 10 Activity Configuration

Activity Name Trouble Ticket Receipt
Responsible Role Manager
Form Process Variable Role Assignment Form


Figure 6-44 Trouble Ticket Receipt
Figure 6-44 Trouble Ticket Receipt


  • Solving Trouble Ticket

This step conducts that the person in charge resolves the requested trouble. The values of Receipt Date, Department, and Trouble Description for the “Role Assignment Form” are automatically shared by the “Trouble Ticket Form”.


Table 6-11 Activity Configuration

Activity Name Solving Trouble Ticket
Responsible Role Right Person
Form Process Variable Trouble Resolution Form


Figure 6-45 Solving Trouble Ticket
Figure 6-45 Solving Trouble Ticket


  • Closing Trouble Ticket

After solving troubles by people in charge, managers need to view the result. It displays the contents resulted from the third form, “Trouble Resolution Form”. Therefore, there is no additional form required. Only related process variables need to be created.

Table 6-12 Activity Configuration

Activity Name Closing Trouble Ticket
Responsible Role Manager
Form Process Variable Trouble Resolution Form


Figure 6-46 Closing Trouble Ticket
Figure 6-46 Closing Trouble Ticket


  • Solved Trouble Ticket Confirmation

This step allows the Initiator to view the result of the trouble ticket. At this step, we only need to configure only related process variables connected with the third form, "Trouble Resolution Form".


Table 6-13 Activity Configuration

Activity Name Solved Trouble Ticket Confirmation
Responsible Role Initiator
Form Process Variable Trouble Resolution Form


Figure 6-47 Solved Trouble Ticket Confirmation
Figure 6-47 Solved Trouble Ticket Confirmation


  1. Implementation of Multiple Value Edition

The functionality of multiple value edition is like an online invoice which contains many items listed and provides an automatic line addition for users when an additional item needs to be entered to the system.

With a simple HTML manipulation, the implementation is simply made. Moreover, the values of added rows do not need to get mapped so as to transfer them to a different form. Like [Figure 6-48] the “AddRow” control button can be placed in the “Trouble Description” field of the “Trouble Ticket Form”. As a result, users are able to take advantage of its edition functionality for multiple values.


Multiple value entry


Figure 6-48  AddRow control addition into Trouble Ticket Form
Figure 6-48 AddRow control addition into Trouble Ticket Form


Transfer Multiple Values


In order to transfer the values of added rows which are automatically created, the parts that you want to transfer needs to be surrounded by <input:foreach variablename=”the control name”> and </input:foreach>. It is similar to HTML tags which come in pairs, an open and a close tag. The following [Figure 6-49] easily explains that the “TextArea” html tag is surrounded with “foreach” tags. In addition, if the inside of the “foreach” is composed with input, TextArea, or other controls, only one among many control fields needs the value of variablename within the “foreach” script. The values of all other fields will be transferred automatically.


Figure 6-49 Ways to Transfer Multiple Values
Figure 6-49 Ways to Transfer Multiple Values


The configuration of this functionality is the same as a single mapping that one representing variable gets mapped, and the values of multiple rows will be transferred automatically.

The following [Figure 6-50] and [Figure 6-51] explain that in the Ticket Description field, users add one row and complete the form. At “Trouble Ticket Receipt”, we will learn that all the multiple values are automatically transferred.


Figure 6-50 addRow Usage



Figure 6-51 addRow Usage


Processes between Process Participants - Workflow

Flow Control for Conditional Branches

At this chapter, let us practice an extended version of “Trouble Ticket Process” which has conditional branches that have different task flows based on their trouble type. Our expecting process looks similar to the following figure [Figure 7-1] shown below.


Figure 7-1 Our Expecting Process with Conditional Branches
Figure 7-1 Our Expecting Process with Conditional Branches


The figure [Figure 7-1] shows that if a trouble type is either “S/W” or “H/W”, it will perform the following tasks that we practiced earlier. For “Request for improvement”, it skips the tasks and performs the last task of the process.


Define Execution Block for Conditional Branches

For building conditional branches, we take advantage of “SwitchActivity” in the “Flow Control” located under the second “Control” tab menu of the “Process Designer”.


Figure 7-2 Process with Conditional Branches
Figure 7-2 Process with Conditional Branches


For creating conditional branches, the related icon, “SwitchActivity” must be clicked and drag & drop it into an appropriate location where it is executed in the flowchart. Configure corresponding conditions. Subsequently, necessary activities are also defined accordingly as so to execute conditional branches. First of all, like the [Figure 7-3], drag and drop the corresponding activities into the conditional branch block.


Figure 7-3 Define the first Execution Block
Figure 7-3 Define the first Execution Block


Let us define another execution block for the second condition. First of all, click the “SkipActivity” from the “Activity Type Palette”, and it will be placed in the execution block by drag and drop.


Figure 7-4 Empty Task, “Skip Activity” Creation
Figure 7-4 Empty Task, “Skip Activity” Creation


In order to place the empty task Activity, “SkipActivity” into the second execution block, like [Figure 7-5] drag the “SkipActivity” and drop it onto the “SwitchActivity” icon(파일:Switch_icon.jpg‎).


Figure 7-5 Define the second Execution Block
Figure 7-5 Define the second Execution Block


After locating all the acitivities into desired places, click the label of execution block(default is condition0), and configure the same way as follows.

  • The first execution label : S/W or H/W
  • The second execution label : Request for Improvement


Figure 7-6 Define Conditional Branch Labels
Figure 7-6 Define Conditional Branch Labels


Eventually, we complete building basic execution blocks for the process with conditional branches.


Configure Conditions of Conditional Branches


Form now on, we need to make conditional branches executable when data is submitted via completed forms by users. The first activity, “Opening Trouble Ticket” receives values. Finally, we are able to configure conditional branches with them. After clicking the “Problem Type” process variable found on the bottom of the “Process Designer”, there are 3 configured choices that can be displayed while opening a trouble ticket.

ValueType
SoftwareSystemic Problem
HardwareHardware Problem
Req_for_improvementsRequest for Improvements


For System or Hardware problem type, it executes the first upper conditional branch, otherwise the second conditional branch is executed for the case with “Request for Improvements”. In the conditional branch property window, make sure that the first label is displayed on the first corresponding “Case” row. Open another property window by clicking on the “Conditional1” cell located in the first row, and configure properties accordingly.


Figure 7-7 Configuration of Conditional Branches
Figure 7-7 Configuration of Conditional Branches


Let us configure conditions for either SW or HW. Like the figure, [Figure 7-8] shown below, while keeping the property window open, select the process variable, “Problem Type”, and click on the “Direct Value” radion button, and select the “Text” data type, and finally enter the value with “Software” in the displayed input box. The first two conditions execute the same branch block, so another condition for “Hardware” must be added in the same way as we did for “Software” earlier. As a result, they become an OR condition, and the OR condition requires that any of these conditions must be met for the first block execution.


Figure 7-8 Configure one(Otherwise) of Conditional Branches
Figure 7-8 Configure one(Otherwise) of Conditional Branches


At last, we select the “Otherwise” for the last “Request for Improvement” condition. If a condition does not belong to either“Software” or “Hardward”, it will follow the second execution block.


Let us take a practical test after deploying all the details that we discussed.


Figure 7-9 Conditional Branch Execution Result (if system has a problem)


Figure 7-9 Conditional Branch Execution Result (if system has a problem)
Figure 7-9 Conditional Branch Execution Result (if system has a problem)


With the execution result above, it shows that the process moves to the first conditional block. At this time, we will practice executing the second conditional block resulted from other cases that do not belong to either “Software” or “Hardware”, therefore it requests for improvements.


Figure 7-10 Conditional Branch Execution Result (If a problem is requsting for improvements)


Figure 7-10 Conditional Branch Execution Result (If a problem is requsting for improvements)
Figure 7-10 Conditional Branch Execution Result (If a problem is requsting for improvements)


If a problem type is the case of “Request for Improvements”, it executes the second conditional branch that includes the empty and the last task, and it finishes the whole process. The conditional branch has the core functionality that helps users to implement decision making in business processes, therefore users need to practice for making good use of the functionality more comfortably.

Flow Control for Conditional Branches

Loop (Request for improvements)

At this chapter, if a problem type is neither “Software” nor “Hardware”, it conducts the second condition, “Request for Improvements”, so a user requests a proposal, and the code block of requested proposal keeps repeating until the proposal is approved by the manager. Throughout this task, we are able to learn this “Loop Control flow”.


Figure 7-11 Final Process Screen
Figure 7-11 Final Process Screen


Before moving onto the details for the second case, “Request for Improvements”, we need to remove the empty task, “SkipActivitiy” that we created earlier, and create necessary activities based on the following table. From the “Flow Control” menu, we need to add a “Loop Activity”, and then 2 human work Activities can be placed in the “Loop Activity”. It is very simple as it is, so we will skip the steps of flowchart creation. Additional process variables along with their configurations are as follows.


- Process Variable Definition

Process Variable ID Process Variable for Display Process Variable ID Process Variable for Display
ProposalProposal TextTextAreaInput(Cols : 80 , Rows : 5)
IsApprovedIs Approved? Yes or No


- Activity Definition

Activity Role Parameters
ProposalRight Person(Tester) Proposal
ApprovalManager Proposal (in), IsApproved

For the “Proposal Activity”, the right person is not defined yet. Therefore, by using “Role Picker”, role must be mapped with a specific person(direct-mapping).

- Loop Flow Activity Definition

Conditional Process Variable Condition Value
IsApproved== No (Direct Value)


Figure 7-12 Loop Condition Configuration
Figure 7-12 Loop Condition Configuration


After completing the process like the figure above, click the “Deploy” button, and initiate this process via Web browser. At the step of approving the proposal, click “no” for the “Is Approved?” field, and the task block keeps repeating after “no” is clicked.


Figure 7-13 Loop Screen
Figure 7-13 Loop Screen
Sub Processes

Sub Process Definition(Request for Improvements)

Users can request proposals for the functional improvements of their trouble tickets. There are two ways resolving this request. Like [Figure A], related activities can be easily placed in the second conditional block. Otherwise, a sub process can be useful for this situation. Like [Figure B], additional processes can be separate from the current process, and complete the whole process.


Figure A
Figure A


Figure B
Figure B


The followings are several advantages if we use sub processes.

  1. Sub Process can be used in various main processes if needed(Recyclability).
  2. Large and complex processes can be broken down into smaller sub processes, and it can be structured. Moreover, users can understand complex processes much easily (Better Understanding).

First of all, let us create a sub process for the second conditional case, “Request for Improvements”, which is used in an example.


Figure 7-14 Proposal Process for Functionality Improvement
Figure 7-14 Proposal Process for Functionality Improvement


Locate a “Loop Activity” obtained from the “Control Flow” into flowchart, and then add two “Human Activities” into the “Loop Activity. It is very simple, so the configuration for the flowchart can be skipped. Participants and Process Variable definitions of the sub process will be coveniently created like the following tables.


- Participant Definition

Participant ID Participant for Display
DrafterDrafter
ManagerManager


- Process Variable Definition

Process Variable ID Process Variable for Display Data Type Inputter
ProposalProposal TextTextAreaInput(Cols : 80 , Rows : 5)
IsApprovedIs Approved? Yes or No


- Activity Definition

Activity Role Parameters
ProposalDrafter Proposal
ApprovalManager Proposal (in), IsApproved


- Loop Control Flow Activity Definition

Conditional Process Variable Condition Value
IsApproved== No (Direct Value)


After configuring all the definitions above, the deployment is property executed by clicking the“Deploy” button. Subsequently, the corresponding version is published into production. Otherwise, the process execution is not working as we wish.


Sub Process Configuration


From the “Activity Palette”, Click the “Control” tab menu, and select the “Sub Process Activity”, finally drag and drop the “Sub Process Activity” into the second branch block, and remove the empty activity, “Skip Activity”.


Figure 7-15 Sub Process Definition
Figure 7-15 Sub Process Definition


  • Sub Process Basic Property Configuration

At this part, we will configure the properties of the sub process. After clicking on the “Sub Process Activity”, the property configuration window appears. By clicking on the second tab menu, we can select a sub process from the process definition list that we have created so far.


Figure 7-16 Sub Process Selection
Figure 7-16 Sub Process Selection


VersionSelectOption Configuration'

VersionSelectOption selects a process version which is being used for the process.

  • Use the CURRENT production version : the current production version will be used
  • Use the production version AT THE INITIATED TIME : The initial version of the process will be used.
  • Use the production version AT THE DESIGNED TIME : The version that the corresponding process defintions are designed will be used.
  • Use the version JUST SELECTED : The selected version will be used.

At this time, we had better select the “Use the Current production version” for a better maintenance.


Process Variable and Participant Recognition between Sub Process and Main Process

Process variable and participants defined within the sub process must be recognized by the main process, therefore, process variable mappings are required as figure[Figure 7-17] shown below. For the “RunAndForget” field located on the bottom part of the popup window, it asks whether the main process waits for the sub process until the sub process completes its work. Otherwise, the main process does not wait for the sub process, and keep moving forward to next task.


Figure 7-17 Sub Process Property Configuration
Figure 7-17 Sub Process Property Configuration


After completing sub process configurations, another deployment is required. We will learn that both the main process, “Extended Trouble Ticket Process” and the sub process, “SubProposalProcess” will be executed accordingly after selecting the third problem type, “Request for Improvements” at the first task, "Opening Trouble Ticket".


Figure 7-18 Execution Results of Main Process and Sub Process


Figure 7-18 Execution Results of Main Process and Sub Process
Figure 7-18 Execution Results of Main Process and Sub Process

Processes between Systems - EAI

Database Connection

Hypersonic DB Configuration

At this chapter, we take advantage of “SQL Acitivity” that helps users record trouble ticket results resolved by technicians, “Person in Charge”. It can be useful as a FAQ that similar troubles are occurred by other users and the same trouble can be solved immediately by using the FAQ database. For the purpose of trouble ticket accumulation, a connection between uEngine and database is required. By using SQL statements, data can be stored and retrieved from the database consequently. Let us practice this by using the uEngine’s default database, “HyperSonic DB. For Hypersonic DB management, doubleclick the “runHSQLManager.bat” located under the directory, “/hsqldb/demo/” after running the “runHSQLServer.bat” executable file. The following figure[Figure 8-1] which is called a “Hypersonic client program” can be shown after performing the instructions above.


Figure 8-1 Hypersonic Database Execution Screen
Figure 8-1 Hypersonic Database Execution Screen


Select the “HSQL Database Engine In-Memory” of “Type” field, click the “OK” button on the bottom of popup window. Eventually, the list of database tables will be displayed. Create a database table with a “TroubleTicket” name. The following table is the script for the table creation.

Field Name Data Type
RegnoINTEGER
ProblemType VARCHAR
ProblemDescriptionVARCHAR
ResolutionVARCHAR

Let us get back to uEngine, and we utilize the “SQL Activity”.


SQL Activity

"SQL Activity" can be found in the “Connect” tab menu of “Activity Palette” in Process Designer. By drag and drop, the activity can be placed in the last task of the whole process like the figure[Figure8-2] below. We could change the name of the Activity into “Save to Database” for convenience.


Figure 8-2 Process Creation of Database Connection
Figure 8-2 Process Creation of Database Connection


In the property of the Activity, the following SQL statement can be written and transmits it to the database.

insert into TroubleTicket (Regno, ProblemType, ProblemDescription) values (<%=Instance.InstanceId%>, ? , ? )

Copy the SQL statement above and paste it into Sqlstmt text area. Necessary table columns are mapped with variables like the figure[Figure 8-3].


Figure 8-3 Database Variable Configuration
Figure 8-3 Database Variable Configuration


After applying recent changes of the process with deployment, we learn that problem types and problem descriptions are stored into the "TroubleTicket" table in the Hypersonic DB.


Figure 8-4 SQL Execution Result
Figure 8-4 SQL Execution Result


Practical Use of URL Form

Web Application Activity

The core functionality of Web Application Activity has Web Application Recyclability which is very useful during WorkItem handler development. Users are able to embed the functionality easily. More importantly, its functionality helps users synchoronize the handling of workItem completion and result recongnition. uEngine provides an interface for processing tasks, but, in order to apply created business processes to users’ organizations, the connection of current complete web sites is necessary in most cases. In this case, with the support of “Web Application Activity”, invoke necessary web pages and handle related results obtained by the use of Web browser URLs.

For practical use of the functionality, we now make a simple version of exisiting “Trouble Ticket” process. We require two URL Linked App Activities including both “Opening Trouble Ticket” and “Solving Trouble Ticket”. They are both connected to an external JSP program.


Figure 8-5 Completed Example
Figure 8-5 Completed Example


The following web files are required for the connection between these web pages and the example. (Installed under the \was\webapps\uengine-web\sample_url_applications\troubleticket).

File Name Description
Register_index.jsp Write a trouble report
Register_submit.jspThe resulted description is stored into the DB
View.jspDisplay the status of tasks in progress


Figure 8-6 register_index.jsp Execution Screen
Figure 8-6 register_index.jsp Execution Screen


Add a “Script Activity” located in the “Control” group under the “Control” tab menu into the flowchart. Configure participants and process variables in the same way as follows.

Participant ID Participant for Display Property
UserUser


Process Variable Process Variable for Display Property
RegnoRegno Text
ResultURLResultURL Text

Process Variable, “Regno” contains a unique ID value that distinguishes among different trouble tickets requested by users. Additionally, “ResultURL” is another process variable keeping the address values of URLs resulted on browsers.


Report Trouble, URL Activity

Open the Web Application property window, and check the values.


Figure 8-7 Properties of Web Application
Figure 8-7 Properties of Web Application


Item Value
URL web page address which is being invoked
URLWhenSuccess A bridge web page so as to move to the next activity (If the configured page is displayed, it is considered that the task is successfully completed.)
ResultURLPV A process variable keeps the value of URL when the activity completes.

When the activity, “Opening Trouble Ticket” is executed, problem types and descriptions are obtained on the “register_index.jsp”. After then, the results are transferred to the database. The final page, “view.jsp” is displayed if the activity is successfully completed.

Item Value
URL /uengine-web/sample_url_applications/troubleticket /

register_index.jsp

URLWhenSuccess view.jsp
ResultURLPV ResultURL

Select “Initiator” for the role, and apply the changes.


Parsing for the results via Script Activity(Parsing)


At this time, let us practice how to use Script Acitivity which is essential functionality for “Form Control”. The process variable, “ResultURL” contains the URL address resulted when the previous activity completes. A trouble ticket is stored into the database, the unique Regno value is included to URL, so the process requires parsing at the next page. Therefore, Regno can be referenced everywhere. From “register_submit.jsp”, we need to obtain the “Regno” value, and the following script is the parsing needed for the purpose.


Figure 8-8 Script
Figure 8-8 Script


Script
var resultURL = instance.get("ResultURL");
var key = "regno";
var regno = resultURL.substring(resultURL.indexOf(key)+key.length+1);
return regno


The script gets the value cut right after “regno=” of the string. At last, the property of basic information display should be “Yes” and both “Apply” and “Deploy” buttons should be clicked for applying recent changes.

  • Writing resolution’URL : Process Start Screen after application implemented.


  • Process values after completing the first task


Figure 8-9 Execution Result


By the process variable page, we are able to learn that the process variable,“Regno” is obtained from the “ResultUrl” after parsing.

Other Types of Processes

Role Processes

BRE(Business Rule Engine) is a system that takes business requirements in a fast and correct way, because business rules are separate from applications. This separation also helps users manage and define business rules more efficiently. At this time, the goal is creating a process that helps users make decisions automatically based on the decision tables. For a better understanding of this point, a process follows rules which simply can be explained with a situation where people follow the rules and laws of the organization after joining to an organization. At this chapeter, we will practice with an insurance task that conducts pricing the insurance coverage based on the subscriber’s conditions. The resulted information including the insurance coverage can be stored into database, or after getting approval by the person in charge, the information finally transfer to the database and the information saved into database. The process we need to struct is the following.


Policy Pricing Decision Process

Figure 9-1 Policy Pricing Decision Process
Figure 9-1 Policy Pricing Decision Process


Figure 9-2 Policy Pricing of an insurance company
Figure 9-2 Policy Pricing of an insurance company


1-1. Policy Princing Decision Process(Rule Engine)’s Structure The figure [Figure 9-3] is an essential decision table that helps users calculate the amount of basic insurance coverage. With this, we are able to construct the basic decision process.


Figure 9-3 Policy Pricing Decision Table
Figure 9-3 Policy Pricing Decision Table


Decision Process‘s Process Variable Configuration

Configure in the same way as the following table shows.


Table 9-1 Process Variables

Process Variable ID Process Variable for Display Data Type Default Value
age age Number -
BasePrice BasePrice Number -
LocationRiskProfile LocationRiskProfile Text -
PriorClaims PriorClaims Number -
Type Type Text -


Activity Configuration

Add an “AssignActivity” into the [Conditional Branches], “Switch Activity”, and configure conditions and values along with scripts for each conditional branch.

Figure 9-4 Decision Process


Figure 9-4 Decision Process
Figure 9-4 Decision Process

Enter the value of the process variable, [BasePrice] after clicking the “AssignActivity”

ex) AssignValue: 800
Variable: BasePrice

With the following table, configure the conditions of the “SwitchActivity”.


Table 9-2 Configuration of the Conditional Branches

No Case Condition1 Condition2 Condition3 Condition4 Condition5
1 450AUD case age>=18 age<=24 LocationRiskProfile == LOW PriorClaims==1 Type == COMPREHENSIVE
2 200AUD case age>=18 age<=24 LocationRiskProfile == MED Type == FIRE_THEFT
3 300AUD case age>=18 age<=24 LocationRiskProfile == MED PriorClaims==0 Type == COMPREHENSIVE
4 300AUD case age>=25 age<=30 PriorClaims==1 Type == COMPREHENSIV
5 150AUD case age>=18 age<=24 LocationRiskProfile == LOW Type == FIRE_THEFT
6 150AUD case age>=18 age<=24 LocationRiskProfile == LOW PriorClaims==0 Type == COMPREHENSIVE
7 700AUD case age>=18 age<=24 LocationRiskProfile == MED PriorClaims==1 Type == COMPREHENSIVE
8 700AUD case age>=18 age<=24 LocationRiskProfile == HIGH PriorClaims==0 Type == COMPREHENSIVE
9 550AUD case age>=18 age<=24 LocationRiskProfile == HIGH Type == FIRE_THEFT
10 120AUD case age>=25 age<=30 PriorClaims==0 Type == COMPREHENSIVE
11 590AUD case age>=25 age<=30 PriorClaims==2 Type == COMPREHENSIVE
12 800AUD case age>=25 age<=35 PriorClaims==3 Type == THIRD_PARTY
13 Otherwise

Like [Figure 9-5], check “No” for the “InitiateFirstWorkItem” field, and click the “Deploy”.


Figure 9-5 Information of the Process Definition
Figure 9-5 Information of the Process Definition


1-2 Policy Pricing Configuration of an insurance company

Configure activities like the figure , [Figure 9-6] shown below.


Figure 9-6 Policy Pricing of an insurance company
Figure 9-6 Policy Pricing of an insurance company


Configuration of Process Participants and Process Variables

For process participants, add [User] and [Mananger]. The [Manager] gets mapped with [Members in the group with id 1] with the support of Role Picker”. The process variables are as follows.


Figure 9-7 Participants and Variables
Figure 9-7 Participants and Variables


Figure 9-8 Participant Addition
Figure 9-8 Participant Addition


Activity Configuration


  • Input Profile Information

The figure, [Figure 9-1] shows that the participant and parameters are configured with “User”, “age”,”LocationRiskProfile”, “PriorClaims” relatively.


Figure 9-9 Input Profile Information
Figure 9-9 Input Profile Information


  • Fire Rule

The process, “Policy Pricing Decision Process” we made ealier is added into this “Insurance” process as a sub process. Therefore, related process variables are required to get mapped with each other. The direction of the process variable, “BasePrice” should be “out”.


Figure 9-10 Fire Rule
Figure 9-10 Fire Rule


  • Select Insurance Type

For participant, select “User” and “Type” and “BaseType” process variables are added into the third task, “Select Insurance Type”.


Figure 9-11 Select insurance Type
Figure 9-11 Select insurance Type


  • Fire Rule

It should be the same as the first “Fire Rule” above. Simply copy the first one, and paste into the flowchart.


  • Conditional Branches

The label of the first condition for the Conditional Branches is “Case1: Price is greater than $300”. The second one is “Case2: Price is less than $300 or equal to $300. Configure the same way as the figure shows below.


9-12 Conditional Branches
Figure 9-12 Conditional Branches


No Case Condition1
1 Case1:Price is greater than $300 or equal to $300 BasePrice >= 300
2 Case2:Price is less than $300 Otherwise

Table 9-3 Conditional Branches


  • Confirm by Manager

The participant, "Manager" is responsible for this task, all process variables are required to be added through the [Parameters] field. The direction of all the process variables must be “in”.


Figure 9-13 Confirm by Manager
Figure 9-13 Confirm by Manager


1-3. Process Execution

Initiate the completed process, “Insurance Process”. Enter “30”, “LOW”, “1” for the process variables, “age”, “LocationRiskProfile”, “PriorClaims” respectively. After that click the “Complete” button.


Figure 9-14 Process Execution
Figure 9-14 Process Execution Result


Enter “COMPREHENSIVE" for the “Type” field, and click the “Complete” button.


Figure 9-15 Process Execution
Figure 9-15 Process Execution Result


Figure 9-16 Process Execution
Figure 9-16 Process Execution Result


The figure above, [Figure9-16] shows that if the “[BasePrice]” based on the rules is greater than $300 or equal to $300, the manager confirms the result, and approves the case by clicking the “Complete” button. The process is finally completed. On Instance List page, the following figure[figure 9-17] is found if we search excuted processes with a criteria which the [BasePrice] is $450 for instance.

Figure 9-17 Process Execution
Figure 9-17 Process Execution Result
Page Flow Processes

Page flow is an action that the same person receives tasks in a row and completes the tasks respectively when a process is in progress. In general, a new task is assigned, the assigned works can be found by clicking another tab menu. However, it looks like a current web page turns to another web page smoothly. Therefore, the second task page shows up on the screen, and enables users to complete tasks more efficiently. Let us take a practice with a following “Cellphone Process”. As a result, we will be able to understand the Page Flow Process in a better way.


2.1 Structure of Cell Phone Subscription Process

We struct the cellphone process in the same way as figure[Figure 9-18] shown below.


Figure 9-18 Cellphone Process
Figure 9-18 Cellphone Process


2.2. Configuration of Process Variables and Participants

Participants: [Initiator], [Approver] - [Approver]: Mapped with [Members in the group with id 1] by Role Picker.

Process Variable Configuration [AgeofSubscriber]: Date Type [EstimatedFee], [ExistingPhoneNumberCnt]: Number Type [IsDMB], [IsApproved], [IsUnpaid]: Yes or No Other Process Variable: Text Type [ActualUser]: Text, select the radio button type for Inputter. For “Values” and “Selections”, enter “For him/herself”, “For Other Person”, and “For Underage Person”.


Figure 9-19 Participant and Process Variable Configuration
Figure 9-19 Participant and Process Variable Configuration


Figure 9-20 Actual User Configuration
Figure 9-20 Actual User Configuration


2.3. Activity Configuration


1. Subscription Information Entry

Roles: Add “Initiator”, for parameters, add “CustomerName”, “AgeOfSubscriber”, “aid”, “CustomerType”, “WishingNumber”, “RealCustomer”, “ TerminalModel”, and “IsUnpaid”.


Figure 9-21 Subscription Information Entry
Figure 9-21 Subscription Information Entry


2. Conditional Branches(1)

For the first conditional branch, we configure 2 condtions that are “Case1: Not Perfect Credit Customers who have ever Unpaid Bills”, “Case2: Excellent Credit Customers always Pay Bills on time”. The following figure shows the configuration.


Figure 9-22 Conditional Branches(1)
Figure 9-22 Conditional Branches(1)


No Case Condition1
1 Not Perfect Credit Customers who have ever Unpaid Bills IsUnpaid == Yes(Yes or No)
2 Excellent Credit Customers always Pay Bills on time Otherwise

Table 9-4 Conditions of Condtional Branch(1)

3. Report for Approval For the role of this task, assign “Initiator”, and Enter “This customer is not qualified to subscribe because of [<%=UnpaidResult%>].
Click "Complete" to escalate for this matter.
” for the task instruction.


Figure 9-23 Approval Report
Figure 9-23 Approval Report


4. Approval

For this task, “Approver” is assigned as a person in charge. For parameters, add “CustomerName”, “AgeOfSubscriber”, “ActualUser”, and “TerminalModel”. Configure the “Direction” with “in”, for the “UnpaidResult”, “IsApproved”, Direction should be set with “in-out”.


Figure 9-24 Approval
Figure 9-24 Approval


5. Conditional Branches(2)

For conditions of this conditional branch, configure with “Case1: Approved”, “Case2: Rejected.


Figure 9-25 Conditional Branches(2)
Figure 9-25 Conditional Branches(2)


No Case Condition1
1 Approved Rejected
2 Approve == Yes(Yes or No) Otherwise

Table 9-5 Conditions of Conditional Branches(2)


6. ApprovalRejected(MessengerActivity)

Select the “Initiator” for Recipient, Because customer "<%=CustomerName%>" has an issue related to <%=UnPaidResult%>, so notify this to the customer.” in the “Contents” field.


Figure 9-26 Approval Failure Notification
Figure 9-26 Approval Failure Notification


7. Conditional Branches(3)

For conditions of this third conditional branch, configure with “Case1: For Other Person”, “Case2: For Underage Person”, and “Case3: For him/herself.


Figure 9-27 Conditional Branches(3)
Figure 9-27 Conditional Branches(3)


No Case Condition1
1 For Other Perseon ActualUser == For Other Person
2 For Underage Person ActualUser == For Underage Person
3 For him/herself Otherwise

8. For both Actual User Information Entry, Guardian’s Information Entry, participant should be the Initiator, and no parameters required. We assume that there are necessary forms needed, but we skip the details for this time.


9. Loop Configuration Configure “existingPhoneNumberCnt >= 1” on the “Condition1” cell.


Figure 9-28 Loop Activity Configuration
Figure 9-28 Loop Activity Configuration


10. Phone Number Selection(Whether the desired phone number for subscriber is already taken by somebody else). By using “SQLAcitivity”, we select the direct setting for ConnectionFactory. Configure in the same way as the figure shows below.


Figure 9-29 Check Duplicate Phone Number
Figure 9-29 Check Duplicate Phone Number


UserID sa
DriveClass org.hsqldb.jdbcDriver
ConnectionString jdbc:hsqldb:hsql://localhost:1701
SQL Statement select count(*) as existingPhoneNumberCnt from mobileAccount where phoneNumber = ?

Table 9-6 Check Duplicate Phone Number


11. Change Message(Script Activity)

Enter this javascript message, “instance.set("errMsg", "This phone number is already used by another subscriber. Please choose another number");” on the property window of the “Script Activity”.


12. Subscription Registration(DB Mapping Activity)

Enter a tablename with “mobileaccount”, process variables, CustomerName and WishingNumber should be mapped with SUBSCRIBER, PHONENUMBER respectively.


Figure 9-30 Subscription Registration
Figure 9-30 Subscription Registration


2.4. Process Execution

Execute the “Cell Phone Subscription Process”. Fill out the following.


Figure 9-31 Process Execution Screen
Figure 9-31 Process Execution Screen


Figure 9-32 Process Execution Screen


Figure 9-32 Process Execution Screen
Figure 9-32 Process Execution Screen


From the whole flow, we learn that the same participant keeps moving forward with stopping, so the participant does not need to look for next assigned tasks.

Exceptional Processes

Multiple Instances
  1. Multiple Instance Configuration


The functionality of “Multiple Instances” is creating more than 1 sub processes at the same time, and the number of sub processes is dynamically defined based on for instance, number of participants or number of process variables. For example, the purchase order process, the consumer requests quotations of purchase orders to various suppliers who need the same processes simultaneously. However, the most of existing BPMS are not able to handle multiple instances, so they overcome these difficulties via programming such as scripts, SI(System Integration). With uEngine’s Multiple Instance functionality, we can simply solve these difficulties through configuration not with programming.

From the previously created Trouble-Ticket process, we will change the role of “Manager” into “Trouble Manager” group.


Figure 10-1 Manager Role Change
10-1 Manager Role Change


In addition, for sub process participant's mapping, mangers from both main and sub processes get mapped each other. Like figure[Figure 10-2], the field, “ForEachVariable”, we select the manager”.


Figure 10-2 Multiple Instance Configuration
10-2 Multiple Instance Configuration


From the [Report trouble] task, select the “Request for Improvement” and click the “Complete”. The figure [Figure10-3] shows that various instances created from the “InstanceId of sub process”.


Figure 10-3 Multiple Instance Execution
10-3 Multiple Instance Execution


Figure 10-4 Single Instance Execution
10-4 Single Instance Execution
Event Handling (ScopeActivity and Event Handler)

“ScopeActivity” enables users to control various activities that we have created so far by tying them all together into a group. Included activities within the scope have the same event handler which makes the main process stop at any time, and execute sub processes or perform defined tasks. Let us practice this “ScopeActivity” with a simple example.


  1. Add “ScopeActivity” into Trouble-Ticket

The purpose of this example is that a person in charge receives trouble tickets and resoloves the issues via two steps of approvals and finally completes the process. If managers responsible for approvals of trouble tickets turn down any of two trouble tickets, the task moves back to the one where the person of charge writes a new resolution for the issues all over again.


Like [Figure 10-5], add one ScopeActivity into the flowchart, especially right after the “Handle Trouble Ticket” task, and Add two Human Works named “Approval1”, “Approval2”. Below the scope, add a sub process on the Event handler area. This sub process is being executed anytime even both “Approval1” and “Approval2” included within the scope are executed.


Figure 10-5 ScopeActivity Execution Screen
10-5 ScopeActivity Execution Screen


At this point, write a new process that links with the added sub process, “Improvement Rejection”. Let us create a new process in the same way as follows.


Figure 10-6 Sub Process Creation
10-6 Sub Process Creation


By making use of “BackActivity” from Activity Palette, the process goes back to the previous task, “Handle Troubles” where the person in charge handles requested trouble tickets. The properties of “BackActivity” are configured like the following figure below.


Figure 10-6-2 Back Activity


Item Value
TargetActivityPV
TargetActivity / InstanceId <%=Instance.MainProcessInstanceID%>
TargetActivity / TracingTag 3
(Target Activity tracing tag number. In this case, 3 is the tracing tag of the previous task, “Handle Troubles”, so, the correct tracing tag must be entered.)


TracingTag is a unique address pointer where the current task goes back to the location chosen. The values of tracing tags are found in the “Basic Properties” of selected activities.


Figure 10-7 Tracing Tag Configuration
10-7 Tracing Tag Configuration


We finally complete the “Approval Rejection” sub process. Click the “Deploy” button, and changes that we have made so far can be applied to the server. If the uEngine version is older than 3.5.2, the current version must be published into production. (Required)

From now on, let us return to the main process, and needs to register the sub process we just created above.


Figure 10-8 Sub Process Mapping
10-8 Sub Process Mapping


Let us make sure that this approval is working correctly. Execute the process, and select “system” for problem type, and explain the problem in detail. After submission by users, the person in charge handles the issues, and writes the resolution for the trouble ticket. From the figure below, we are able to see that the process is still running and currently working for the “Approval1” task.


Event Handler

Open Manager’s workitems, we will see that “Approval Rejection” button is displayed.


Event Handler


With the following figures we are able to see that the sub process completes its works, and returns to the main process when the “Approval Rejection” button is clicked.


Compensation Handling
  1. Compenstation Handling


Compensation Handling is used that the process goes back a specific work item by the request of user or system while the process instance is in progress. If it happens, all the work items processed between the current task and the task where it goes back to must be back to the original in the same way as if the changes have never made.

Our expected “Compensation Handling process is like the figure[Figure 10 9] displayed below. After entering all the information needed from the “Report Trouble”, click the “Complete” button. At the “Insert into DB” task, information is inserted into “TroubleTicket” table. In that case, the flow goes back to the first task, “Report Troubles” by users, delete the current data from the “TroubleTicket” table, and finally the flow moves back the first task.


Figure 10-9 Compensation Handling Process
10-9 Compensation Handling Process


For participants, we only use “Initiator”, the process variables are as follows[Table 10 1].


Table 10-1 Process Variable Configuration
Process Variable Data Type Process Variable for Display Inputter
ProblemType Text ProblemType
ProblemDescription Text Problem Description TextArea(60,5)

Both “Trouble Report” and “Confirmation” acitivities are configured as follows[Table 10 2].

Table 10-2 Activity Configuration
Activity Role Parameters
Trouble Report Initiator ProblemType, ProblemDescription
Confirmation Initiator ProblemType(in), ProblemDescription(in)


For “DB Insertion” activity, [Figure 10 10] and [Table 10 3] can be refereced.


Figure 10-10 Configuration of “DB Insertion” Activity
10-10 Configuration of “DB Insertion” Activity


Table 10-3 Configurations of “DB Insertion” and “DB Deletion” Activities
Activity SQL Statement Parameters
DB Insertion insert into troubleticket(instid,problemtype,problemdesc) values(<%=instance.instanceId%>,?,?) ProblemType, ProblemDescription
Confirmation delete from troubleticket where instid='<%=instance.instanceId%>'

Configure “DB Deletion” activity as well by using [Table 10-3]. Finally, ScopeActivity can be configured by using both [Figure 10-11] and [Table 10-4]. After configuring both activities, Deployment is followed, at last, execute the process.


Figure 10-11 ScopeActivity Configuration
10-11 ScopeActivity Configuration


Table 10-4 ScopeActivity Configuration
Item Value
TriggeringMethod When the scope is compensated
OpenRoles Initiator
Name compensationHandling
DisplayName CompensationHandling

After executing the process, necessary information is entered at the first task, “Trouble Report”. At the last task, “Confirmation”, the executed information is confirmed. Like the figure[Figure 10-13], an inserted record can be viewed by connecting to the Database.


Figure 10-12 Compensation Handling Process Execution
10-12 Compensation Handling Process Execution


Figure 10-13 DB Confirmation of Compensation Handling Process
10-13 DB Confirmation of Compensation Handling Process


Like [Figure 10-13], check the entered information. In another way, like [Figure 10-14] at the last task, “Confirmation”, we return back to the first task, “Trouble Report” by clicking the “Back” button displayed on the flowchart.


Figure 10-14 Compensation Handling
10-14 Compensation Handling


As figure[Figure 10 15] shown below, the flow returned back to the first task, “Trouble Reprot”, and we are able to check the record which we were able to check at [Figure 10 13], was removed by looking at figure[Figure 10 16].


Figure 10-15 Returned Screen of Report Trouble
10-15 Returned Screen of Report Trouble


Figure 10-16 Removed Record
10-16 Removed Record
Exceptional Handling
  1. Fault Handling

Fault Handling is an action when a specific activity has an error during the process, so users such as administrators will be immediately notified.


Figure 10-17 Fault Handling Process
10-17 Fault Handling Process


In an example, [Figure 10-17], Let us configure that if the “DB Update” Activity is in failure, let managers know the error message via Messenger Activity.

Process variables, participants, “Trouble Report”, and “Confirmation” except for “Scope Activity”, “SQL”, “Messenger Activity” are configured in the same way as the “Compensation Handling” had previously. So the ways of detailed configuration will be skipped.

Table 10-5 Configuration of DB Insertion Activity
Activity SQLStatement Parameters
DB Update update troubleticket set problemtype=? , problemdesc=? where instanceid='<%=instance.instanceId%>' ProblemType, ProblemDescription

Like [Table 10 5], configure “DB Insertion” activity in the same way as the table describes. In SQL statement, the column, instanceid does not exist in the database. Therefore, users will be notified that an error is occured when this DB Insertion activity is executed. The figure[Figure 10 18] shown below has the configuration information of Messenger Activity. We just need to follow the instructions. After clicking on the “Messenger Activity” the property window pops up, and clicking the second tab, type this message, “An error occurred while trying to update the table.” for the “Contents” field. At last, configure the “ScopeActivity” based on the figure [Figure 10 19] and the table [Table 10 6]. After configuration, click the “Deploy” and execute the process.


Table 10-6 Configuration of Scope Activity
Item Value
TriggeringMethod When one of child is in fault
OpenRoles Initiator
Name faultHandling
DisplayName FaultHandling


Figure 10-18 “Notification to Manager” Activity Configuration
10-18 “Notification to Manager” Activity Configuration


Figure 10-19 Configuration of Scope Activity
10-19 Configuration of Scope Activity


After initiating the process, “Trouble Report” will be successfully completed, however, the”DB Update” activity occurs an error and users will be notified by the “Notification to Manager” activity. An Error Notification email will be delivered.


Figure 10-20 Execution of Fault Handling Process


Figure 10-20 Execution of Fault Handling Process
10-19 Configuration of Scope Activity


Practical Use of Process Modeling

In Part3, we learned modeling techniques by extending the good example, “Trouble Ticket” process. In Part4, we improve our ability of implementation on process modeling via various practical examples.

Sales Order Contract Management

Task Description

The most important goal for many companies is generating income via sales. One part, “Sales Order Contract Management” in Sales decides whether the order is beneficial for companies. Throughout the whole process, companies review approximate income that can be generated. In advance, it helps companies calculate reasonable quotations that keep from risking by reckless order contracts and quotations. Therefore, companies are able to generate more profits than without the process.

By creating a process for the whole activities mentioned above, we learn how the process can be useful in actual business activities. For a better understanding of this process, we will make use of a simple task happened in a small business as a model.

A flow of “Sales Order Contract Management” includes that a sale person receives orders and report them to a manager. After getting an approval from the manager, a person in charge of quotation completes the quotation forms. Finally, the sale person receives the requested quotation form, and it finishes the whole process.


Figure 10-1 Structure of Sales Order Contract Management Process
Figure 11-1 Structure of Sales Order Contract Management Process


Process Scenario


Figure 11-2 Sales Order Contract Process
11-2 Sales Order Contract Process


  1. A sales person reports an order description
  2. A president reviews the order, and makes a decision abount taking the order, and asking an estimator for a quotation.
  3. After receiving the order, the estimator completes the quotation form based on the order taken by the sales person, and report the quotation form to the president.
  4. The president makes an approval decision whether the quotation is reasonable for the company.
  5. Approved quotation form is delivered to the sales person and finishes the process.


Process Defintion


Summary of Process Definition

Order Report Order Review Write Quotation Form Quotation Review Result Notification
Participant Sales Person President Estimator President Sales Person
Process Variable IsOrderApproved IsQutationApproved
Form Order_Report_Form Order_Report_Form Quotation_Form Quotation_Form Quotation_Form

For order approval, there are two ways we can have for the result. The first one is the “Quotation Request” after getting an approval by the president. The second one is that the order can not be allowed. For quotation approval, the decision can be made whether filling out another quotation form is needed again for the same order.


Form Creation

We need two forms(“Order Report”, “Quotation”) before creating a process. Two form need the same basic information such as “customer name”, “phone number”, “project name”, and “a person in charge”. So we take advantage of the one that we created first. For approval, radio buttons must be inserted into each form.

Entry Field Name(Form) Order_Report_Form(Order Report Form) Quotation_Form (Quotation Form)
Quotation_Form (Quotation Form) y / n y / n
  • For entry fields, the field names must be alphanumeric (space, special characters are not allowed)


Figure 11-3 Order Report Form
11-3 Order Report Form


Figure 11-4 Quotation Form
11-4 Quotation Form


Participant Definition

Let us define participants required for the process. A person who reports an order to the manager is a sales person(the process initializer), an estimator who completes the quotation form, and a president who approves both “order report” and “quotation” forms, so three participants get involved in the process.

Participant ID Participant Name for Display
Initiator Sales Person
President President
Estimator Estimator

There is only one president working in the company, so we select the persident(special user) directory by selecting the first tab menu, “Direct Mapping” of the Role Picker. The title of the estimator is Manager, so we select Manager for the participant by selecting the second tab menu,”By Role” of the Role Picker.


Figure 11-5 Role Mapping(Direct Mapping)
Figure 11-5 Role Mapping(Direct Mapping)


Figure 11-6 Role Mapping(Rule-Based)
Figure 11-6 Role Mapping(Rule-Based)


Process Variable Definition

Two forms(Order Report Form, Quotation Form) that we created ealier must defined as a process variable. The last values, “Approved/Rejected”, on each form required for deciding whether the proposal is approved or rejected are also declared additionally, because the values included in the forms(internal values of the forms) can not be a direct process variable. Therefore, additional process variables must be mapped with values existed in the forms.


Table 11-1 Process Variable Definition
Name Data Type FormDefId(Defined Form) Process Variable Name for Display
Order_Report_Form Html Form OrderReportForm Order Report Form
Quotation_Form Html Form QuotationForm Quotation Form
Order_Approval Text Order Approval
Quotation_Approval Text Quotation Approval

Process Flow Definition

First of all, define “Order Report” and “Order Review” activities. Two activities need forms, so we selecte two FormActivities from the Activity Palette, and drag & drop them into the flow chart. After clicking each activity, select a relavant form that we created earlier for “VariableForHtmlFormContext” field located under the second tab menu, “FormActivity”.


Table 11-2 Participants per each Activity
Activity Order Report Order Review Write Quotation Form Quotation Review Result Notification
Participant Sales Person President Estimator President Sales Person
Figure 11-7 Order Report Form Usage
11-7 Order Report Form Usage


Figure 11-8 Entry field Mapping of Order Report and Quotation
11-8 Entry field Mapping of Order Report and Quotation


The other three tasks including “Write Quotation Form”, “Quotation Review”, and “Result Notification” can be composed with “FormActivity”. At these steps, all the process variables of basic information are passed from the “Order Report Form” by mapping. Let us define a flow of the process. First of all, after completing “Order Review” with an approval by president, the step moves to the “Write Quoation Form”, otherwise, the process stops moving forward. From “Write Quotation Form” to “Quotation Review”, it keep repeating until a quotation approval is made by the president.


Figure 11-9 Conditional Branches and Repetition


Figure 11-9 Conditional Branches and Repetition
11-9 Conditional Branches and Repetition


Taking one of the possible branch paths or conditioning loop requires an approval made on the “Order Review”, “Quotation Review” forms respectively. So each approval field on forms needs to get mapped with a created process variable correspondly.


Table 11-3 Mapping between Entry Fields and Prcoess Variables
Activity Form Field Process Variable
Order Review order_apr (radio button of Order Review Form) IsApproved(Order Review)
Quotation Review IsApproved(radio button of Quotation Review) IsQuotationApproved(Quotation Review)

Based on the result of order review approval, the flow moves to the task of “Write Quotation Form”. If the values is ‘n’, the process stops, otherwise, the next task will appear on the screen.

Table 11-4 Configuration of Conditional Branches
Case Condition
Approved IsApproved == (Direct Value) y
Rejected otherwise


Figure 11-10 Configuration of Conditional Branches
11-10 Configuration of Conditional Branches


A quotation created by the estimator must be approved by the president. If the president is not satisfied with the quotation, loop starts working, so the configuration of loop condition is needed. If the condition is ‘n’ , the estimator fills out another quotation form again.


Table 11-5. Configuration of Loop Condition
Condition1 IsQuotationApproved == (Direct Value) n


Figure 11-11 Configuration of Loop Condition
11-11 Configuration of Loop Condition


After completing this, we finally complete the process design. After deploying, our definition will be found on the list of Definitions.


Process Enactment

"'Order Report' and 'Quotation' tasks for a Sales person, assistant manager Mr Kim in A corporation"

An assistant manager, Mr. Kim got an order from B corporation, and connected to the system of A corporation, and starts the “Sales Order Contract Process”, and filling out the first task, “Order Report”.

The president of A corporation, reads the “Order Report” made by the assistant manager, Mr. Kim, and decides whether the order is profitable for the corporation. If it is reasonable, then approves it, otherwise rejects the request. However, in this case, we assume that the corporation had better take the opportunity, so approves the request.


Figure 11-12 Order Report Screen
11-12 Order Report Screen


Figure 11-13 Order Review Screen
11-13 Order Review Screen


The approved task is delivered to an estimator, manager Mr Lee, and he fills out a quotation form based on the order taken by the sales person.


Figure 11-14 Written Quotation Form
11-14 Written Quotation Form


A written quotation form is delivered to the president. After reviewing the quotation, he approves the quotation because the quotation is very reasonable for the corporation.


Figure 11-15 Quotation Approval Screen
11-15 Quotation Approval Screen


The approved quotation form is delivered to the Sales Person, assistant manager, Mr Kim. He doublechecks the quotation, and finally he completes the contract with B corporation.


Developer Manual

Introduction

1.Introduction

Today’s e-business trend is interactions with network applications like web services. In order for us to follow this trend, we need to be able to integrate business resources in a real time or keep up with fast moving technology. With that reason, uEngine’s component based BPMS provides us to have adaptability and flexibility. uEngine not only supports Business Process Management for companies, but also B2B(Business to Business) and even EAI(Enterprise Application Interface) between applications as an integrated business operating system. uEngine is built based on GNU philosophy with developers’ active and cooperative involvements in development. [Note] This manual is written based on uEngine standalone v3.5.2 version. The followings are essential that you need to understand before moving ahead.

  • Workflow Management System
  • Web Services (SOAP/WSDL/UDDI)
  • J2EE
  • Object oriented framework
  • JAVA Beans framework and reflection
  • Design Patterns
  • XML and XML Binding framework (JAXB)
  • JSP and simple Portlet

[Note] The component based uEngine follows the unique OKF(Open Kernel Framework) development methodology that supports abstraction, persistence, and tools. Moreover, with efficient and proved workflow methodology, the component becomes formalized. Therefore, users maximize usability in business environment. In conclusion, with the focus on business environment implementation preferences, it attracts developers to deliver recyclable components that have high frequency of use. It definitely differs from other component based development methodologies, frameworks, and templates.

2.Strengths

Unsolved Workflow Problems

Workflow(Workflow Management Systems or Business Process Management Systems) based development helps users reduce burdens on not only business process implementation and design but also process execution and monitoring, and many more. However, there are unsolved issues that the workflow does not cover in development even though it is very easy and efficient.

  • Does workflow satisfy all the requirements in development?(Customization Problem)

Even though, workflow supports much functionality needed in development, there are chances that we must add new activity types according to the requirements or changes of business or techniques. Mostly, technical understanding, implementations, and refactoring process are required in order to add new activities into workflow engines. We might be worried about “how we could complete the project before the deadline with limited time, cost, and workflow product supports”. This is a hazard that we might confront during early or in the middle stage of the project.

  • Is it recyclable in different environments if we have workflows?(Portability Problem)

All packaged products have the same recycling problems. Packaged applications are well understandable and useful by its engines. However, users are mostly required to re-develop their applications when different environments or applications involved. This also brings a new issue whether workflow is applicable when the project is just initialized.

  • Is it well implemented among different types of workflow engines? (Interoperability Problem)

Workflow integration between organizational workflows or B2B(Business to Business) transactions by using process connections is the most powerful feature. In spite of significant efforts toward standardization, it is still difficult to have flexible integrations under different system environments developed in different programming languages along with its own workflow engines.

uEngine Design Principles

With limitation on existing workflow engines, uEngine tries to overcome the unsolved issues with the following two ideas.
1) Component frameworks
2) Apply Web Service design principles.

uEngine = Workflow Management System + Component based Development Tool + Web Service based Integration Solution


Component based adaptable/growing engine
In Java development environment such as JavaBeans, EJB, the separation between business logic and techniques is available on component based frameworks under component environment. It also helps developers extend functionality that requires XML, Web Services, Swing, Message Queuing, even EJB that are simply added without understanding of these technologies.

  • Component based development methodology : It is supported with a component addition environment like plugin method that keeps applying new technical, functional requirements without engine change. It is possible that the special object oriented structure, OKF(Open Kernel Framework) is installed under the uEngine.
  • Especially, not only new features but also new process flow patterns can be extended that basically differ from engines developed by other organizations.
  • It helps developers not to make the same mistakes that they already made during the development because experiences that obtained from various projects are effective for them not to make the same mistakes. The topic will be brought up in next development strategy chapter.

Based on Web Services

The process made by uEngine becomes a Web Service as is. Users can benefit from the dynamic integration of WSDL-SOAP Web Service (integration without technical knowledge) and make use of its strengths. It helps other workflow engines integrate with uEngine process in the simple and easy way of Web Services. In addition to that, uEngine is not only for opening processes, but also applying engine development design for the purpose of process implementation between web services.

  • XML based Process Variables : uEngine contains XML-type systems for process variable declaration, assignment, and job processing. This also supports fundamental functionalities for data delivery between web services and web services based workflow resource integration management.
  • Dynamic Web Service Activity : It provides activity types that help users make use of the detection, integration, and invocation of web services. With these features, users are able to build the Internet business environment successfully.
  • Integrated Resource Management : Workflow resources (IT, employees, business partners) are well managed as an integrated resource management with various web services by wrapping. All resources defined within uEngine can be recyclable anywhere.

Architecture

2.Architecture

This chapter explains regarding uEngine design and even overall architecture process models in order for users to understand advanced programming source codes.

System Architecture

uEngine is based on the combination of the most popular architectures.

Figure 1. uEngine Architecture
Figure 1. uEngine Architecture


J2EE is chosen as uEngine system framework

J2EE helps uEngine be operated under the circumstances that include managed transactions, messaging, and managed persistence in the same state of uEngine logic. The following 6 Beans are structured.

  • One stateless Bean(ProcessManagerBean) : It is the entrance responsible for receiving service requests such as process management, operation, and external web service invocation.
  • Two Message Driven Beans(WorkProcessBean, FaultProcessorBean) : Physically, the process ends.
  • Three Entity Beans : Preserve transactional data

All business logic and database entities are not structured by EJB . Actually, OKF(Open Kernel Framework) and JE22 placed in the center of the uEngine are responsible for receiving requests and executing logic by workflow related components, and returning the results. It provides professional component interface to workflow engines. For more detailed description, a separate chapter will be used.

Interface between configured workflow elements via Web Services

uEngine’s sub-structured modules and workflow with the configured elements that contain workflow engine, workflow handlers, email server are separated as much as possible, also these are interfacing by web services. This means that it is easily replaceable by other types of components and becomes the foundation of the system which has potential to be recognized universally. For instance, users are able to use uEngine Process management functionality with their existing portal systems or intranets that interface with the uEngine via supported Web Services, while they keep their comfortable user interfaces

Web Service tools - Axis / WSDL4J / UDDI4J

uEngine creates Web Service stubs at design time by Axis tools invoked by Ant. And then, process definitions are open and being hosted. WSDL4J is used for getting connection information needed for Web Service invocation of Process Designer. For various Web Services search, UDDI4J and uddibrowser(hosted in sf.net) which is the open source UDDI search tool are used.

Persistence – XML Serialization plus Entitiy Beans

In order to preserve XML formatted data, XGen is used to convert Java Objects into XML at run time. The converted XML is saved by Java Beans. uEngine also takes into consideration on adopting Apache Xindice, XML specialized databases for the next version.

Easy approaches on the Internet via Java Web Start

JWS technology is a recent client design methodology that is easy to use. On the Web browser, Process Designer developed by Java Swing is open, and users continue working on it.

[Note] Metaworks is a framework used to create UI(User Interfaces) like Process Designer, Workitem Handlers. For more detailed introduction to Metaworks, it will be brought up in a separate chapter.

Process Manager Interface

For external access, the session bean, org.uengine.processmanager.ProcessManagerBean is supported. The following shows the definitions of Process Manager interface. For overhead issue, uEngine makes use of “Stateless Bean” rather than “Stateful Bean”. It is possible that overhead for resource persistence is avoided with the use of “Stateless Bean”. For the purpose of the issue, process definition names or instance IDs should be passed as arguments when invoking various methods if needed.

[Note : Detailed Interface information, see Appendix C - ProcessManagerRemote API Reference]

//initialize process manager –Process Start related APIs
	public String initialize(String processDefinition, String instanceId, RoleMapping loggedRoleMapping) throws RemoteException;
	public String initializeProcess(String processDefinition, String instanceName) throws RemoteException;
	public String initializeProcess(String processDefinition) throws RemoteException;
	public String initializeProcessIfRequired(String processDefinition, String instanceId) throws RemoteException;

//process execution – Process Execution related APIs
	public void executeProcess(String instanceId) throws RemoteException;
	public void executeProcessByWorkitem(String instanceId, ResultPayload resultPayload) 
throws RemoteException;

//process variable – Process Variable related APIs
	public void setProcessVariable(String instanceId, String scope, String varKey, 
Serializable val) throws RemoteException;
	public Serializable getProcessVariable(String instanceId, String scope, String varKey) 
throws RemoteException;
	public String getProcessVariableInXML(String instanceId, String scope, String varKey) 
throws RemoteException;
	public Hashtable listProcessVariableValues(String instanceId) throws RemoteException;

//role – Responsibility/Role related APIs
	public void putRoleMapping(String instanceId, String roleName, String endpoint) 
throws RemoteException;
	public void putRoleMapping(String instanceId, RoleMapping roleMapping) 
throws RemoteException;
	public void delegateRoleMapping(String instanceId, String roleName, String endpoint) 
throws RemoteException;
	public void delegateRoleMapping(String instanceId, RoleMapping roleMapping) 
throws RemoteException;
	public String getRoleMapping(String instanceId, String roleName) 
throws RemoteException;
	public RoleMapping getRoleMappingObject(String instanceId, String roleName) throws RemoteException;

//messaging, triggering, event, workitem handling – Message, Trigger, Event, Workitem related APIs
	public Serializable sendMessage(String instanceId, String message, Serializable payload) throws RemoteException;
	public Serializable sendMessageXML(String instanceId, String message, String payload) throws RemoteException;
	public void completeWorkitem(String instanceId, String tracingTag, String taskId, ResultPayload payload) throws RemoteException; 
	public void saveWorkitem(String instanceId, String tracingTag, String taskId, ResultPayload payload) throws RemoteException;
	public void executeEventByWorkitem(String mainInstanceId, String eventName, ResultPayload resultPayload) throws RemoteException;
	public void executeEventByWorkitem(String mainInstanceId, String eventName, String triggerActivityTracingTag, ResultPayload resultPayload) throws RemoteException;
	public String[] delegateWorkitem(String instanceId, String tracingTag, RoleMapping roleMapping) 
throws RemoteException;

//flow control – Activity Flow Control related API
	public void flowControl(String command, String instanceId, String tracingTag) throws RemoteException;

//process definition – Process Definition related APIs
	public String addProcessDefinition(String name, int version, String description, boolean isAdhoc, String strDef, String folder, String pdid) throws RemoteException;
	public String addProcessDefinition(String name, int version, String description, boolean isAdhoc, String strDef, String folder, String belongingPdid, String objectType) throws RemoteException;
	public String addProcessDefinition(String name, int version, String description, boolean isAdhoc, String strDef, String folder, String defId, String objectType, String alias, String superDefId) throws RemoteException;
	public String addProcessDefinition(String name, int version, String description, boolean isAdhoc, ProcessDefinition def, String folder, String pdid) throws RemoteException;
	public void removeProcessDefinition(String definitionName) throws RemoteException;
	public void renameProcessDefinition(String pdName, String newName) throws RemoteException;

	public String getProcessDefinitionIdByAlias (String alias) throws RemoteException;
	public void setVisibleProcessDefinition(String defId, boolean isVisible) throws RemoteException;

//get ProcessDefinitionRemote – Process Information related APIs
	public ProcessDefinitionRemote[] listProcessDefinitionRemotesLight() throws RemoteException;
	public ProcessDefinitionRemote[] findAllVersions(String pdid) throws RemoteException;
	public ProcessDefinitionRemote getProcessDefinitionRemote(String processDefinition) throws RemoteException;
	public ProcessDefinitionRemote getProcessDefinitionRemoteWithInstanceId(String instanceId) throws RemoteException;

//Production Version – Process Version related APIs
	public String getProductionVersionIdAtThatTime(String defId, Date thatTime) throws RemoteException;	
	public String getFirstProductionVersionId(String defId) throws RemoteException;
	public void setProcessDefinitionProductionVersion(String pdvid) throws RemoteException;
	public String getProcessDefinitionProductionVersion(String definitionGroupId) throws RemoteException;
	public String getProcessDefinitionProductionVersionByAlias(String alias) throws RemoteException;
	public String getProcessDefinitionProductionVersionByName(String pdName) throws RemoteException;

//get ProcessDefinition – Process Information Collection related APIs
	public ProcessDefinition getProcessDefinition(String processDefinition) throws RemoteException;
	public String getProcessDefinition(String processDefinition, String encodingStyle) throws RemoteException;
	public ProcessDefinition getProcessDefinitionWithInstanceId(String instanceId) throws RemoteException;
	public String getProcessDefinitionWithInstanceId(String instanceId, String encodingStyle) throws RemoteException;

//get Resource – Form Resource Collection related APIs
	public String getResource(String resourceId) throws RemoteException;

	//get ProcessInstanceRemote – Process Operation Information related APIs
	public ProcessInstanceRemote[] listProcessInstanceRemotes() throws RemoteException;
	public ProcessInstanceRemote[] listProcessInstanceRemotes(String definition) throws RemoteException;
	public ProcessInstanceRemote[] listProcessInstanceRemotes(String definition, String status) throws RemoteException;
	public ProcessInstanceRemote[] listProcessArchiveRemotes() throws RemoteException;

//process Instance – Process Operation related APIs
	public void removeProcessInstance(String instanceId) throws RemoteException;
	public void stopProcessInstance(String instanceId) throws RemoteException;	
	public ProcessInstance getProcessInstance(String instanceId) throws RemoteException;
	public void setProcessInstanceInfo(String instanceId, String info) throws RemoteException;
	public void setProcessInstanceStatus(String instanceId, String status) throws RemoteException;

//Activity – Activity related APIs
	public Serializable getActivityProperty(String processDefinition, String tracingTag, String propertyName) throws RemoteException;
	public Hashtable getActivityDetails(String processDefinition, String tracingTag) throws RemoteException;
	public Hashtable getActivityInstanceDetails(String instanceId, String tracingTag) throws RemoteException;
	public String getActivityStatus(String instanceId, String tracingTag) throws RemoteException;
	public HashMap getInitiationParameterMap(String pvdid) throws RemoteException;

//ActivityInstanceProperty – Activity Property related APIs
	public Serializable getActivityInstanceProperty(String instanceId, String tracingTag, String propertyName) throws RemoteException;
	public void setActivityInstanceProperty(String instanceId, String tracingTag, String propertyName, Serializable value) throws RemoteException;
	public void setActivityInstanceProperty(String instanceId, String tracingTag, String propertyName, Serializable value, Class valueType) throws RemoteException;
	public Serializable doActivityAction(String instanceId, String tracingTag, String actionName, Serializable[] parameters, Class[] parameterTypes) throws RemoteException;

	//import and export – Process Definition and Download and Loading related APIs 
	public void exportProcessDefinitionbyDefinitionId(String defId, boolean allVersion) throws Exception;
	public void exportProcessDefinitionbyVersionId(String defVerId) throws Exception;
	public Vector importProcessDefinition(String parentFolder, InputStream loadedZipFile, UEngineArchive editedUa, String[] command ) throws Exception;
	public Hashtable importProcessAliasCheck(InputStream is) throws Exception;

//flow chart – Flowchart related APIs
	public String viewProcessDefinitionFlowChart(String processDefinition, Map options) throws RemoteException;
	public String viewProcessInstanceFlowChart(String instanceId, Map options) throws RemoteException;

//folder – Folder related APIs
	public void removeFolder(String folderName) throws RemoteException;
	public void addFolder(String folderName, String parentFolder) throws RemoteException;
	public void moveFolder(String pdid, String parentFolder) throws RemoteException;

//dynamic change – Process Definition Change Management related APIs
	public void changeProcessDefinition(String instanceId, String definitionInXML) throws RemoteException;
	public void changeProcessDefinition(String instanceId, ProcessDefinition definition) throws RemoteException;

//test – Test Processing related APIs
	public void setFault(String instanceId, String tracingTag, Exception fault) throws RemoteException;

//signaling all the changes can be applied – Handling Change related APIs
	public void applyChanges() throws RemoteException;
	public void cancelChanges() throws RemoteException;

//user can pass some parameters into the kernel – Handling login information related APIs
	public void setGenericContext(Map genericContext) throws RemoteException;
	public void setLoggedRoleMapping(RoleMapping roleMapping) throws RemoteException;
	public EventHandler[] getEventHandlersInAction(String instanceId) throws RemoteException;
	public ActivityReference getInitiatorHumanActivityReference(String pdvid) throws RemoteException;

Each invocation is handled by the abstract framework, OKF(Open Kernel Framework) that will explain in the next chapter. [Note] By checking jsp files in was/webapps/uengine-web directory or scripts supported by scriptcosole, you will understand how each interface works.

Persistence Framework

uEngine completely separates logic from kernel for data preservation. Process definitions are obtained from “org.uengine.kernel.ProcessDefinitionFactory”. All transactional data is handled by “org.uengine.kernel.ActivityInstance class. In addition, EJBProcessInstance class is used as a default. There are various ways of preservation mechanisms plugged into uEngine. The reason is that we are not able to take responsibility for the risk on complex database design which is critical on performance.

Default Preserved Framework

The default ProcessDefinitionFactory class and EJBProcessInstance class take advantage of XML Serializer and Entity Beans together. It is considered an intermediate way to approach. Objects need to be serialized into XML-Text format, in order to save overall data. For the purpose of a better search performance, it should be saved into Entity Beans. With the default preservation framework that consists of the following three entity beans and XML-Serializer, data can be finally preserved.

1. org.uengine.persistence.processdefinition.ProcessDefinitionRepositoryBean

DescriptionProcess Definitions in XML Text are saved
FieldsID – Definition name, Description – Definition Explanation, Definition – Definition XML Content
NoteFor large volume of database based process definition analysis, definitions need to be stored in a fine-grained way that contains as many tables as possible.

2. org.uengine.persistence.processinstance.ProcessInstanceRepositoryBean

DescriptionSimple information is saved into database that contains the summarized explanation of Process Instances.
FieldsID – Process Instance ID, Definition – Process Definition name (for the reference), StartedDate – Start Date & Time

3. org.uengine.persistence.processdefinition.ProcessVariableRepositoryBean

DescriptionWith XML Serializer use, objects saved in text format, so process variables are stored in Generic type. Therefore, Complex database design can be avoided however, the performance of transactional data based analysis can not be guaranteed
FieldsID – Primary Key, InstanceId – Instance ID(Foreign Key), KeyString – Variable Key name, Value – Actual data value (regardless of variable data type, because of its XML format)
NoteFor transactional data analysis or fast search result, we recommend using SQLActivity class which is an indirect way to do. Instead of using actual data stored by uEngine, necessary information based on requirements for the focus on user’s analysis is better saved into database by adding programming codes into SQLActivity class that is the indirect way doing it. This improves database performance and system complexity.

[Note] 3.3 For more examples in implementation, see Appendix F 3.3.

Composite Pattern

The next figure 2 explains process definition object models used by uEngine. This model is the famous extended version of ‘Composite Pattern ’ .

Figure 2. Activity Component Object Structure of uEngine
Figure 2. Activity Component Object Structure of uEngine


Block type flow models are well designed to be saved by object models. Simple and complex activities both contain execution commands and easily added. However complex activities have logic commands additionally. Simple Activity types include Web Service invocation, sending emails, and human works, while complex activity types control managing between such activities like sequence, all, switch. These two activities are structured by inheritance between Activity and ComplexActivity. It is useful that Activity and ComplexActivity share the same protocol. The same structure makes framework simple and can be extended to generic.

Main class

For a better understanding of uEngine process meta models, there are essential classes that we need to understand before jumping into the details.


1. Activity Definition Class – Activity

Activity.java consists of fields composed with basic activities, callback method declaration, fundamental structure codes, and several utilities. [Note] 3.5.1 For more examples, see Appendix F 3.5.1.


2. Activity Flow Control Class – ComplexActivity

ComplexActivity.java can have child activities. It also controls flows between child activities. Basically, child activities are executed sequentially. AllActivity that executes parallelly is inherited from parent Activity class. In the process meta model addition to that, setter/getter is followed by programming convention, through reflection, design time support is available. uEngine Process Design is working like a Beanbox that helps users be able to make changes on activity types in a Java Bean format by given forms on which its values are automatically set. Developers are able to create activity types according to the rules without understanding AWT or Swing technology. [Note] 3.5.1 For detailed examples, please see Appendix F 3.5.1

It is a class that holds one process definition. It basically works sequentially because it inherits to ComplexActivity class. Additional information is held and required for process definitions.

3. Process Definition Class – ProcessDefinition

Figure 3. Relationship between Process Definition and Instance
Figure 3. Relationship between Process Definition and Instance


It is a class that holds one process definition. It basically works sequentially because it inherits to ComplexActivity class. Additional information is held and required for process definitions.


4. Roles and Role Mapping Class – Roles and RoleMapping

The role decides participants declared in Process Definition. RoleMapping is also a class that holds the information of an initiator who executes Process Definition initially. Role holds the name of responsibility, while RoleMapping holds the email address or endpoint URI(in the case of Web Service) of the participant who executes an assigned work.


5. Process Variable Class – ProcessVariable

ProcessVariable is a class used for Process Variable declaration. It holds variable name, data type, and QName(in the case of XML). The actual value is saved into XML by using the set method of ActivityInstance class.

[Note] 3.5. For more examples, see Appendix F 3.5.

Component Framework
Figure 4. Component Framework
Figure 4. Component Framework


uEngine is based on component framework that helps users continuously extend the system with new activity type additions. This feature helps developers not to make the same mistakes that already made from experiences obtained during other projects. It also improves productivity and quality simultaneously.

uEngine is followed by a component based development methodology which is stable and guaranteed along with the proved analysis of workflow. This is similar to other component based methodologies, but with the focus on business environment implementation preferences, it attracts developers to deliver recyclable components that have high frequency of use. In conclusion, with the efficient and proved workflow methodology, the component becomes formalized. Therefore, users maximize usability in business environment. Under the uEngine, OKF(Open Kernel Framework) is based. The following UMLs show the steps of overall delegation how it works.

Figure 5. A Style of Open Kernel Framework Movement Sequence Diagram for ‘Delegation regarding logic’
Figure 5. A Style of Open Kernel Framework Movement Sequence Diagram for ‘Delegation regarding logic’


Design, Validation, Monitoring, Viewing, Persistence, and Execution control needed for Workflow life cycle are controlled by the kernel(hot-spot). During the working period with the lead of kernel, these are managed by activity execution related properties and logic invocation on necessary ActivityType. This minimizes the dependency by using separation between application logic and workflow system logic. Therefore, the only jobs for developers are to write properties and implement the properties according to the logic interface required for each situation. Without related technical knowledge, they are able to add new activity types into stable and automatically managed environments.

Component Interfaces

There are Activity execution related Activity components in uEngine, however many additional components need to be declared into separate classes. The reason of separation between given Activity components and additional Activity components written by users is that it is easy to manage by different type. With inheritance, unnecessary code dependencies are reduced effectively.

[Note] Each component that has examples can be found in its class file located in its cohesive package.

First of all, there are one Activity type and the related components.

  • Process Viewers (org.uengine.kernel.viewer.*)
DescriptionIt is a viewer component that shows process flow at monitoring time.
Interface

public interface ActivityViewer{
// After reading activity properties, rendering into HTML and returns
StringBuffer render(Activity act, ActivityInstance inst, Map options);
}

Name[Activity Name]Viewer ex) SQLActivityViewer
Time in useMonitoring Time
Invocation Kernelorg.uengine.processmanager.ProcessManagerBean
  • Activity Descriptors (org.uengine.kernel.descriptor.*)
DescriptionIn general, with the purpose of additional properties(caption and input control definitions) at design time, Metaworks framework used for creating UI(User Interface)
Interface

(Please refer to the separate chapter for Metaworks’s explanation.)

Name[Activity Name]Descriptor ex) SQLActivityDescriptor
Time in useDesign and Monitoring Time
Invocation Kernelorg.uengine.processdesigner.ProcessDesigner

Sharing with Metaworks framework

  • Activity Designers (org.uengine.kernel.designer.*)
DescriptionIn order to modify given activities via designer component(UI component)
Interface

public interface ActivityDesigner{
     public Activity getActivity(); //Getting Activity for Modification
     public void setActivity(Activity value);//Setting Activity for Modification
     public void onDropped(java.util.Vector components); //Other Activities dropped from design tool
     public ComplexActivityDesigner getParentDesigner(); //Getting Parent Designer
     public void openDialog(); //Opening property editor for the activity type
     public java.awt.Component getComponent(); //Getting awt or swing control for expressing the activity
}

Name[Activity Name]Designer ex)SQLActivityDesigner
Time in useDesign Time
Invocation KernelCreated by getActivityDesigner method in org.uengine.kernel.Activity class Used by org.uengine.processdesigner.ProcessDesigner
  • Activity Image (org.uengine.kernel.images.svg.*)
DescriptionEach Activity icon image
Interface
Name[Activity Name].svg ex)SQLActivity.svg
Time in useDesign and Monitoring Time
Invocation KernelUsed by org.uengine.processdesigner.ProcessDesigner

The following components except for Activities due to genuine high frequency of use are generally being used in uEngine.

  • Unified Serializers (org.uengine.components.serializers.*)
DescriptionOverall, it manages components that conduct various serializing mechanisms
Interface

public interface Serializer{
     public boolean isSerializable(Class cls); //whether it is possible that this object can be serialized by this mechanism
     public void serialize(Object sourceObj, OutputStream os, Hashtable extendedContext) throws Exception;
     public Object deserialize(InputStream is, Hashtable extendedContext) throws Exception;
}

Name[Serialized mechanism name]Serializer ex)BPELSerializer, BeanSerializer, and AxisSerializer
Time in useAll of the time phase
Invocation Kerneluengine.kernel.GlobalContext
  • Process Model Adapters (org.uengine.processpublisher.*)
DescriptionFor import/export support between uEngine process object model and various process languages
Interface

public interface Adapter{
     public Object convert(Object src, Hashtable keyedContext) throws Exception;
}

Name1. Importer: [language name]/importer/[original language class name]Adapter

2. Exporter: [language name]/exporter/[activity name]Adapter
ex) WebServiceActivityAdapter

Time in useAll the time phase
Invocation KernelEach language serializer.
ERD

In uEngine, there are database tables that are basically required in definition and customization stages. With several necessary SQL query examples, users are able to check the process information whether it is correct.


Figure 6. System Scheme
Figure 6. System Scheme
DAO
1. DAO Types
Named DAO

IDAO is useful without type definition. Due to lack of type definition, corresponding source codes need to be changed. However, it is impossible, unless users understand all the tables, columns along with data types correctly.

// Using IDAO
…
IDAO person = (IDAO )GenericDAO.createDAOImple(cf,
” select * from person where name=?name”,
IDAO.class);
person.set(“name”,“kim bo sang”);   // The first parameter is the column name, the second parameter is the value of the first parameter.
person.Insert();
…
Typed DAO

Instead of IDAO, it is possible to validate source codes by complier like eclipse, because it uses a declared type(interface). It helps developers reduce typos or mistakes. High frequency of use can benefit better than rare use. However, it is inconvenient when database table information changes, we also need to change the type accordingly.

  • createDAOImple method can be found in org.uengine.util.dao.GenericDAO class
//Person Type definition
public Interface Person extends IDAO{  
	String getName();
	void setName(String name);
}

// Getting the DAO object of Person type
…
Person person =(Person) GenericDAO.createDAOImple(cf    /* ConnectionFactory */,
”select * from person where name=?name”  /* SQL statement*/,
Pserson.class     /* class type */);
person.setName(“kim bo sang”); // a method declared by Interface Person
person.Insert();
…

2. DAOs used by uEngine
GenericDAO

It has automatic connection management functionality, if transactional connection is used, connections could be broken, so it is useful when we need to use DefaultConnectionFactory. After using DAO, the releasing the connection resource is not necessary.

…
DefaultConnectionFactory cf = new DefaultConnectionFactory(); 

// In order to get DAO, GenericDAO class method is used
IDAO person = GenericDAO.createDAOImple(cf, ”select * from person where name=?name”, IDAO.class);
person.set(“name”,“kim bo sang”);
person.Insert();
…

ConnectiveDAO

The difference between ConnectiveDAO and GenericDAO is that in ConnectiveDAO, there is no automatic connectivity management functionality. Therefore, in some cases, we need to make sure that there must not be the automatic connectivity management functionality like transaction handling. The result of the purpose, we need to use ConnectiveDAO instead.

…
TransactionContext tc = new TransactionContext();
ConnectionFactory cf = tc.getConnectionFactory();

IDAO person = ConnectiveDAO.createDAOImple(cf, ” select * from person where name=?name”, IDAO.class);
person.set(“name”,“kim bo sang”);
person.Insert();
…
3. Transaction
Transaction Preservation

DAO is created by getting a connection from TransactionContext, and able to preserve the transaction. We should be aware that when a connection ends, make sure that the transaction should be disconnected as well.

// transaction safe 
TransactionContext tc = new TransactionContext();
try{
         ConnectionFactory cf = tc.getConnectionFactory();
	Person person =( Person) ConnectiveDAO.createDAOImpl(cf, "insert into Person (?name, ?age)", Person.class);
	person.setName("jju");
	person.setAge(32);
	person.insert();
	tc.commit();
}catch(Exception e){
	tc.rollback();
}finally{
	tc.releaseResources();
}

Through DefaultConnectionFactory, besides the transaction, DAO is created separately by getting connectivity, so connectivity should be managed manually well. So, we must make sure that connectivity must be disconnected when it is no longer needed.

// transaction not safe 
DefaultConnectionFactory cf = new DefaultConnectionFactory();
try{
	Person person =( Person) GenericDAO.createDAOImpl(cf, "insert into Person (?name, ?age)", Person.class);
	person.setName("jjy");
	person.setAge(32);
	person.insert();
}catch(Exception e){
}finally{ }
4. Relationship between TransactionContext and TransactionListener

TransactionContext includes one or more than one TransactionListener. When commit() or rollback() methods are invoked, all the included TransactionListeners are automatically invoked as well.


Figure 7. TC and TL Class Diagram
Figure 7. TC and TL Class Diagram


5. Caching Enabled

At this point, caching is collecting all the tasks carried after creating a transaction. After then, all the tasks are being batch processed right before the commit. In a simple way to describe the caching, it keeps all the tasks processed before the commit. The following codes are an example that transaction listeners are added into transaction and conducting the corresponding logic when beforeCommit() method is invoked.

TransactionContext tc = new TransactionContext();
…
tc.addTransactionListener(  new TransactionListener(){
	public void beforeCommit(TransactionContext tx) throws Exception {
                  ConnectionFactory cf = tc.getConnectionFactory();
	Person person = ConnectiveDAO.createDAOImpl(cf, 
"insert into Person (?name, ?age)", 
Person.class);
		person.setName("jju");
		person.setAge(32);
		person.insert();
		tc.commit();
	}
	public void beforeRollback(TransactionContext tx) throws Exception {}

	public void afterCommit(TransactionContext tx) throws Exception {}

public void afterRollback(TransactionContext tx) throws Exception {}
				
}
)
  • The invocation time of the beforeComment() method of TransactionListener is found in the commit() method of TransactionContext class in org.uengine.processmanager package.
6. Synchronized DAO (automatically cached DAO)

SynchronizedDAO is explained in chapter 3.3 that it is a DAO methodology with caching functionality. There is one careful attention needed that commit() method is used instead of either insert() or update() method when applying all the processed works.

createSynchronizedDAO()

A new DAO is created and added into SharedContext when createSynchronizeDAO is invoked, while DAO is recyclable until commit() method is being invoked. For a better understanding of SharedContext, it is the DAO list of transactions being used. All the saved DAO list is initialized automatically when commit() method is executed. In addition, once a DAO is added into SharedContext, the same DAO needs to add again, it conducts the same task 2 times until the commit statement is passed, it delays performance. Therefore, once a DAO object is created by createSynchronizeDAO() method, you can avoid duplicate creations of the same DAO object by using findSynchronizedDAO() method. For this method, 4 parameters are needed. The first one is table name, and the second one is primary key, and the third one is value, and the last one is DAO class name.

TransactionContext tc = new TransactionContext();
Person person = (Person)tc.createSynchronizedDAO("Person", "name", "jjy", Person.class);
person.setName(“jjy”);
... 
Person someone = (Person)tc.findSynchronizedDAO("Person", "name", "jjy", Person.class);
someone.setAge(32);
…
tc.commit(); // Insert person

findSynchronizedDAO()

It is a method that gets the DAO saved in SharedContext through createSynchronizeDAO. The arguments of findSynchronizedDAO are the same as createSynchronizeDAO method.

TransactionContext tc = new TransactionContext();
Person person = (Person)tc.findSynchronizedDAO("Person", "name", "jjy", Person.class);
person.setName(“kbs”);
setAge(30);
…
tc.commit(); /// update person

7. SQL Generation

SQL generation’s functionality is generating a SQL query statement automatically. SQL query statements are not required for DAO creation. There are 2 ways to create SQL query statements. One is applying the autoSQLGeneration option when DAO is declared. The other one is generating SQL query statements through createInsertSql() method right before commit() method invocation.

createInsertSql()

SQL query statement creation must be used right before invoking commit() method, because it is created with the only information carried until createInsertSql() method invocation, as a result of that, complete SQL query statements can be generated right before the commit() method invocation.

IDAO dao = ConnectiveDAO.createDAOImpl(tc, null, IDAO.class);
dao.getImplementationObject().setTableName("Person");
dao.getImplementationObject().setKeyField("name");
dao.set("name", "jjy");
dao.set("age", 32);
dao.getImplementationObject().createInsertSql();
dao.insert();
setAutoSQLGeneration()

SQL query statements are generated automatically when invoking setAutoSQLGeneration(true) method, it is internally set to ‘true’ value as a default. By calling createInsertSql() method right before the commit execution, it generates SQL query statements.

IDAO dao = ConnectiveDAO.createDAOImpl(tc, null, IDAO.class);
dao.getImplementationObject().setTableName("Person");
dao.getImplementationObject().setKeyField("name");
dao.getImplementationObject().setAutoSQLGeneration(true);
dao.set("name", "jjy");
dao.set("age", 32);
dao.insert();
8. EJBProcessInstance

This EJBProcessInstance class is one of typical classes that TransactionListener is being used for this class. It is an implementation class of an abstract ProcessInstance class, and it implements TransactionListerner. So, once an instance is created, one TransactionListener is registered into TransactionContext. As chapter 3.3 explained, many processed tasks are put aside, it is actually applied when beforeCommit() method is invoked.


// Member variables that save Processed tasks 
Map modifiedKeyMap;
Map modifiedRoleMappings;
Map cachedRoleMappings;

//Methods of TransactionListener
public void beforeCommit(TransactionContext tx) throws Exception{
	applyChanges(); // Apply all the tasks into engine
}

public void beforeRollback(TransactionContext tx) throws Exception{
}

public void afterCommit(TransactionContext tx) throws Exception {
}

public void afterRollback(TransactionContext tx) throws Exception {
}

public void applyChanges() throws Exception{
	MeasuringContext mc = new MeasuringContext("EJBProcessInstance:applyChanges()");
		
	ProcessInstanceDAO procInsDAO = getProcessInstanceDAO();
	procInsDAO.getImplementationObject().setTableName("BPM_PROCINST");
	procInsDAO.getImplementationObject().setKeyField("INSTID");
	procInsDAO.setModDate(GlobalContext.getNow(getProcessTransactionContext()).getTime());
		
	if(isNew){
		procInsDAO.getImplementationObject().createInsertSql();
	}else{
		procInsDAO.getImplementationObject().createUpdateSql();
	} 
	procInsDAO.update();
         if(modifiedKeyMap !=null){
…
}

At this point, we might think that this class is also implemented via SynchronizedDAO. However, this class had been implemented before uEngine’s engine adopted SynchronizedDAO.

9. Persistence
EJB Mode Change

The script, ‘use.ejb=false’ is found in the uengine.properties setting file. This means that engine is working under either EJB mode or already implemented uEngine. By clicking uEngine’s ProcessManager menu, there is the process definition tree displayed on the left side of the screen. In order to display the tree menu with created process definitions, ProcessDefinitionList.jsp is invoking listProcessDefinitionRemotesLight() method in ProcessManagerbean.

public ProcessDefinitionRemote[] listProcessDefinitionRemotesLight() throws RemoteException{
try{
ProcessDefinitionRepositoryHomeLocal pdhr = GlobalContext.ceateProcessDefinitionRepositoryHomeLocal(getTransactionContext());
ProcessDefinitionVersionRepositoryHomeLocal pdihr = GlobalContext.createProcessDefinitionVersionRepositoryHomeLocal(getTransactionContext());

	Collection definitions = pdhr.findAllProcessDefinitions();
			
	Vector processDefinitionRemotes = new Vector();			
	for(Iterator iter = definitions.iterator(); iter.hasNext();){
		ProcessDefinitionRepositoryLocal pdrl = ((ProcessDefinitionRepositoryLocal)iter.next());
…

Looking carefully at ceateProcessDefinitionRepositoryHomeLocal method, it is set to ‘use.ejb=false’ and returns ProcessDefinitionRepositoryHomeLocalImpl, which makes EJB not work. In the case of ‘use.ejb=true’, it returns processDefinitionRepositoryHomeLocal, which makes EJB work. With the following codes, users are able to switch the engine mode.

public static ProcessDefinitionRepositoryHomeLocal createProcessDefinitionRepositoryHomeLocal(TransactionContext tc) throws Exception{
	/* 
         * org.uengine.kernel.GloabalContext
* If it is not under EJB mode, returns ProcessDefinitionRepositoryHomeLocalImpl.
         * ProcessDefinitionRepositoryHomeLocalImpl is woking under uEngine’s implemented logic
         * If it is EJB mode, returns processDefinitionRepositoryHomeLocal.
         */
	if(!useEJB)
		return new ProcessDefinitionRepositoryHomeLocalImpl(tc);
		
	if(processDefinitionRepositoryHomeLocal==null){
		processDefinitionRepositoryHomeLocal =
			(ProcessDefinitionRepositoryHomeLocal)
				getInitialContext().lookup("ProcessDefinitionRepositoryHomeLocal");
	}
		
	return processDefinitionRepositoryHomeLocal;
}
RepositoryHomeLocalImpl class

From the previous page, ProcessDefinitionRepositoryHomeLocal is generally declared as an interface, which is inherited from javax.ejb.EJBLocalHome. How about ProcessDefinitionRepositoryHomeLocalImpl? We do not know why we need this as well. The answer is here that ProcessDefinitionRepositoryHomeLocalImpl is an implementation class for ProcessDefinitionRepositoryHomeLocal in order to make use of all the uEngine DAO types.

//ProcessDefinitionRepositoryHomeLocalImpl’s creation method
public ProcessDefinitionRepositoryLocal create(Long id) throws CreateException {
	final ProcessDefinitionDAO pd;
	try {
		pd = (ProcessDefinitionDAO)ConnectiveDAO.createDAOImpl(tc, null, ProcessDefinitionDAO.class);
		pd.getImplementationObject().setTableName("BPM_PROCDEF");
		pd.setDefId(id);
			
		tc.addTransactionListener(new TransactionListener(){
			public void beforeCommit(TransactionContext tx) throws Exception {
				pd.getImplementationObject().createInsertSql();
				pd.insert();
			}

			public void beforeRollback(TransactionContext tx) throws Exception {
			}

			public void afterCommit(TransactionContext tx) throws Exception {
			}

			public void afterRollback(TransactionContext tx) throws Exception {
			}
				
		});
		return pd;
	} catch (Exception e) {
		throw new CreateException(e.getMessage());
	}
}

Development

Install and Build the Project

How to Download and Run the uEngine Standalone
  • Visit this page, http://www.sf.net/projects/uengine
  • Download uEngine_standalone version.
  • Directory descriptions are shown below after downloading the uEngine Standalone version.
Directory Description
defaultcompanyCustomization file directory location
docUser guide, in the case of “apidoc”, use the “javadoc” instead
hsqldbHypersonic Database is given default
META-INFMetaworks directory as a Database development tool
srcuEngine project directory
src/build.xmlUseful commands are supported by Ant tool
wasTomcat directory given by standard WAS
was/bin/startup.bat Useful scripts for executing Tomcat

How to run the uEngine-web

  1. Run “runServer.bat” in the “hsqldb/demo” directory. (hsqldb execution)
  2. Run “startup.bat” in the “was/bin” directory. (Tomcat execution)
  3. Visit the page, http://localhost:8080/uengine-web/.


After running the uEngine, with “test” ID for English version, cf. “test_ko” for Korean version, access can be permitted. For uEngine Standalone version, standard UI and activities are supported. You can also make changes on them by adding and updating the functions as you wish.

[Note] uEngine Server is successfully tested on JRE 1.5 or higher versions, However, you need JRE 1.6 or higher versions for “Process Designer”(Swing Independent Client Application) execution. If the server is not working properly, please add the following script in the top of “startup.bat” file.

set JAVA_HOME=<jre1.5 or jdk1.5 location >

[Note] In the case of the relative directory path issue, data files could not be found. Please add the following script in the top of “startup.bat” file.

Cd <The absolute directory path of “was\bin”> 
After building defaultcompany project, changes can be applied

“defaultcompany” directory is the place where you can apply additional development. Source code changes and additions can be applied by using “Ant”. uEngine customizing methods will be explained in the next chapter, for this time, we perform how to build the uEngine project. The followings should be configured, before compiling “Ant”.


C:\> set JAVA_HOME=C:\Program Files\Java\jdk1.5.0
C:\> set UENGINE_HOME=C:\uengine_standalone
C:\> path %PATH%;C:\apache-ant-1.7.0\bin

And then, execute the “ant” command in the “uEngine_standalone\src\” directory. In addition to that, execute the “ant” command in the “defaultcompany” directory, the following screen below will appear, and it becomes the latest version.

C:\uEngine_standalone\defaultcompany> ant
Buildfile: build.xml

Compile:

Apply:

Signjar:
   [echo] jarfile= ./build/uengine_settings.jar

BUILD SUCCESSFUL
Total time: 1 second
The properties of uengine.properties

Standard configuration values are already written and different changes can be applied in the “uengine.properties” file located in the setup directory, “..\uEngine_standalone\was\webapps\uengine-web\WEB-INF\classes\org\uengine”.

Property Description Example
pd.inputterpackages Process Designer customizing purpose. For additional inputters, the names of different packages are separated by comma(,). org.metaworks.inputter.webInpputer
pd.logo.image The location of logo image resource that appears on the Process Designer, the whole path except for the file extension.
pd.rolepicker.class Customizable role picker class
worklistservice.class Worklistservice class org.uengine.webservices.worklist.JDBCExtWorkList
Daofactory.class DAOTYPE of the database being used org.uengine.persistence.dao.HSQLDAOFactory
processinstance.class ProcessInstance class being used. org.uengine.kernel.EJBProcessInstance
rolemapping.class RoleMapping class org.uengine.liferayintegration.LiferayRoleMapping
server.definition.path The directory path of definition file. <was>/bin/uengine/definition
Web.context.root Web context root path. For Tomcat version, the path is different Jboss :/html/uengine-web
tomcat :/uengine-web
datasource.jndiname JNDI name of Datasource. java:/uEngineDS
usertransaction.jndiname JNDI name of user transaction UserTransaction
portlet.width The lengths of the width and height of Portlet 950
emailactivity.smtp.ip
emailactivity.smtp.userid
emailactivity.smtp.password
SMTP server account for sending emails via  Email Activity. smtp.mail.yahoo.co.kr
pongsor
123456
messengeractivity.msn.id
messengeractivity.msn.password
Account for sending messages via MSNMessenger Activity or AlarmActivityFilter uengine_82@hotmail.com
pongsor2
org.uengine.components.activityfilters.
olapetlfilter.datasource.name
Data Source name of OLAP
DataMart, or for OlapEtlFiler use.
java:/uEngine-DW-DS
Defaultactivityfilters A type of Defaultactivityfilter class (different values are separated by comma(,). org.uengine.components.activityfilters.OlapEtlFilter (Loading the results of work into DM),org.uengine. components.activityfilters.AlarmActivityFilter (any messages delivered to users like Messenger), org.uengine.components.activityfilters. CalendarFilter(It is possible when JBoss is running, calendar scheduling function supported)
use.ejb Whether EJB is needed false
use.managedtransaction Transaction management option (Container or uEngine), if you want all the controlling done by uEngine, set to ‘false’, otherwise ‘true’. true
use.auto.usertransaction.demarcation If 'UserTransaction' is not needed ‘set to true’, otherwise ‘false’ For instance of use.ejb=true, the function is disabled true
was.type The name of WAS JBOSS

Customization functions

How to Develop Customizable Workitem Handlers (WIH)

WIH written in JSP is simply explained that it is the screen seen by user when the process is being executed. It is important, because it occupies the largest space in the customization area. It also retrieves necessary information from the server and submits data to the server through ProcessManager interface.

Figure 8. shows one example of uEngine Workitem handler functions. The WIH is also the user interface for workitem result submission. Users can select a workitem in the worklist(to-do list), the next step of process appears on the screen, finally users click the “Complete” button, the result will be transferred to the server, and the next step will proceed as it shows.


Figure 8. Workitem handler example
Figure 8. Workitem handler example


How WIH works

When index.jsp file is loaded, worklist requests all the information to index.jsp that WIH requires in order to display the results via “request.getParameter() method. It also retrieves chart and the information defined in the Process Designer via PrcessManager bean function. At last, users submit the entered data to submit.jsp, while submit.jsp is collecting the results generated from index.jsp and transmits them after invoking ProcessManager bean function.

In general, users underestimate the system which actually has outstanding execution capabilities or functions, because the quality of their customized designs was poor. Therefore, the best focus on the WIH customizing is UI(User Interface) modifications as users wish by using index.jsp. Basically, create the best screen for users while keeping the standard index.jsp functions.

How to Apply Workitem Handler

WIH can be found in “<UENGINE_HOME>/webapps/uengine-web/wih” directory, after uEngine is installed successfully. It basically defines “defaultHandler”, but additional handlers can be conveniently added if necessary.

Develop Customizable Activity Type

A new activity type can be added as we follow the process object model explained earlier. With a great example, we can add a new activity type. For this time, we create an activity that executes SQL queries.


How to add an activity type

1. Activity types are already defined in “defaultcompany\src\org\uengine\processdesigner\activitytypes.xml” file. New activitiy definition classes can be added by following steps.
2. Save “SQLSampleActivity.java” file into “defaultcompany\src\com\defaultcompany\activitytypes” directory.
3. The image, “SQLSampleActivity.gif” that its name is the same as activity name except for the file extension should be saved into two directory locations below.
1) “defaultcompany\src\com\defaultcompany\activitytypes\images”.
2) “defaultcompany\WebContent\uengine-web\processmanager\images”.
4. Apply with “ant” command execution in the “defaultcompany”.
5. ”Ant” tutorials can be found on chapter 4.2.
6. Restart Tomcat.

Ways to test new activity types.

1. Run the “Process Designer” and click the right button under the “Definitions”, the root node of “Process Manager” tree, and click the “New Process”.
2. Check the left menu whether SQLSampleActivity is created
If it is not found, please doublecheck the followings
1) Is added activity group name in “activitytypes.xml” file different?
2) Is added activity package name in “activitytypes.xml” file different?
3) Is any error found in “SQLSampleActivity.java” file(check base class).
3. In the new process, creates SQLSampleActivity, changes the process name into “ActivityTest”, click the “Apply” button on the bottom of the screen.
4. Click the “Deploy” button.
5. Click the “View” menu under the recently created “ActivityTest” under the Definitions, the root node of “Process Manager” tree.
6. Click the “Initiate” button on the top and right side of the screen.
7. Click the instance ID with “ActivityTest” name in the Process Manager.
8. Click the “Start” button on the flow chart.
9. Check the Tomcat console screen whether it shows that “this is SQLSampleActivity”.


Figure 9. Tomcat captured screen
Figure 9. Tomcat captured screen


As the result of that, activity types are defined in the “activitytypes.xml” file. For setter/getter parts implemented in the “SQLSampleActivity.java”, we could check that the data entry window can be automatically popped up and applied in the Activity Definition part in the “Process Designer” as shown in Figure 10. Some users might be curious about why only test entries are applied. Here is the answer for the question that we will solve the curiosity at the Metaworks part in the near future. Especially, we will learn that executeActivity function parts are eventually executed, when the activity is being invoked.


Figure 10. Process Designer Modification Screen
Figure 10. Process Designer Modification Screen
Implement Customizable Organization Chart

Mostly, BPM systems have their own organization models. Due to the issue, sometimes, synchronization such as batch processing must be made in order to integrate between BPM system and other enterprise applications. However, uEngine not only has its own organization model, but also it provides the strategy interface where users make use of essential strategy components that fit with their own organization models. This key feature helps them prevent from organization data duplication or other complex organization model dependency.

Figure 11. Standard Organization Entity Model
Figure 11. Standard Organization Entity Model


Basically, the ERD shown above is simply given in the actual organization model installed within “hypersonic db”. This model is too simple to satisfy all the requirements given by organization, for a better understanding of an organization model, it is simply made as an example, therefore, users must be able to make changes that reflect their own organization models or applications by using the “strategy components(see the next chapter)”.

Rolemapping class

'RoleMapping' class is responsible for retrieving the detailed information from a specific organization chart. It is one of uEngine key strategy components.

Figure 12. Organization Chart Strategy Pattern -Member
Figure 12. Organization Chart Strategy Pattern -Member


Steps to proceed the role mapping

  1. Request role information from Activity.
  2. Role requests RoleMapping information to ProcessInstance
  3. ProcessIntance sends RoleMapping information to Activity.
  4. Proceed RoleMapping via RoleResolutionContext if RoleMapping information is not found, and send information to Activity.


Figure 13. Organization Chart Strategy Pattern Protocol 1- discover actual mapping Sequence Diagram
Figure 13. Organization Chart Strategy Pattern Protocol 1- discover actual mapping Sequence Diagram


The following codes below show the implementation that ‘Default Company’s RoleMapping class connected with existing organization’s database gets filled with detailed resource information. In general, RoleMapping holds only endpoints, due to the large amount of resource waste. If RoleMapping holds all the information that databases have, we will waste a lot of resources. uEngine simply invokes fill(..) method in RoleMapping class when sending emails or requiring detailed information. And then, RoleMapping gets filled with information. However, in order to apply newly created RoleMapping class, we need to configure uengine.properties in the same way as the one below.

rolemapping.class=com.defaultcompany.organization.DefaultCompanyRoleMapping

RoleResolutionContext class

'RoleResolutionContext' is a component that decides the right person who is the best fit for the role. It is also called a rule definition expression. In a company, for instance, the rules of assigning people from ‘RoleUserTable’ will be explained in 'DefaultCompanyRoleResolutionContext'. The component consists of two parts. One is build time, and the other one is run time. The first build time includes property declaration, metaworks-callback, and getDisplayName() method. Property declaration also gets loaded by entry forms that handle the type information of reflection APIs and RoleResolutionContext. Additionally, with getDisplayName() method, user for the RoleResolutionContext is finally able to understand the screen with returned information. Moreover, ‘metaworks-callback’ provides a static method that makes use of RoleResolutionContext’s GUI when Role Picker is executed by the process designer.


Figure 14. Roll Picker
Figure 14. Roll Picker


‘getActualMapping(..)’ method will be referenced after roles are defined and being invoked. For example, ‘roleID’ searches for the appropriate users whose property is “Role”, and returns the ‘RoleMapping’ object. If you wish to use the RoleResolutionContext class, you need to configure uengine.properties and rebuild the ‘defaultCompany’ project like the one below.

roleresolutioncontexts=org.uengine.kernel.DirectRoleResolutionContext,com.defaultcompany.organization.
DefaultCompanyRoleResolutionContext
Login Mechanism – getLoggedUser.jsp and login.jsp

In order to check current active users on uEngine portal, ‘getCurrentUser.jsp’ and ‘loggedUserXXX’, ‘loggedRoleMapping’ variables can be directly used for the purpose. If you are willing to change the ‘login’ mechanism as you wish, you need to make changes on ‘getLoggedUser.jsp’ in ‘uengine-web/common’ directory. The current login information can be obtained from servlet session, and deliver to ‘getCurrentUser.jsp’ page.

Organization Chart Browser - organizationChart.jsp and organizationChartXML.jsp

It is working similar to ‘getLoggedUser.jsp’. The pages, ‘organizationChart.jsp’ and ‘organizationChartXML.jsp’ can be customized by users based on their organizational culture or structures. Especially, those two pages are automatically referenced within uEngine when any screen needs to pick the best people for the role.


Figure 15. Organization Chart
Figure 15. Organization Chart


How it works? The results can be returned from the database based on the selection criteria that users check on ‘check-boxed tree’ like the Figure 15. shown above. For ‘getSelectedUsers()’ and ‘SelectedInfo()’ methods, their object creations are written in ‘organizationChart.jsp’ template. For declaration parts, it is better not to make changes. If necessary, you need to fully understand these two 'organizationChartPicker.jsp' and ‘org_uengine_kernel_RoleMappingInput.java’ files.

Metaworks / UI Generation Framework

uEngine takes advantage of Metaworks framework to develop Process Designer, the User Interface creation of work processor, and metadata based programming. Metaworks stands for “metadata-oriented database framework”. It is an automatic framework working with metadata selected from the database such as SQL, UI, Web, and EJB. Metaworks is an object oriented framework or component generators different from usual RAD tools or legacy modernizers that mostly working as a source generator. A source code generating method is a burden for developers who need to keep maintaining their programming source codes. However, the uEngine is well designed using design patterns that have great strengths. Those strengths are recycling, extendability, ease of maintaining, and generating useful components. For instance, by changing metadata, all the related technical implementations can be easily updated. Furthermore, it helps you reduce cost and delays in development by using special methodologies such as ‘Customization from default application’ and ‘JIT UI personalization.


Figure 16. Metaworks Framework
Figure 16. Metaworks Framework


[Note] Independently working Metaworks is a sister project with uEngine. For more detailed information, visit here, http://metaworks.sourceforge.net/korean.

Type Declaration
After declaring type class, retrieves information from created tables with criteria using similary like the “create” statement of database.
[Note] 5.4.1. for more useful examples, please see Appendix F 5.4.1.
Automatic UI Creation – InputForm Type Use
Metaworks is creating a ‘Form Panel(Swing JPanel) that can receive one row of data entry in a given type. For instance, by invoking metaworksCallback method, name and the date of birth can be entered by users. As we learned from chapter 5.2. “Develop Customizable Activity Type”, with use of setter/getter, we could control entry fields for users. Additionally, we are able to create User Interfaces on processDesigner.
[Note] 5.4.2. For more examples, please see Appendix F 5.4.2
Consistent ways to input data - Inputter
Swing entry UI components are useful for consistent ways to process and it is an interface where recycling and abstraction are easily made, therefore it is flexible, extensible, and especially useful for UI development.
  • Standard Inputters supported (com.cwpdm.util.db.inputter.*)
Inputter class Description Default type
TextInput JTextField entry window Types.VARCHAR
NumberInput Only numeric type allowed, right aligned JTextField Types.INTEGER
DateInput Calendar DateButton Types.DATE
SelectInput JComboBox, only one option allowed N/A
RadioInput RadioButton, only one option allowed N/A
ReferenceInput JTextField entry window selection PopupButton, only one option selected from the database

The sixth argument for the parameter of “FieldDescriptor” class can be entered.

new FieldDescriptor("JOB","Job Selection", 12, false,		
	new FieldAttribute[]{
		new FieldAttribute("default", new String("Unemployeed")),
	},
	new SelectInput(new String[]{"", "Unemployeed", "Student", "Employeed"})	
),

new FieldDescriptor("BookCount","No of videos borrowed, 0,false,
	null,
	new NumberInput()  
),	
...

After defining data types, you can create “Form Panel” by using InputForm class. [Note] 5.4.3. For more examples, please see Appendix F 5.4.3.


Consistent ways to validate - Validator
In order to validate entered data whether it is in correct format, consistent interfaces are supported. Especially, for the combination of several validation conditions, it is possible to check all the requirements for passing the validation, and error handling with appropriate error messages is automatically supported through InputForm.
Standard validators supported (com.metaworks.validator.*)
Validator class Description Default type
NotNullValid Whether the data is entered(null), in the case of database, not null constraint N/A
NumberValid Whether the entered data is numeric Types.INTEGER
How to Use
The seventh argument for the parameter of “FieldDescriptor” class can be entered.
Not only supported validators, but also validators that users are willing to have can be implemented by using abstract class inheritance.
You can see the automatic UI creation example near the validator of ObjectType declaration part explained earlier.

FieldAttribute Use

  • The fifth argument for the parameter of “FieldDescriptor” class can be entered.
  • It explains a few properties of Field Descriptor.
  • It is optional information that handles each SQL column separately by Type class (Access permission: Saving not allowed, update not allowed as well)

Attribute Keys

Key Value Description Example
Default Initial value when creating InputForm new FieldAttribute("default", "male"))
Size Maximum number of length of entered component allowed new FieldAttribute("size", new Integer(10))
Hidden Hidden fields. When creating InputForm, it is not shown. In most cases, display values after processing. The second argument of the object is initially displayed new FieldAttribute("hidden", "test")
Mandatory Required entry fields. With a red triangle, it can be recognized new FieldAttribute("mandatory", new Boolean(true))
Source For SQL processing, already written default strings are used. Database server date (sysdate) or sorting expressions can be used directly. new FieldAttribute("source", "sysdate")
Dontcare It can be ignored new FieldAttribute("dontcare", new Boolean(true))

※ Only object types allowed, primitive types such as int, char, and boolean should not be entered. In the case of primitive int type, the following way can be used for this case. new Integer(value). - Data delivery to Inputter (After initializing, data can be passed to InputForm)

public static void main(String args[]) throws Exception{

  // Create a table. In the case of database, ‘create’ statement
  Type  AddressBook= new Type (
    "AddressBook= ",        // table name
                         //  column    type   size
    new FieldDescriptor[]{
      new FieldDescriptor(“PERSONNAME”,”user name”, 0 , false,
        new FieldAttribute[]{
           new FieldAttribute("default", new String('pongsor')),	
           new FieldAttribute("size", new Integer(10))              
        },
      ),
      new FieldDescriptor(“AGE”,”age”, 0,false
        new FieldAttribute[]{
           new FieldAttribute("default", new String('1')),	
        }
      )
    }
  );
}

At this chapter, we learn how to apply Metaworks explained chapter 5.4 to uEngine Process Designer and customize it.

ActivityType Design Time Customizing

In Activity Type, we simply make changes by using Metaworks with Inputters. With the following codes, a DriverClass can be selected in SqlSampleActivity rather than typing. Especially “metaworksCallback_changeMetadata” method is working with properties generated through setter/getter. The properties can be changed with the selected DriverClass.

public class SQLSampleActivity extends DefaultActivity {

	//Activity Property definition /////////////////////////////
	//----------------------------------------------------------
	
	public static void metaworksCallback_changeMetadata (Type type){
		FieldDescriptor fd;
		
		// Property name argument that needs changes
fd = type.getFieldDescriptor("DriverClass");
//Data type that needs changes
		fd.setInputter(new SelectInput(new String[]{"Oracle","MS-Sql","HyperSonic"}));
		
		type.setName("SqlSampleActivity");
	}	
	TextContext sqlStmt;	
		public TextContext getSqlStmt(){
			return sqlStmt;
		}			
		public void setSqlStmt(TextContext value){
			sqlStmt = value;
		}	
	
	String connectionString;	
		public String getConnectionString(){
			return connectionString;
		}
		public void setConnectionString(String value){
			connectionString = value;
		}
	
	String userId;	
		public String getUserId(){
			return userId;
		}
		public void setUserId(String value){
			userId = value;
		}
	
	String password;	
		public String getPassword(){
			return password;
		}
		public void setPassword(String value){
			password = value;
		}
		
	String driverClass;	
		public String getDriverClass(){
			return driverClass;
		}
		public void setDriverClass(String value){
			driverClass = value;
		}
	public SQLSampleActivity(){
                   setName(“SQLSampleActivity”);
}
	
	public void executeActivity(ProcessInstance instance) throws Exception{
                  //Execution parts
                  //Console shows that “this is SQLSampleActivity”
		System.out.print(“This is SQLSampleActivity.”);
	}
}


Figure 17. Input Type Changed Screen of Activity Type
Figure 17. Input Type Changed Screen of Activity Type


Process Variable Object Extensibility

In order to customize the “Process Variable” declaration screen, it is the same way that Activity Type does. The properties that you are willing to have can be added through setter/getter. Input types are also applied by using metaworksCallback_changeMetadata method. You can find “ProcessVariable” class in org.uengine.kernel package, so the following codes should be added.

  1. ProcessVariable.java
…
//metaworksCallback_changeMetadata
fd = type.getFieldDescriptor("ExtValue1");
		fd.setInputter(new RadioInput(new String[]{"a","b","c"}));	
}     
//setter/getter
String extValue1;
		public String getExtValue1() {
			return extValue1;
		}
		public void setExtValue1(String extValue1) {
			this.extValue1 = extValue1;
		}
…

Ways to test the changes

  1. Execute “ant” command in src directory where updated ProcessVariable class is placed.
  2. Restart the server.
  3. Run Process Designer.
  4. Click “Variable Declaration” in Process Designer.
  5. Click the “New” button, the following UI screen shown below appears.


Figure 18. Process Variable Configuration Screen
Figure 18. Process Variable Configuration Screen


Role Object Extensibility

Let us make changes on role mapping configuration screen. The following codes should be added into Role class in org.uengine.kernel package. When the selected person is not able to complete the assigned work, with the reason of sick leave, out of office, or many more, another person can continue the assigned work instead of the other person originally assigned. At this situation, we can make use of “delegatorUser” function.

  1. Role.java
…
//metaworksCallback_changeMetadata
fd = type.getFieldDescriptor("DelegatorUserId");
		fd.setInputter(new XMLValueInput("/usermanager/organizationChartXML.jsp"));
	}
//setter/getter
	String delegatorUserId;
		public String getDelegatorUserId() {
			return delegatorUserId;
		}
		public void setDelegatorUserId(String delegatorUserId) {
			this.delegatorUserId = delegatorUserId;
		}
…

Pay attention to setInputter region. We will see that “organizationChartXML.jsp” is an argument that retrieves user information and converts it in XML format, finally loads into inputter. In addition to that, we could also customize the jsp according to user information obtained from database.


Figure 19. Role Mapping Change
Figure 19. Role Mapping Change


Tips. Run the ‘Process Designer’ test via eclipse.

  1. Run the uEngine server.
  2. Hit the ‘Run’ button on eclipse.
  3. Add “ProcessDesigner” for the “Run” profile.
  4. Enter “-Dbpm_port=8080 -Dbpm_host=localhost” as a VM argument.
  5. Click “Run” button and Choose “ProcessDesigner”.
  6. Click “Participate” button in ProcessDesigner.
  7. Doublecheck whether it is correctly added by clicking “New” button on the top of the screen.


Figure 20. eclipse Run Configuration Screen
Figure 20. eclipse Run Configuration Screen


[Note] 5.5.3. For more examples, please see Appendix F 5.5.3.

Appendix A - ProcessManagerRemote API Reference

initialize process manager –Process Start related APIs

File nameOrg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String initialize(String defVerId, String instanceId, RoleMapping loggedRoleMapping) throws RemoteException;
PurposeMake processManager initialzed. This command conducts that if instanceID is returned with null, with initializeProcess functionaility, processInstance is created, returns ID value. ( same as initializeProcessIfRequired function)
Parameters
  • defVerId - definition version’s ID value
  • instanceId – instance’s ID value
  • loggedRoleMapping – contains role mapping information, RoleMapping object
Return ValuesInstance’s ID value
ExampleinstanceId = initialize(“100”, instanceId,rolemapping);


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String initializeProcess(String defVerId, String instanceName) throws RemoteException;
PurposeCreate a Process Definition instance of a corresponding defVerID
Parameters
  • defVerId - definition version’s ID value
  • instanceName – instance’s name.
Return ValuesInstance’s ID value
Example


File nameOrg.uengine.processmanager.ProcessManagerRemote
Method namepublic String initializeProcess(String defVerId) throws RemoteException;
PurposeInitialize process.
Parameters
  • defVerId - definition version’s ID value
Return ValuesInstance’s ID value
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String initializeProcessIfRequired(String defVerId, String instanceId) throws RemoteException;
PurposeIf instanceId is null, returns instanceid after initializing process.( check initialize)
Parameters
  • defVerId - definition version’s ID value
  • instanceId – instance’s ID value
Return ValuesInstance’s ID value
Example

process execution – Process Execution related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void executeProcess(String instanceId) throws RemoteException;
PurposeStart Executing ProcessInstance of a corresponding instanceID
Parameters
  • instanceId – instance’s ID value
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void executeProcess(String instanceId) throws RemoteException;
PurposeStart Executing ProcessInstance of a corresponding instanceID
Parameters
  • instanceId – instance’s ID value
  • resultPayload – resultPayload gets loaded with Process Variable Changes or Additions when executing processInstance.
Return ValuesNo returns(void)
Example

resultPayload.setExtendedValues(new KeyedParameter[]{

new KeyedParameter("TASKID", taskId)});

process variable – Process Variable related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setProcessVariable(String instanceId, String scope, String varKey, Serializable val) throws RemoteException;
PurposeProcess Variable Configuration
Parameters
  • instanceId – instance’s ID value
  • scope – always empty strings entered (Not implemented yet)
  • varKey – process variable name.
  • Val – Returns the values of variables serialized.
Return ValuesNo returns(void)
Example

resultPayload.setExtendedValues(new KeyedParameter[]{

new KeyedParameter("TASKID", taskId)});


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable getProcessVariable(String instanceId, String scope, String varKey) throws RemoteException;
PurposeGets process variable values
Parameters
  • instanceId – instance’s ID value
  • scope - always empty strings entered (Not implemented yet)
  • varKey – process variable name
Return ValuesNo returns(void)
Example

Returns the values of variables serialized.


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessVariableInXML(String instanceId, String scope, String varKey) throws RemoteException;
PurposeGets process variable values
Parameters
  • instanceId – instance’s ID value
  • scope - always empty strings entered (Not implemented yet)
  • varKey – process variable name
Return ValuesConverts values into XML string type.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Hashtable listProcessVariableValues(String instanceId) throws RemoteException;
PurposeGets all the process variables of a corresponding instanceId
Parameters
  • instanceId – instance’s ID value
Return ValuesReturns process variables in Hashtable
Example

role – Role related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void putRoleMapping(String instanceId, String roleName, String endpoint) throws RemoteException;
PurposeAssign the people for the role by a corresponding instanceId. Already assigned workitems can not be applicable to this assignment.
Parameters
  • instanceId – instance’s ID value
  • roleName – Role name
  • endpoint – user endpoint values
Return ValuesReturns process variables in Hashtable
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void putRoleMapping(String instanceId, RoleMapping roleMapping) throws RemoteException;
PurposeAssign the people for the role by a corresponding instanceId. Already assigned workitems can not be applicable to this assignment.
Parameters
  • instanceId – instance’s ID value
  • roleMapping – RoleMapping object that contains role mapping information
Return ValuesReturns process variables in Hashtable
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void delegateRoleMapping(String instanceId, String roleName, String endpoint) throws RemoteException;
PurposePass the tasks to new people selected by a corresponding instanceId. Already assigned all the workitems can be passed to the new people for the role(Role Delegation).
Parameters
  • instanceId – instance’s ID value
  • roleName – role name
  • endpoint – user’s endpoint value
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void delegateRoleMapping(String instanceId, RoleMapping roleMapping) throws RemoteException;
PurposePass the tasks to new people selected by a corresponding instanceId. Already assigned all the workitems can be passed to the new people for the role(Role Delegation).
Parameters
  • instanceId – instance’s ID value
  • roleMapping – RoleMapping object that contains role mapping information
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getRoleMapping(String instanceId, String roleName) throws RemoteException;
PurposeGet the person for the role whose ID matches a corresponding instanceId
Parameters
  • instanceId – instance’s ID value
  • roleName – role name
Return ValuesReturns RoleMapping object
Example

Messaging, triggering, event, workitem handling related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable sendMessage(String instanceId, String message, Serializable payload) throws RemoteException;
PurposeDeliver messages to BPM Server via WebServices.
Parameters
  • instanceId – instance’s ID value
  • Message – The contents that delivered to the recipient.
  • Payload
Return ValuesThe data delivered to the recipient
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable sendMessageXML(String instanceId, String message, String payload) throws RemoteException;
Purpose
Parameters
  • instanceId – instance’s ID value
  • Message – The contents that delivered to the recipient.
  • Payload
Return ValuesThe data delivered to the recipient
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void completeWorkitem(String instanceId, String tracingTag, String taskId, ResultPayload payload) throws RemoteException;
PurposeCompletes workitems, which belongs to a corresponding instanceid. Keep proceeding if next step of the task exists.
Parameters
  • instanceId – instance’s ID value
  • tracingTag – Current activity tracing tag value
  • taskId – workItem’s taskId value
  • resultPayload – resultPayload gets loaded with Process Variable Changes or Additions when executing processInstance.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void saveWorkitem(String instanceId, String tracingTag, String taskId, ResultPayload payload) throws RemoteException;
PurposeSaves workitems, which belongs to a corresponding instanceid. Stop proceeding even though next step of the task exists.
Parameters
  • instanceId – instance’s ID value
  • tracingTag – Current activity tracing tag value
  • taskId – workItem’s taskId value
  • resultPayload – resultPayload gets loaded with Process Variable Changes or Additions when executing processInstance.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void executeEventByWorkitem(String mainInstanceId, String eventName, ResultPayload resultPayload) throws RemoteException;
PurposeStarting tasks of Workitem Handler for event handler
Parameters
  • mainInstanceId – instanceId value of processInstance that uses event handler
  • eventName – event handler name.
  • resultPayload – resultPayload gets loaded with Process Variable Changes or Additions when executing processInstance.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void executeEventByWorkitem(String mainInstanceId, String eventName, String triggerActivityTracingTag, ResultPayload resultPayload) throws RemoteException;
PurposeStart processing workitem handlers for event handler
Parameters
  • mainInstanceId – instanceId value of processInstance that uses event handler
  • eventName – event handler name.
  • triggerActivityTracingTag
  • resultPayload – resultPayload gets loaded with Process Variable Changes or Additions when executing processInstance.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String[] delegateWorkitem(String instanceId, String tracingTag, RoleMapping roleMapping) throws RemoteException;
Purposedelegates the people for the workitem by a corresponding instanceId. Only one workitem can be passed on to the new person. delegateRoleMapping is for changing the people for the role, while, delegateWorkitem is for delegating workitem only to the new person.

The function comparison for assigning people to task roles (O: delegation is possible, X: delegation is not possible). Works processed previously can not be delegated to others.

Works that currently in progress Works that need to be processed
delegateRolemmaping() O O
putRolemmaping() X O
delegateWorkitem() O X
Parameters
  • instanceId – instance’s ID value
  • tracingTag – Current activity tracing tag value
  • taskId – workItem’s taskId value
  • resultPayload – resultPayload gets loaded with Process Variable Changes or Additions when executing processInstance.
Return ValuesNo returns(void)
Example

Delegated people’ endpoints

Messaging, triggering, event, workitem handling related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable sendMessage(String instanceId, String message, Serializable payload) throws RemoteException;
PurposeDeliver messages to BPM Server via WebServices.
Parameters
  • instanceId – instance’s ID value
  • Message – The contents that delivered to the recipient.
  • Payload
Return ValuesThe data delivered to the recipient
Example

flow control – Activity Flow Control related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void flowControl(String command, String instanceId, String tracingTag) throws RemoteException;
PurposeCurrent stage(Activity) moves to a pointed stage by flowControl. For instance, backActivity is used to return back to the pointed stage.
Parameters
  • command – It is used for flow control.
suspend It stops
resume Returns back to where it was
skip Skip the stage
compensate Go back to previous stage
compensate to Go back to the pointed stages

< table. Command’s Types >

  • instanceId – instance’s ID value
  • tracingTag – tracing tag where it moves to
Return ValuesNo returns(void)
Example

pm.flowControl("resume”, instanceId, "3");


process definition – Process Definition related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String addProcessDefinition(String name, int version, String description, boolean isAdhoc, String strDef, String folder, String defId, String alias) throws RemoteException;
PurposeAdd a new definition
Parameters
  • name - definition's name
  • version - Added definition's version
  • description - Additional detailed description for definition
  • isAdhoc -
  • strDef - definition's definition description.
  • Folder - The saving directory location
  • defId - definition's ID.
  • Alias - recognizable strings that show definition.
Return ValuesReturn VersionId of definition
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String addProcessDefinition(String name, int version, String description, boolean isAdhoc, String strDef, String folder, String defId, String objectType, String alias) throws RemoteException;
PurposeAdd a new definition
Parameters
  • name - definition's name
  • version - Added definition's version
  • description - Additional detailed description for definition
  • isAdhoc -
  • strDef - definition's definition description.
  • Folder - The saving directory location
  • defId - definition's ID.
  • Alias - recognizable strings that show definition.
  • objectType - definition's type (process, form …etc).
Return ValuesReturn VersionId of definition
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String addProcessDefinition(String name, int version, String description, boolean isAdhoc, String strDef, String folder, String defId, String objectType, String alias,String superDefId) throws RemoteException;
PurposeAdd a new definition
Parameters
  • name - definition's name
  • version - Added definition's version
  • description - Additional detailed description for definition
  • isAdhoc -
  • strDef - definition's definition description.
  • Folder - The saving directory location
  • defId - definition's ID.
  • Alias - recognizable strings that show definition.
  • objectType - definition's type (process, form …etc).
  • superDefId - parent definition's ID.
Return ValuesReturn VersionId of definition
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String addProcessDefinition(String name, int version, String description, boolean isAdhoc, ProcessDefinition def, String folder, String defId) throws RemoteException;
PurposeAdd a new definition
Parameters
  • name - definition's name
  • version - Added definition's version
  • description - Additional detailed description for definition
  • isAdhoc -
  • strDef - definition's definition description.
  • Folder - The saving directory location
  • defId - definition's ID.
Return ValuesReturn VersionId of definition
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void removeProcessDefinition(String defVerId) throws RemoteException;
PurposeRemove definition of VersionId
Parameters
  • defVerId - definition's VersionId value
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void renameProcessDefinition(String pdName, String newName) throws RemoteException;
PurposeChange definition’s name
Parameters
  • pdName - definition's name before change
  • newName - definition's name after change.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessDefinitionIdByAlias(String alias) throws RemoteException;
PurposeGet definitionId by a corresponding alias
Parameters

Alias - recognizable strings that show definition.

Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setVisibleProcessDefinition(String defId, boolean isVisible) throws RemoteException;
PurposeControl display (show/hide) for definitions in Definition tree.
Parameters
  • defId - definition's ID.
  • isVisible - (be displayed:true, hidden:false).
Return ValuesNo returns(void)
Example

getProcessDefinitionRemote- Process Definition Collection related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote[] listProcessDefinitionRemotesLight() throws RemoteException;
PurposeGet all the process definitions created
Parameters
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote[] findAllVersions(String defId) throws RemoteException;
PurposeGet all definitions and versions by a corresponding definitionID
Parameters
  • defId – definition’s ID value
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote getProcessDefinitionRemote(String defVerId) throws RemoteException;
PurposeGet all definitions by a corresponding VersionId
Parameters
  • defVerId – VersionId’s value of definition
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example

getProcessDefinitionRemote- Process Definition Collection related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote[] listProcessDefinitionRemotesLight() throws RemoteException;
PurposeGet all the process definitions created
Parameters
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote[] findAllVersions(String defId) throws RemoteException;
PurposeGet all definitions and versions by a corresponding definitionID
Parameters
  • defId – definition’s ID value
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote getProcessDefinitionRemoteByDefinitionId(String defId) throws RemoteException;
PurposeGet a definition by a corresponding definitionID
Parameters
  • defId – definition’s ID value
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinitionRemote getProcessDefinitionRemoteWithInstanceId(String instanceId) throws RemoteException;
PurposeGet a definition by a corresponding instanceId
Parameters
  • instanceId – instance’s ID value
Return ValuesReturn with an array type of ProcessDefinitionRemote
Example


production version – Version related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProductionVersionIdAtThatTime(String defId, Date thatTime) throws RemoteException;
PurposeGet definition’s VersionId by a corresponding definitionId that published into production
Parameters
  • defId - definition's ID value
  • thatTime - Production Date
Return ValuesReturn VersionId of definition.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getFirstProductionVersionId(String defId) throws RemoteException;
PurposeGet definition’s VersionId by a corresponding definitionId that originally published into production.
Parameters
  • defId - definition's ID value
Return ValuesReturn VersionId of definition.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessDefinitionProductionVersionByAlias(String alias) throws RemoteException;
PurposeGet definition’s VersionId by a corresponding alias that published into production.
Parameters
  • defId - definition's ID value
Return ValuesReturn VersionId of definition.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setProcessDefinitionProductionVersion(String pdvid) throws RemoteException;
PurposeSet definition into production by definition VersionId
Parameters
  • defVerId - definition's VersionId value
Return ValuesReturn property value that is Serializable type
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessDefinitionProductionVersion(String defId) throws RemoteException;
PurposeGet version of definition in production by definitionId
Parameters
  • defId - definition's ID value
Return ValuesReturn String type production version
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessDefinitionProductionVersionByName(String pdName) throws RemoteException;
PurposeGet version of name definition in production by a corresponding definition.
Parameters
  • defId - definition's ID value
Return ValuesReturn String type production version
Example

get ProcessDefinition - Process Definition Collection related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinition getProcessDefinition(String defVerId) throws RemoteException;
PurposeGet a definition by a corresponding definition VersionId.
Parameters
  • defVerId - definition's VersionId value
Return ValuesReturn ProcessDefinition object type
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessDefinition(String defVerId, String encodingStyle) throws RemoteException;
PurposeGet a definition's definition description by a corresponding definition VersionId.
Parameters
  • defVerId - definition's VersionId value
  • encodingStyle - encoding style
Return ValuesReturn String type definition description of definition
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessDefinition getProcessDefinitionWithInstanceId(String instanceId) throws RemoteException;
PurposeGet a definition that belongs to a corresponding instanceId
Parameters
  • instanceId - instance's ID value
Return ValuesReturn ProcessDefinition object type.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getProcessDefinitionWithInstanceId(String instanceId, String encodingStyle) throws RemoteException;
PurposeGet a definition that belongs to a corresponding instanceId
Parameters
  • defVerId - definition's VersionId value
  • encodingStyle - encoding style
Return ValuesReturn String type definition description of definition
Example

get Resource - Resource Collection related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getResource(String resourceId) throws RemoteException;
PurposeGet definition description of a definition that belongs to a corresponding definition VersionId

Difference between getProcessDefinition and this is that definition is in use except for process

Parameters
  • defVerId - definition's VersionId value
  • encodingStyle - encoding style
Return ValuesReturn String type definition description of definition
Example From formActivity… String html = pm.getResource(prodVerId);

get ProcessInstanceRemote - Process Operation(instance) Information Collection related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessInstanceRemote[] listProcessInstanceRemotes() throws RemoteException;
PurposeReturn all processInstances.
Parameters
Return ValuesReturn an array type of ProcessInstanceRemote.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessInstanceRemote[] listProcessInstanceRemotes(String defId) throws RemoteException;
PurposeReturn a processInstance by a corresponding definitionId.
Parameters* defId - definition's ID value
Return ValuesReturn an array type of ProcessInstanceRemote.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessInstanceRemote[] listProcessInstanceRemotes(String defId, String status) throws RemoteException;
PurposeReturn a corresponding status of processInstance by a definitionId
Parameters
  • defId - definition's ID value
  • Status - processInstance's status value
Return ValuesReturn an array type of ProcessInstanceRemote.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessInstanceRemote[] listProcessArchiveRemotes() throws RemoteException;
PurposeReturn a corresponding status of processInstance by a definitionId
Parameters
Return ValuesReturn an array type of ProcessInstanceRemote.
Example


process instance - Process Operation (instance) related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void removeProcessInstance(String instanceId) throws RemoteException;
PurposeRemove processInstance by a corresponding instanceId.
Parameters
  • instanceId - processInstance's ID value
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void stopProcessInstance(String instanceId) throws RemoteException;
PurposeMake a corresponding processInstance stop.
Parameters
  • instanceId - processInstance's ID value
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ProcessInstance getProcessInstance(String instanceId) throws RemoteException;
PurposeGet processInstance object by a corresponding instanceId
Parameters
  • instanceId - processInstance's ID value
Return ValuesReturs ProcessInstance object.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setProcessInstanceInfo(String instanceId, String info) throws RemoteException;
PurposeEnter additional descriptions into processInstance by a corresponding instanceId.
Parameters
  • instanceId - processInstance's ID value
  • Info - Additional description.
Return ValuesReturn ProcessInstance object.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setProcessInstanceStatus(String instanceId, String status) throws RemoteException;
PurposeEnter additional descriptions into processInstance by a corresponding instanceId.
Parameters
  • instanceId - processInstance's ID value
  • status - processInstance status value
Return ValuesNo returns(void)
Example

Activity- Activity related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable getActivityProperty(String defVerId, String tracingTag, String propertyName) throws RemoteException;
PurposeGet Activity properties of tracking tag that belongs to definition VersionId's definition.

The definition here is an initial value that an instance is not yet created.

Parameters
  • defVerId - definition's VersionId value
  • tracingTag - Activity's tracingTag.
  • propertyName - Property name.
Return ValuesReturn Serializable type of property value.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String getActivityStatus(String instanceId, String tracingTag) throws RemoteException;
PurposeGet tracingTag Activity status value of instanceId that belongs to definition.
Parameters
  • defVerId - definition's VersionId value
  • tracingTag - Activity's tracingTag value
Return ValuesReturn String type of status value.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Hashtable getActivityDetails(String defVerId, String tracingTag) throws RemoteException;
PurposeGet tracingTag Activity status value of definition VersionId that belongs to definition.
Parameters
  • defVerId - definition's VersionId value
  • tracingTag - Activity's tracingTag value
Return ValuesReturn property value stored in Hashtable.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic HashMap getInitiationParameterMap(String pvdid) throws RemoteException;;
PurposeGet Activity Parameters of the first human work in the first stage of definition.
Parameters
  • defVerId - definition's VersionId value
  • tracingTag - Activity's tracingTag value
Return ValuesReturn String type of status value.
Example

ActivityInstanceProperty- Activity Property related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Hashtable getActivityInstanceDetails(String instanceId, String tracingTag) throws RemoteException;
PurposeGet tracingTag Activity property value of definition in which instanceId belongs
Parameters
  • defVerId - definition's VersionId value
  • tracingTag - Activity's tracingTag value
Return ValuesReturn property value stored in Hashtable.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable getActivityInstanceProperty(String instanceId, String tracingTag, String propertyName) throws RemoteException;
PurposeGet Activity properties of tracking tag that belongs to instanceId's definition.

The property value here is that the setting value when instance is executed. it also affects a corresponding instance.

Parameters
  • instanceId - processInstance's ID value
  • tracingTag - Activity's tracingTag.
  • propertyName - Property's name.
Return ValuesReturn Serializable type of property value.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setActivityInstanceProperty(String instanceId, String tracingTag, String propertyName, Serializable value) throws RemoteException;
PurposeSet Activity properties of tracking tag that belongs to instanceId's definition.

The property value here is that the setting value when instance is executed. it also affects a corresponding instance.

Parameters
  • instanceId - processInstance's ID value
  • tracingTag - Activity's tracingTag.
  • propertyName - Property's name.
  • Value - Property value.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setActivityInstanceProperty(String instanceId, String tracingTag, String propertyName, Serializable value, Class valueType) throws RemoteException;
PurposeSet Activity properties of tracking tag that belongs to instanceId's definition.

The property value here is that the setting value when instance is executed. it also affects a corresponding instance.

Parameters
  • instanceId - processInstance's ID value
  • tracingTag - Activity's tracingTag.
  • propertyName - Property's name.
  • Value - Property value.
  • valueType - value's objectType
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Serializable doActivityAction(String instanceId, String tracingTag, String actionName, Serializable[] parameters, Class[] parameterTypes) throws RemoteException;
PurposeThis function is useful when creating activity parameters remotely in EJB mode.
Parameters
  • instanceId - processInstance's ID value
  • tracingTag - Activity's tracingTag.
  • actionName - Action's name.
  • parameters - Parameters' values.
  • parameterTypes - parameter values' object types
Return ValuesNo returns(void)
Example

Ways to set up Activity's Parameters
<in- process way>
ProcessDefinition pd = pm.getProcessDefinition("100");
Activity act = pd.getActivity("2");
HumanActivity ha = (HumanActivity)act;
Ha.createParameter(instance);

<remote way >
Pm.doActivityAction("1","2","createParameter",new serializable[]{…..},new Class[]{….})


Import and export- Process Definition Download related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void exportProcessDefinitionbyDefinitionId(String defId, boolean allVersion) throws Exception;
PurposeDownload process definitions by a corresponding definitionId.
Parameters
  • defId - definition's ID value
  • allVersion - Chooses whether all process versions need download or only production version.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void exportProcessDefinitionbyVersionId (String defVerId) throws Exception;
PurposeDownload process definitions by a corresponding definition VersionId.
Parameters
  • defVerId - definition Version's ID value
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Vector importProcessDefinition(String parentFolder, InputStream loadedZipFile, UEngineArchive editedUa, String[] command ) throws Exception;
PurposeLoad exported process definition files.
Parameters
  • parentFolder - Folder ID that needs import.
  • loadedZipFile - exported process definition files
  • editedUa - property updated process definition.
  • Command - import command type (add, update)
Return ValuesReturn imported process definitionIds.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Hashtable importProcessAliasCheck(InputStream is) throws Exception;
PurposeCheck process definition or configuration files that need import
Parameters
  • is - zip file that needs import
Return ValuesReturn imported process definitionIds.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic Hashtable importProcessAliasCheck(InputStream is) throws Exception;
PurposeCheck process definition or configuration files that need import
Parameters
  • is - zip file that needs import
Return ValuesReturn imported process definitionIds.
Example

flow chart - Flowchart related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String viewProcessDefinitionFlowChart(String defVerId, Map options) throws RemoteException;
PurposeGet the flowchart of definition by a corresponding definition VersionId.
Parameters
  • defVerId - definition Version's ID value
  • Options - options for configuring chart.
Return ValuesReturn string type of flowchart value.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String viewProcessInstanceFlowChart(String instanceId, Map options) throws RemoteException;
PurposeGet the flowchart of definition by a corresponding instanctId.
Parameters
  • instanceId - processInstance's ID value
  • Options - options for configuring chart.
Return ValuesReturn string type of flowchart value.
Example

folder - Folder related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void removeFolder(String folderName) throws RemoteException;
PurposeRemove folders by a corresponding folder name.
Parameters
  • folderName - folder name.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic String addFolder(String folderName, String parentFolder) throws RemoteException;
PurposeCreate a child folder under parent folder with the same name of a corresponding folder name
Parameters
  • folderName - folder name.
  • parentFolder - parent folder ID
Return ValuesReturn created folder ID.
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void moveFolder(String defId, String parentFolder) throws RemoteException;
PurposeMove a corresponding folder into parent folder.
Parameters
  • defId - folder ID.
  • parentFolder - parent folder ID
Return ValuesReturn created folder ID.
Example


dynamic change - Change Management related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void changeProcessDefinition(String instanceId, String definitionInXML) throws RemoteException;
PurposeUpdate definition of executing instanceID.
Parameters
  • instanceId - processInstance's ID value
  • definitionInXML - ProcessDefinition defined in XML
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void changeProcessDefinition(String instanceId, ProcessDefinition definition) throws RemoteException;
PurposeUpdate definition of executing instanceID.
Parameters
  • instanceId - processInstance's ID value
  • definition - ProcessDefinition's object
Return ValuesNo returns(void)
Example


Test - Process Handling related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setFault(String instanceId, String tracingTag, Exception fault) throws RemoteException;
PurposeSet exception handling for tracingTag's Activity of a corresponding instanceId.
Parameters
  • instanceId - processInstance's ID value
  • tracingTag - Activity's tracingTag value
  • fault - Exception object
Return ValuesNo returns(void)
Example

signaling all the changes can be applied - Change Handling related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void applyChanges() throws RemoteException;
PurposeSubmit updated contents to the server and applies.
Parameters
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void cancelChanges() throws RemoteException;
PurposeCancel to apply updated contents.
Parameters
Return ValuesNo returns(void)
Example


user can pass some parameters into the kernel - Login Information Processing related APIs

File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setGenericContext(Map genericContext) throws RemoteException;
PurposeSubmit special information to the server.
Parameters
  • genericContext - information that needs submission to the server

ex) request, respose, loggedRoleMapping

Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic void setLoggedRoleMapping(RoleMapping roleMapping) throws RemoteException;
PurposeSet up rolemapping of logged in users.
Parameters
  • roleMapping - RoleMapping's object, it contains rollmapping information of logged in users.
Return ValuesNo returns(void)
Example


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic EventHandler[] getEventHandlersInAction(String instanceId) throws RemoteException;
PurposeGet event handlers that can be invoked for definition by a corresponding instanceId.
Parameters
  • instanceId - processInstance's ID value
Return ValuesReturn an array type of event handler object, EventHandler.
Example Org.uengine.processmanager.ProcessManagerRemote


File nameorg.uengine.processmanager.ProcessManagerRemote.java
Method namepublic ActivityReference getInitiatorHumanActivityReference(String pdvid) throws RemoteException;
PurposeGet starting workitem handler references of defintion by a corresponding definition VersionId.
Parameters
  • pdvid - definition Version's ID value
Return ValuesReturn an object type of ActivityReference.
Example

Appendix B – Useful Examples that used APIs

For this time, we learn various customizing ways by using uEngine’s available APIs with a proposal process scenario that happens in a real company situation.


Example Titleorg.uengine.processmanager.ProcessManagerRemote.java
Creation Steps
  1. Process Modeling [Process Designer]
  2. Create DB tables
  3. Separate Activities[Proposal, View, WorkLists, Approval, Return, Refused] Task screen creation [Web(JSP) Programing]

Proposal Process

There are 2 steps for proposal process as shown in figure 21 that are a ‘Proposal Registration’ and a ‘Proposal Approval’. From Proposal Registration accepts the proposal contents. When the ‘Proposal Approval’ approves the proposal contents, it completes the process. However, if it returns, it will go back to the first step of the process, and repeat the same steps.


Figure 21. Proposal Process
Figure 21. Proposal Process


There are ‘regno’ and ‘approve’ process variables. ‘regno’ variable saves the sequential number of proposal contents, while ‘approve’ receives the result either ‘proposal approved’ or ‘proposal rejected, and it passes the result to switchActivity and then decides which one to follow and execute.

SAMPLE_PROPOSAL Table

Column Name Data TypeDescription
PROPOSAL_IDINTCreate a sequentially incremented ID
PROPOSAL_NMVARCHAR(100)Proposal name
CHARGE_NMVARCHAR(50)Person name in charge of the task
PROPOSAL_BACKGROUNDVARCHAR(1000)Proposal background
REG_IDVARCHAR(19)Register ID

Workitem Handler Customizing


WIH of Proposal Registration Activity consists of the entry screen where the content is entered by users, Proposal Approval Activity needs to develop a workitem handler that makes a decision whether the proposal is approved or rejected.

RegisterProposal
At this time, let us create a WIH for proposal registration Activity. Create this directory, ‘wih/proposal/registerProposal’ and locate a customized index.jsp file into the directory that we just created. As we learned from Process Definition part, there is rejection functionality in this Activity, therefore, the same entered information must be displayed in the stage of the task where it goes back to after rejection is made.

Figure 22. Proposal Registration Execution Screen
Figure 22. Proposal Registration Execution Screen
  1. index.jsp
<%@include file="../../wihDefaultTemplate/header.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="org.uengine.util.dao.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
//======================= Variable initialization ========================================//
// Gets ProcessManagerRemote object and process information in order to use APIs.

// Make use of APIs after getting ProcessManagerRemote object.
ProcessManagerRemote pm = processManagerFactory.getProcessManager();

//Gets instanceid in order to use APIs
	String instanceId = request.getParameter("instanceId");
         //Gets values in order to transmit the values to submit.jsp
	String definitionId = request.getParameter("processDefinition");
         //Gets tracingTag in order to check the status
	String tracingTag = request.getParameter("tracingTag");
	
// Variable declaration for proposal rejection. 
	String proposal_nm = "";
	String background = "";

         //Variable the boolean value whether process is being executed 
	boolean isRunning = true;

//========================= Due to the rejection, the same steps of tasks repeat =================================//
//if instanceid is not null,
//rejection contents must be displayed at the entry screen if rejection is made.
	if(instanceId!=null){
                  //API that helps us get ProcessInstance
		ProcessInstance instance = pm.getProcessInstance(instanceId);  

                  //API that helps us get status
		String status = pm.getActivityStatus(instanceId, tracingTag);
		
                  //Check the status whether it is in execution
		if(status!=null && !status.equals("Running") && !status.equals("Timeout")){
			isRunning = false;
		}

                  //API that helps us get regno process variable
		Number regno = (Number)pm.getProcessVariable(instanceId, "", "regno");
		
                  //Database SQL query by using IDAO class
                  //Codes needed for getting the rejection context of a corresponding regno
		IDAO dao = ConnectiveDAO.createDAOImpl(   
			instance.getProcessTransactionContext(),  
			"select * from sample_proposal where proposal_id = ?regno",   
			IDAO.class
		);
		
                  //Assign rejected proposal regno into proposal_id and execute the SQL query.
//assign values into ?regno part
		dao.set("regno", regno);
		dao.select();

                  //API that receives the values that obtailed after executing SQL query 
                  //if the rejection content exists, gets (dao.next()==true).
		if(dao.next()){
			proposal_nm = (String)dao.get("proposal_nm"); 
			background = (String)dao.get("proposal_background"); 
		}
	}

%>
//============================== User Interface ===========================================//
<h1>Proposal Registration </h1>
<p>
<form action="submit.jsp">

// Variables that will be sumitted to submit.jsp.
<input type=hidden value="<%=definitionId%>" name="processDefinition">
<input type=hidden value="<%=instanceId%>" name="instanceId">
<input type=hidden value="<%=tracingTag%>" name="tracingTag">

// displayed screen on users’ screens
Proposal Name: <input name="proposalName" value="<%=proposal_nm%>"><br>
Proposal Company : <input name="proposalCompanyName"><br>
Person in charge for the proposal : <input name="rightPersonName" value="<%=loggedUserFullName%>"><br>
The phone number of the person in charge: <input name="rightPersonPhone" value=""><br>
Proposal Background: <input name="background" value="<%=background%>"><br>
Service Summary: <input name="serviceDesc"><br>
<p>

//If the process is in execution, submit button will not be displayed 
<%
if (isRunning){%>
<input type=submit>
<%}%>

</form>
  1. submit
<%@include file="../../wihDefaultTemplate/header.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="javax.transaction.*, org.uengine.util.dao.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
//=========================== Variable Initialization ===========================================//
// Gets ProcessManagerRemote object and process information for using APIs
// gets ProcessManagerRemote object.
	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	
//process information received by index.jsp.
 //parameters for process initialization 
	String definitionId = request.getParameter("processDefinition");
          //completeWorkitem function parameters for completing woritem
	String tracingTag = request.getParameter("tracingTag");
          //Receives instanceid for using APIs.
	String instanceId = request.getParameter("instanceId");
	
// String(request.getParameter("proposalName").getBytes("8859_1"), "UTF-8") for proper Korean encoding
//Receives proposal name
	String proposal_nm = new String(request.getParameter("proposalName").getBytes("8859_1"), "UTF-8");
          //Receives the name of person in charge.
	String charge_nm = new String(request.getParameter("rightPersonName").getBytes("8859_1"), "UTF-8");
          //Receives the proposal background content
	String proposal_background = new String(request.getParameter("background").getBytes("8859_1"), "UTF-8");

	InitialContext context = new InitialContext();
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.
USERTRANSACTION_JNDI_NAME) : null);

	try{
//Start a transaction	
		if(tx!=null) tx.begin();		
//============================= Process initialization ============================================//
//necessary initialization work for process execution.

                    //Process Initialization
		instanceId = pm.initialize(definitionId, instanceId, loggedRoleMapping);
		
                    //use genericContext for submitting login information to the server
		Map genericContext = new HashMap();
		genericContext.put(HumanActivity.GENERICCONTEXT_CURR_LOGGED_ROLEMAPPING, loggedRoleMapping);
		genericContext.put("request", request);
		pm.setGenericContext(genericContext);
		
                    // API that helps us get ProcessInstance
		ProcessInstance instance = pm.getProcessInstance(instanceId);

//============================== enter proposal content into database ===============================//
                    // Variable for getting SEQ_PROPOSAL
		Number regno = new Long(0);
		
//execute SEQ_PROPOSAL
                    //gets the data of current regno value plus 1.
                    // regno value becomes proposal_id.
		IDAO dao = ConnectiveDAO.createDAOImpl(			
			instance.getProcessTransactionContext(),	
			"select NEXT VALUE FOR SEQ_PROPOSAL as regno from dual",
			IDAO.class
		);
		
		dao.select();
		if(dao.next())
			regno = (Number)dao.get("regno"); 
		
		//contents entered by users save into database.
		dao = ConnectiveDAO.createDAOImpl(
			instance.getProcessTransactionContext(),			
			"insert into SAMPLE_PROPOSAL( "+
			" proposal_id ,"+
			" proposal_nm ,"+
			" charge_nm ,"+
			" proposal_background ,"+
			" reg_id "+
			") values ("+
			" ?proposal_id,"+
			" ?proposal_nm ,"+
			" ?charge_nm ,"+
			" ?proposal_background ,"+
			" ?reg_id"+
			")",
			IDAO.class
		);
		
//Assign values into respective variables.
		dao.set("proposal_id", regno);
		dao.set("proposal_nm", proposal_nm);
		dao.set("charge_nm", charge_nm);
		dao.set("proposal_background", proposal_background);
		dao.set("reg_id", loggedUserId);
		
		dao.update();

                    //Passes regno value into Process variable.
		pm.setProcessVariable(instanceId, "", "regno", regno);
	          //Completes workitem.
		pm.completeWorkitem(instanceId, tracingTag, null, null);

                    //Applies any changes to the server
		pm.applyChanges();

		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

	%>
	<h1><font color=green>		This proposal is successfully accepted!!
	<%

	}catch(Exception e){
		e.printStackTrace();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();
		
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception e){}
	}
%>

signProposal
At this time, let us create a WIH for proposal acceptance Activity. Create this directory, ‘wih/proposal/ signProposal’ and locate customized index.jsp and submit files into the directory that we just created. At this proposal acceptance stage, the received proposal content completes when it is approved, otherwise, it goes back to the stage where the proposal registration form appeared.


Figure 23. Proposal Approval
Figure 23. Proposal Approval


  1. index.jsp
<%@include file="../../wihDefaultTemplate/header.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="org.uengine.util.dao.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
//===========================Variable initialization ======================================//

         //Gets instanceid in order to use APIs
	String instanceId = request.getParameter("instanceId");
         //definitionid that will be submitted to submit.jsp
	String definitionId = request.getParameter("processDefinition");
         //tracingTag that will be submitted to submit.jsp
	String tracingTag = request.getParameter("tracingTag");
          
         // Gets ProcessManagerRemote object for using APIs
	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
         // API function that gets ProcessInstance
	ProcessInstance instance = pm.getProcessInstance(instanceId);    
%>
//============================ User Interface ===================================//
<h1>Proposal Approval</h1>
<p>

<form action="submit.jsp">

//values that will be submitted to submit.jsp 
<input type=hidden value="<%=instanceId%>" name="instanceId">
<input type=hidden value="<%=definitionId%>" name="processDefinition">
<input type=hidden value="<%=tracingTag%>" name="tracingTag">

/* 
*  At proposal registration stage, regno value needed in order to display entered information 
*  regno value is obtained from the previous stage where the value is stored
*  Display the proposal registration content from database by a corresponding regno
*/
<%
                  //receives regno via Process Variable
		Number regno = (Number)pm.getProcessVariable(instanceId, "", "regno");
		
                  //Execute SQL query that helps us get corresponding information from database		
IDAO dao = ConnectiveDAO.createDAOImpl(  
			instance.getProcessTransactionContext(),   
			"select * from sample_proposal where proposal_id = ?regno",   
			IDAO.class
		);
		
		dao.set("regno", regno);
		dao.select();

	         String proposal_nm = "";
	         String background = "";
                  //if a corresponding data exists, take them.
		if(dao.next()){
			proposal_nm = (String)dao.get("proposal_nm"); 
			background = (String)dao.get("proposal_background"); 
		}

         //obtains rolemapping infromation
	RoleMapping user = pm.getRoleMappingObject(instanceId, "initiator");
%>
//Parts that are displayed on the screen
Proposal name: <%=proposal_nm%><br>
Proposal background: <%=background%><br>
BP person in charge: <%=user.getResourceName()%>

<hr>

Do you approve this proposal?
<input type=radio name="approve" value="yes">Approval
<input type=radio name="approve" value="no">Rejection

<p>

<input type=submit>

</form>

  1. submit
<%@include file="../../wihDefaultTemplate/header.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="javax.transaction.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
//============================ Variable initialization ======================================//
          // Gets ProcessManagerRemote object for using APIs
	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	
          //receives entered contents from index.jsp
	String instanceId = request.getParameter("instanceId");
	String definitionId = request.getParameter("processDefinition");
	String tracingTag = request.getParameter("tracingTag");
          //Variable that contains the proposal either approved or rejected
	String approve = request.getParameter("approve");
	
	InitialContext context = new InitialContext();

	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.
USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();		
//=============================== Process initialization and apply to the server =======================================//                   
                    //Initialization
		instanceId = pm.initialize(definitionId, instanceId, loggedRoleMapping); 

                    //pass the approval value that gets from index.jsp to process variables
                    //With this value, switchActivity decides which way it follows
		pm.setProcessVariable(instanceId, "", "approve", approve);

                    //Complete a workitem		
		pm.completeWorkitem(instanceId, tracingTag, null, null);

                    //Apply changes to the server
		pm.applyChanges();

		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

	%>
	<h1><font color=green>	The proposal is successfully <%="yes".equals(approve) ? "approved" : "rejected "%>!
	<%

	}catch(Exception e){
		e.printStackTrace();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();
		
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception e){}
	}
%>

Check Processes

At this time, we will make a page that has the functionality of checking workitems. In order to check the workitems, we need criterions, because users only need to see filtered workitems. Therefore, at present, we are making a proposal process, let us add necessary functions for the purpose.


Figure 24. Workitem List
Figure 24. Workitem List


As Figure 24 shows, there are 2 proposals listed, and 3 buttons are displayed on the bottom left side of the proposal list. These are “Dismiss”, “Reject”, and “Select people in charge”. “Dismiss” means that the selected proposals will be permanently removed from the workitem list. “Reject” proceeds the functionality that the first page of the process will appear, and repeat the process all over again. “Select people in charge” includes the functionality that currently assigned people in charge can be changed to other people. With this page implementation, workitems will be automatically displayed on the assigned workers. Therefore, listing criterions can be customized according to the assigned workers for the tasks.


workItemList

workItemList retrieves workitems and displays them on the user’s screen. For instance, we will create a special work list page that displays only workitems in the approval stage of the proposal process. We assume that the proposal process definition(defid) is 23 and the proposal approval tracingTag which is the second step of the process is 2. Create ‘uengine-web/proposal’ directory and save the following jsp file under the directory.

  1. proposalList.jsp
<%@include file="../common/header.jsp"%>		
<%@include file="../common/getLoggedUser.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="org.uengine.util.dao.*"%>

//================================ function declaration part ==========================================//
<script>
          //It executes a corresponding WIH on the new window after clicking the list.
	function viewTaskInfo( taskid, instanceId, tracingTag ){
		var option = "width=500,height=400,scrollbars=yes,resizable=yes";
                    ///workitemHandler.jsp is responsible for finding WIH and executing it.
		var url = "../processparticipant/worklist/workitemHandler.jsp?taskId="+taskid+"&instanceId="+instanceId+"&tracingTag
="+tracingTag;
		window.open(url, "wihspace", option)
	}
	
          //It works when the “Dismiss” button is pushed, the selected proposals will be removed from the list
	function dropInstance(){
		var instanceId="";
                    for(i=0; i<document.forms[0].selectedInstance.length; i++) {
                      If(document.forms[0].selectedInstance[i].checked==true) 
                        instanceId= document.forms[0].selectedInstance[i].value;
                    }		
		var option = "width=500,height=400,scrollbars=yes,resizable=yes";
		var url = "dropProposal.jsp?instanceId="+instanceId;
		window.open(url, "wihspace", option)
		
	}
          //When the “Reject” button is pushed, it returns to the previous stage of the process.
	function backInstance(){
		var instanceId="";
                    for(i=0; i<document.forms[0].selectedInstance.length; i++) {
                      If(document.forms[0].selectedInstance[i].checked==true) 
                        instanceId= document.forms[0].selectedInstance[i].value;
                    }		
		var option = "width=500,height=400,scrollbars=yes,resizable=yes";
		var url = "backProposal.jsp?instanceId="+instanceId;
		window.open(url, "wihspace", option)
		
	}
          //Changes the people in charge,  it executes roleMappingChangeForm.
	function setCharge(){
		var instanceId="";
                    for(i=0; i<document.forms[0].selectedInstance.length; i++) {
                      If(document.forms[0].selectedInstance[i].checked==true) 
                        instanceId= document.forms[0].selectedInstance[i].value;
                    }
			
		var option = "width=500,height=400,scrollbars=yes,resizable=yes";
		var url = "../processmanager/roleMappingChangeForm.jsp?instanceId="+instanceId+"&roleName=Initiator";
		window.open(url, "wihspace", option)
		
	}

</script>

//=============================== User Interface=================================//
<form>

<table border=1>
<tr>
<td>Select</td>	
<td>proposal_nm</td>	
<td>charge_nm</td>	
<td>starteddate</td>	
<td>info</td>	
<td>instid</td>	
<td>trctag</td>	
</tr>

<%
          //A query for retrieving the list, the query criteria is important.
          //Retrieve only worklists in progress after joining 3 different tables.
	IDAO dao = GenericDAO.createDAOImpl( 
		DefaultConnectionFactory.create(),			
		"select                                                 "+
		" sp.proposal_nm,                                       "+
		" sp.charge_nm,                                         "+
		" pi.starteddate,                                       "+
		" pi.info,                                              "+
		" pi.instid,                                            "+
		" wl.trctag,                                            "+
		" wl.taskid                                             "+
		"from                                                   "+
		" bpm_worklist wl,                                      "+
		" bpm_procinst pi,                                      "+
		" sample_proposal sp                                    "+
		"where                                                  "+
		" pi.defid = 23                                         "+
		" and wl.endpoint=?endpoint                             "+
		" and (wl.status='NEW' or wl.status='CONFIRMED')        "+
		" and wl.trctag=2                                       "+
		" and pi.instid = wl.instid                             "+
		" and pi.ext1 = sp.proposal_id				",
		IDAO.class                                               
	);      
	
          //assign logged in user id to endpoint.
	dao.set("endpoint", loggedUserId);
	dao.select();
	
          //displays workitems after  selecting the workitems
	while(dao.next()){
                    //proposal name
		String proposal_nm = dao.getString("proposal_nm");
                    //person in charge
		String charge_nm = dao.getString("charge_nm");
                    //proposal creation date
		Date starteddate = (Date)dao.get("starteddate");
                    //explains the stage that is being processed
		String info = dao.getString("info");
                    //instanceid
		Number instid = (Number)dao.get("instid");
                    //taskid
		Number taskId = (Number)dao.get("taskid");
                    //TracingTag
		String trctag = dao.getString("trctag");
	%>
<tr>
// construct the list
<td><input type=radio name="selectedInstance" value="<%=instid%>"></td>	
//A new window popup, and the task starts processing after the list is clicked
 <td><a href="javascript:viewTaskInfo( '<%=taskId%>', '<%=instid%>', '<%=trctag%>')"><%=proposal_nm%></a></td>	
<td><%=charge_nm%></td>	
<td><%=starteddate%></td>	
<td><%=info%></td>	
<td><%=instid%></td>	
<td><%=trctag%></td>	
</tr>
	
	<%	
	}
%>
// print out the button
</table>
	<input type=button onclick="dropInstance()" value="Dismiss">
	<input type=button onclick="backInstance()" value="Reject">
	<input type=button onclick="setCharge()" value="Select people in charge">
</form>

When executing this page, http://localhost:8080/uengine-web/proposal/proposalList.jsp, we are able to see the workitems that is in the approval stage. Additionaly, click one of proposal_nm column items, a new window appears and WIH is being executed on it. The reason can be explained by looking at “workitemHandler.jsp” file, the file searches a corresponding WIH and executes the WIH. Multiple ways of SQL query can be assumed, just design an appropriate one according to the situation.

Select people in charge The functionality of selecting people in charge for the tasks is useful when we want to change the current people to different people . It simply works by selecting one from the organization chart and clicking the “Select people in charge” button. After that, ‘roleMappingChangeForm’ is automatically executed. This is already implemented and the selected associates can be people in charge for the task, and instanceid and rolename must be passed to the page.


Figure 25. The screen of selecting people in charge
Figure 25. The screen of selecting people in charge


Rejection

This rejection is exactly working in the same way like the one we learned previously. For this time, we do not make use of process variables. However, we directly use APIs instead. Most of source codes are familiar, but for this time, we make use of flowControl function, and the third argument for the tracingtag parameter should be 1. After that, it goes back to the first stage of the process. The behavior is called “Rejection”.

  1. backProposal.jsp
<%@include file="../common/header.jsp"%>		
<%@include file="../common/getLoggedUser.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="javax.transaction.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
//================================== Variable initialization ============================================//
          //Get the ProcessManagerRemote object by using APIs.
	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
          //For flowcontrol’s second argument of instanceid parameter, we need the instanceid.
	String instanceId = request.getParameter("instanceId");
	
	InitialContext context = new InitialContext();
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();		
 //=============================== Conduct “Rejection” process ============================================//
                    //Proposal creation activity’s trcTag = 1                   
                    //For rejection, set the value of “trcTag” with 1.
		pm.flowControl("compensateTo", instanceId, "1");     // <<<<<<<<<<<<<<<<<<<<<<<<<<<<

		pm.applyChanges();

		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

	%>
	<h1><font color=green>		This proposal is successfully rejected!!
	<%

	}catch(Exception e){
		e.printStackTrace();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();
		
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception e){}
	}
%>

Dismission

The source codes of dismission are almost same as the rejection. Then only difference is that we use the stopProcessInstance function with an instanceid argument.

  1. dropProposal.jsp
<%@include file="../common/header.jsp"%>		
<%@include file="../common/getLoggedUser.jsp"%>		
<%@page pageEncoding="KSC5601"%>
<%@page import="javax.transaction.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
//==================================== Variable initialization ===========================================//
          // Get the ProcessManagerRemote object by using APIs.
	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	//get an instanceid for stopProcessInstance
	String instanceId = request.getParameter("instanceId");
	
	InitialContext context = new InitialContext();
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();		
//================================ Conduct proposal dismission ==========================================//
                    //dismiss the proposal by invoking “stopProcessInstance”.
		pm.stopProcessInstance(instanceId);

		pm.applyChanges();

		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

	%>
	<h1><font color=green>		This proposal is successfully dismissed!!
	<%

	}catch(Exception e){
		e.printStackTrace();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();
		
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception e){}
	}
%>

Appendix C – Sample Code

3.3. ProcessManager Interface Example #1. - initiateProcess.jsp

<%@include file="../common/header.jsp"%>
<%@page import="javax.transaction.*"%>

<LINK href="../style/uengine.css" type=text/css rel=stylesheet>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" /><%

	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	InitialContext context = new InitialContext();
	
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();
	
		String definitionName = decode(request.getParameter("definitionName"));
		String productionVersionId = pm.getProcessDefinitionProductionVersionByName(definitionName);
		String instanceId = pm.initializeProcess(productionVersionId);
		pm.applyChanges();
		
		try{
			tx.commit();
		}catch(Exception txe){
		}

%>
Process instance '<%=instanceId%>' has been successfully initialized.<p>
<%
	}catch(Exception e){
		try{
			pm.cancelChanges();
		}catch(Exception txe){
		}
	
		try{
			tx.rollback();
		}catch(Exception txe){
		}

		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception ex){
			System.out.println("error when to remove pm");
			ex.printStackTrace();
		}
	}

%>

3.3. ProcessManager Interface Example #2. - startProcess.jsp


<%@include file="../common/header.jsp"%>
<%@page import="javax.transaction.*"%>

<LINK href="../style/uengine.css" type=text/css rel=stylesheet>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" /><%

	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	InitialContext context = new InitialContext();
	
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();
	
		String instanceId = decode(request.getParameter("instanceId"));

		pm.executeProcess(instanceId);
		pm.applyChanges();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

%>
Process instance '<%=instanceId%>' has been successfully started.<p>
<%
	}catch(Exception e){
		try{
			pm.cancelChanges();
		}catch(Exception ex){
		}
	
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();

		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception ex){
		}
	}

%>

3.3. ProcessManager Interface Example #3. - initiateAndStartProcess.jsp

<%@include file="../common/header.jsp"%>
<%@page import="javax.transaction.*"%>

<LINK href="../style/uengine.css" type=text/css rel=stylesheet>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" /><%

	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	InitialContext context = new InitialContext();
	
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();
	
		String definitionName = decode(request.getParameter("definitionName"));
		String productionVersionId = pm.getProcessDefinitionProductionVersionByName(definitionName);
		String instanceId = pm.initializeProcess(productionVersionId);
		pm.executeProcess(instanceId);
		pm.applyChanges();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

%>
Process instance '<%=instanceId%>' has been successfully initialized and started.<p>
<%
	}catch(Exception e){
		try{
			pm.cancelChanges();
		}catch(Exception ex){
		}
	
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception ex){
		}
	}

%>

3.3. ProcessManager Interface Example #4. - getProcessVariable.jsp

<%@include file="../common/header.jsp"%>
<%@page import="javax.transaction.*"%>

<LINK href="../style/uengine.css" type=text/css rel=stylesheet>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" /><%

	ProcessManagerRemote pm = processManagerFactory.getProcessManagerForReadOnly();
	InitialContext context = new InitialContext();
	
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();
	
		String instanceId = decode(request.getParameter("instanceId"));
		String variableName = decode(request.getParameter("variableName"));

		Serializable value = pm.getProcessVariable(instanceId, "", variableName);


%>
The value is '<%=value%>'.<p>
<%
	}catch(Exception e){
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception ex){
		}
	}

%>

3.3. ProcessManager Interface Example #5. - setProcessVariable.jsp

<%@include file="../common/header.jsp"%>
<%@page import="javax.transaction.*"%>

<LINK href="../style/uengine.css" type=text/css rel=stylesheet>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" /><%

	ProcessManagerRemote pm = processManagerFactory.getProcessManager();
	InitialContext context = new InitialContext();
	
	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();
	
		String instanceId = decode(request.getParameter("instanceId"));
		String variableName = decode(request.getParameter("variableName"));
		String value = decode(request.getParameter("value"));

		pm.setProcessVariable(instanceId, "", variableName, value);

		pm.applyChanges();
		
		try{
			tx.commit();
		}catch(Exception txe){
		}

%>
Value has been set.<p>
<%
	}catch(Exception e){
		try{
			pm.cancelChanges();
		}catch(Exception txe){
		}
	
		try{
			tx.rollback();
		}catch(Exception txe){
		}

		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception ex){
		}
	}

%>

3.5.1 Activity Definition Class Reference Codes #1 - Activity.java


public abstract class Activity{
	1. Field Declaration

	Activity parentActivity ; 	// Parent Activity including itself (Usually it becomes ComplexActivity)
	String name;
	String tracingTag;	// It is distinguished among different activities by looking at unique tag value. 
	int retryLimit;	// No of times that it tried 
	int retryDelay;	// Amount of time used during retrying(second based)
	Role[] roles;		// Role declaration
	ProcessVariable[] processVariableDescriptors;	//Process variable declaration

1.	Constructor Declaration
	
	public Activity(){}	// An empty constructor for reflexion

2.	Logic Declaration
This part is implemented by developers or inherited. It is separately invoked when uEngine is executing. The working order follows createInstance,  beforeExecute, executeActivity, onEvent (if done), afterExecute.

	protected ActivityInstance createInstance(ActivityInstance instanceInCreating) throws Exception{
		return instanceInCreating;
	}
	protected void beforeExecute(ActivityInstance instance) throws Exception{}	
	abstract protected void executeActivity(ActivityInstance instance) throws Exception;
	protected void afterExecute(ActivityInstance instance) throws Exception{}
	protected void onEvent(String command, ActivityInstance instance, Object payload) throws Exception{}

3.	Callback Methods
Additionally, besides the basic logic declaration, necessary methods are invoked by management tools during uEngine execution.

	protected synchronized String getProcessStatus(ActivityInstance inst, String roleName){} // Returns the status
	
	public void stop(ActivityInstance instance) throws Exception{}		// Handle “Stop” request
	public void suspend(ActivityInstance instance) throws Exception{}	// Handle ‘Suspend’ request
	public void resume(ActivityInstance instance) throws Exception{}	// Handle ‘Resume’ request
	public void skip(ActivityInstance instance) throws Exception{}		// Handle ‘Skip’ request
	public void compensate(ActivityInstance instance) throws Exception{}	// Handle ‘Compensate’ request	
	public ActivityDesigner createDesigner(){}	// Returns GUI tool for current activity edition
	
	public Map getActivityDetails(ActivityInstance inst){// Provide detailed Activity status (Key-and-Value)
		return details;
	}
	
	public ValidationContext validate(){}		// Validate Activity setup at design time
 
4.	Utility methods
Necessary methods needed when writing michellaneous activity logic

	public Activity getRootActivity(){ return root; } 	// get the Root Activity.	
	public ProcessDefinition getProcessDefinition(){	//All process definitions that this Activity holds
		return (ProcessDefinition)getRootActivity();
	}
	
	public void fireComplete(ActivityInstance instance) throws Exception{	//If it is executed successfully		onEvent(ACTIVITY_DONE, instance, null);
	}

	public void fireFault(ActivityInstance instance, Exception fault) throws Exception{ //if it fails
		onEvent(ACTIVITY_FAULT, instance, fault);
	}
}

3.5.2 Activity Flow Control Class Reference Codes #1 - ComplexActivity.java

public class ComplexActivity extends Activity {
	
1.	Field Declaration

	private Vector childActivities;	// The Vector that contains Children 
	
2.	Constructor Declaration

	public ComplexActivity(){}		
	
3.	Invoked crateInstance method implementation when creating an instance – It initiates necessary current step(currentStep) for itself, invoking initialization routine for its children.

	public ActivityInstance createInstance(ActivityInstance instanceInCreating) throws Exception{
				
		super.createInstance(instanceInCreating);
		
		//Sets current running state
		instanceInCreating.set(getTracingTag(), "currentStep", "0");
		
		//Lets each child activity initialize process instance
		Vector childActivities = getChildActivities();	 			
		for(Enumeration enum = childActivities.elements(); enum.hasMoreElements(); ){
			Activity child = (Activity)enum.nextElement();
			child.createInstance(instanceInCreating);
		}
		
		return instanceInCreating;
	}
	

4.	Conduct all steps of Activities, Conduct the total number of child activities, send a completion signal(fireDone). (Real source codes are being queued via JMS, but the following codes are written in a direct ways to conduct)

	protected void executeActivity(ActivityInstance instance) throws Exception{
		int currStep = getCurrentStep(instance);
		if(currStep >= childActivities.size()){
			instance.fireDone();
			
			fireComplete(instance);
			
			return;
		}		
		
		Activity childActivity = (Activity)getChildActivities().elementAt(currStep);		
		childActivity.executeActivity(instance); // In real codes, JMS invocation is needed
	}

5.	If a child Activity completes, The CHILD_DONE event is delivered to the parent Activity. The parent Activity receives the message, increments the value of currentStep, executes next Activity.

	protected void onEvent(String command, ActivityInstance instance, Object payload) throws Exception{
		//dispatching leaf childs
		if(command.equals(CHILD_DONE)){
			int currStep = getCurrentStep(instance);
			currStep++;	
			setCurrentStep(instance, currStep);
			
			executeActivity(instance);	//execute next
		}else		
			super.onEvent(command, instance, null);
	}

	….
}

3.5 Apply Main Class, Example #1

The following example describes a process definition with source codes.


Figure 26. Example Process
Figure 26. Example Process


public class SimpleProcess extends ProcessDefinition{
	
	public SimpleProcess(){
	HumanActivity act1 = new HumanActivity();
	act1.setName("Act1");
	addChildActivity(act1);

	HumanActivity act2 = new HumanActivity();
	act2.setName("Act2");

	HumanActivity act3 = new HumanActivity();
	act3.setName("Act3");

	SwitchActivity sa = new SwitchActivity();
	sa.setName("Switch");
	sa.addChildActivity(act2);
	sa.addChildActivity(act3);	
	addChildActivity(sa);
	}
}

We are able to see that Act1 and Switch are placing in the same level, and Act2 and Act3 are child activities of the Switch. [Note] In reality, these are initialized in XML format and managed as a file.

3.8.4 Transaction Usage example #1

JDBCExtWorklist

JDBCExtWorklist is a class that conducts assigning and managing WorkItem. As we learned from previous chapter, It is a good chance to understand how to make use of SynchronizedDAO. When assigning a task at first, addWorkItemImpl method is invoked and assigned WorkItem’s taskID is used as a key which helps create a WorkListDAO typed DAO, it eventually stores into sharedContext. This DAO separately creates and shares a WorkListDAO for each taskID.

/*
* One part of addWorktemImpl method in JDBCExtWorklist.java
* WorkListDAO type is already declared.
*When reservedTaskId is generated, we need to use “findSynchronizedDAO”, because DAO is already created.
*otherwise, create a new taskID, create a DAO via createSynchronizedDAO invocation.
*/

final WorkListDAO wl;
Long taskId; 
if(reservedTaskId!=null){
	taskId = new Long(reservedTaskId);
	wl = (WorkListDAO) tc.findSynchronizedDAO("BPM_WORKLIST", "taskId", taskId, WorkListDAO.class);
}else{
	taskId = UniqueKeyGenerator.issueWorkItemKey(tc);
	wl = (WorkListDAO) tc.createSynchronizedDAO("BPM_WORKLIST", "taskId", taskId, WorkListDAO.class);
}

When we need WorkListDAO created via addWorkItemImpl for a second time, findSynchronizedDAO method along with the taskID search criteria must be used.


// The method that cancels WorkItem
public void cancelWorkItem(String taskID, KeyedParameter[] options, TransactionContext tc) throws RemoteException {
	try{
	         WorkListDAO wl = (WorkListDAO) tc.findSynchronizedDAO("BPM_WORKLIST", "taskId", new Long(taskID), WorkListDAO.class);
		wl.setStatus(DefaultWorkList.WORKITEM_STATUS_CANCELLED);
	}catch(Exception e){
		throw new RemoteException("ExtWorkList", e);
	}
}

//The method that completes WorkItem
public void completeWorkItem(String taskID, KeyedParameter[] options, TransactionContext tc) throws RemoteException {
	try{
		DAOFactory daoFactory = DAOFactory.getInstance(tc);
		Calendar now = daoFactory.getNow();

		WorkListDAO wl = (WorkListDAO) tc.findSynchronizedDAO("BPM_WORKLIST", "taskId", new Long(taskID), WorkListDAO.class);
		wl.setStatus(DefaultWorkList.WORKITEM_STATUS_COMPLETED);
		wl.setEndDate(new Timestamp(now.getTimeInMillis()));
			
	}catch(Exception e){
		throw new RemoteException("ExtWorkList", e);
	}
}


Figure 27. Example - JDBCWorkList's DAO caching
Figure 27. Example - JDBCWorkList's DAO caching


5.4.1 Type Declaration Example #1

Hypersonic DB is the default database installed under the uEngine. By using hypersonic DB, we will be able to execute the following Example. Before doing that, we should run runManager.bat file located in uengine_standalone\hsqldb\demo\runServer. And then, create AddressBook table, insert corresponding data to the table. Therefore, we finally execute the following codes.

//create a table. Think of database ‘create’ statement
Type  addressBook = new Type(
	" AddressBook ",     // table name
			//  column  type size
	new FieldDescriptor[]{
		new FieldDescriptor("PERSONNAME",”Name”),
		new FieldDescriptor("ADDRESS",”Address”),
		new FieldDescriptor("AGE",”Age”, Types.INTEGER),
		new FieldDescriptor("PHONENUMBER",”Phone Number”)
	},
	con			//database connection that this table is using
);

5.4.2 Automatic UI Creation Example #1

<%@include file="../../wihDefaultTemplate/header.jsp"%>		
<%@include file="../../wihDefaultTemplate/initialize.jsp"%>
<%@page import="org.uengine.contexts.ComplexType"%>

<form action=submit.jsp method=POST>


<input type=hidden value='<%=decode(request.getParameter("instanceId"))%>' name=instanceId>
<input type=hidden value='<%=request.getParameter("message")%>' name=message>
<input type=hidden value='<%=decode(request.getParameter("processDefinition"))%>' name=processDefinition>
<input type=hidden value='<%=request.getParameter("tracingTag")%>' name=tracingTag>
<input type=hidden value='<%=request.getParameter("taskId")%>' name=taskId>
<input type=hidden value='<%=request.getParameter("initiate")%>' name=initiate>
<%
//------------- show flow chart -------------------//
Hashtable options = new Hashtable();
options.put("decorated", "yes");
options.put("nowrap", "yes");
options.put("locale", loggedUserLocale);
options.put("imagePathRoot", "../../../processmanager/");
	
String chart;
if(initiate)
chart = pm.viewProcessDefinitionFlowChart(processDefinition, options);	
else
chart = pm.viewProcessInstanceFlowChart(instanceId, options);	
%>

<%=chart %>

//Create web UI automatically
<table cellspacing=1 border=1>
<%
ParameterContext[] parameterContexts = (ParameterContext[])pm.getActivityProperty(processDefinition, tracingTag, "parameters");
Properties scriptSet = new Properties();
	
HashMap inputterOptions = new HashMap();
inputterOptions.put("instanceId", instanceId);

if(UEngineUtil.isNotEmpty(instanceId))
inputterOptions.put("instance", pm.getProcessInstance(instanceId));
	
inputterOptions.put("defVerId", processDefinition);
inputterOptions.put("definitionRemote", pdr);
inputterOptions.put("processManager", pm);
	
if(parameterContexts !=null)
for(int j=0; j<parameterContexts.length; j++){
ParameterContext parameterContext = parameterContexts[j];
 %>	
     <tr>
        <td align=right>
         <b><%=(parameterContext.getArgument()!=null ? parameterContext.getArgument().getText(loggedUserLocale):
parameterContext.getVariable().getDisplayName().getText(loggedUserLocale))%> : </b>
         </td>
          <td>
     	<%
          Object existingValue = (piRemote!=null ? parameterContext.getVariable().get(piRemote, "") : parameterContext.getVariable().getDefaultValue());	
		
	WebInputter defaultInputter = (WebInputter)parameterContext.getVariable().getInputter();

		
	if(defaultInputter==null){
			
	Class objType = parameterContext.getVariable().getType();
	if(objType == ComplexType.class){
	  objType = ((ComplexType)existingValue).getTypeClass(pm);
	}
			
	ObjectType outputClsTable = new ObjectType(objType);
	FieldDescriptor[] arrayFieldDescriptors = outputClsTable.getFieldDescriptors();
				
	String[] columns = new String[arrayFieldDescriptors.length];	
	for(int i=0; i<arrayFieldDescriptors.length; i++){
	  columns[i] = arrayFieldDescriptors[i].getName();
	}
			
	for(int i=0; i<columns.length; i++){
	  FieldDescriptor fieldDescriptor = outputClsTable.getFieldDescriptor(columns[i]);
	%>	<%=(fieldDescriptor.getDisplayName().equals("-") ? "":fieldDescriptor.getDisplayName()+":")%>
	<%
		    	
	WebInputter inputter = fieldDescriptor.getWebInputter();
	inputter.addScriptTo(scriptSet, parameterContext.getVariable().getName(), fieldDescriptor, existingValue, inputterOptions);
		        
	Object propertyValue = null;
	try{
	  propertyValue = objType.getMethod("get" + columns[i], new Class[]{}).invoke(existingValue, new Object[]{});
	}catch(Exception e){
          }
		        
String htmlFromInputter;
	if(isViewMode || ParameterContext.DIRECTION_IN.equals(parameterContext.getDirection())){
	  htmlFromInputter = inputter.getViewerHTML(parameterContext.getVariable().getName(), fieldDescriptor, propertyValue, inputterOptions);
	}else{
	  htmlFromInputter = inputter.getInputterHTML(parameterContext.getVariable().getName(), fieldDescriptor, propertyValue, inputterOptions);
	}
		    	
	%>  <%=htmlFromInputter%>
	<% if(i<columns.length-1){%>
	<br>
	<%}
	}
	}else{
	  FieldDescriptor fieldDescriptor = new FieldDescriptor("value", "value");
	  defaultInputter.addScriptTo(scriptSet, parameterContext.getVariable().getName(), fieldDescriptor, existingValue, inputterOptions);
	  String htmlFromInputter;
	  if(isViewMode || ParameterContext.DIRECTION_IN.equals(parameterContext.getDirection())){
	  htmlFromInputter = defaultInputter.getViewerHTML(parameterContext.getVariable().getName(), fieldDescriptor, existingValue, inputterOptions);
	  }else{
	    htmlFromInputter = defaultInputter.getInputterHTML(parameterContext.getVariable().getName(), fieldDescriptor, existingValue, inputterOptions);
	    }
    %>	
	    <%=htmlFromInputter%>	    	 
	    <%
	 }
       %>
 </td></tr>
<%
	}
%>
</table>
	<input type=hidden value='<%=request.getParameter("trouble_class") %>' name=trouble_class>
	<input type=hidden value='<%=request.getParameter("trouble_desc") %>' name=trouble_desc>
	<input type=submit value="Complete">
</form>

5.4.3 Reference codes of consistent ways to Input data #1 – DateInput.java

The following example is the source codes of DataInput. (by using inputter.*, you can see a various examples.)

package org.metaworks.inputter;

import java.awt.Component;
import org.metaworks.FieldDescriptor;
import org.metaworks.ui.*;
import org.metaworks.web.HTML;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.text.*;

public class DateInput extends InputterAdapter{

	public DateInput(){
		super();
	}
	
/////////// implemetations //////////////

	public Object getValue(){
		Date srcDate = ((DateButton)getComponent()).getDate();
		
		if(srcDate==null) return null;
		
	/*	Date rtnDate = new Date(srcDate.getTime()){
			public String toString(){
			    SimpleDateFormat displayFormatter = new SimpleDateFormat("yyyy-MM-dd");
				String making = displayFormatter.format(this);
						
				return making;
			}			
		};
		
		return rtnDate;*/
		
		return srcDate;

	}
	
	public void setValue(Object obj){
		if(obj instanceof Date && obj!=null)
			((DateButton)getComponent()).setDate((Date)obj);
	}

	public Component getNewComponent(){
		
		DateButton dateButton = new DateButton();
		
		//dateButton.setDisplayFormat("yyyy-MM-dd");
		
		return dateButton;
	}
	
	public String getViewerHTML(String section, FieldDescriptor fd, Object defaultValue, Map options) {
		
		if(defaultValue!=null){
			Calendar value;

			if(defaultValue instanceof Date){
				value = Calendar.getInstance();
				value.setTime((Date)defaultValue);
			}else value = (Calendar)defaultValue;
			
//			SimpleDateFormat displayFormatter = new SimpleDateFormat("dd-MM-yyyy");
//			String making = displayFormatter.format(value.getTime());
//					
			return value.getTime().toString();
			//return ""+value;
		}
		
		return "-";
	}

	public String getInputterHTML(String section, FieldDescriptor fd, Object defaultValue, Map options){

		int date = 0, month =0, year=0;	
		
		if(defaultValue == null) defaultValue = Calendar.getInstance();
		
		if(defaultValue!=null && defaultValue instanceof Calendar){
			Calendar cal = (Calendar)defaultValue;
			date = cal.get(Calendar.DATE);
			month = cal.get(Calendar.MONTH);
			year = cal.get(Calendar.YEAR);
		}

		StringBuffer html = new StringBuffer();
		
		//day
		html.append("<select");
		html.append(HTML.getAttrHTML("name", "_" + section + "_" + fd.getName() + "_day"));
		html.append(">");
		for(int i=0; i<30; i++){
			if(defaultValue!=null && i==date)
				html.append("<option value=" + i + " selected>" + (i+1));
			else
				html.append("<option value=" + i + ">" + (i+1));
		}
		html.append("</select> - ");

		//month
		html.append("<select");
		html.append(HTML.getAttrHTML("name", "_" + section + "_" + fd.getName() + "_month"));
		html.append(">");
		
		String [] monthNames = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

		for(int i=0; i<11; i++){
			if(defaultValue!=null && i==month)
				html.append("<option value=" + i + " selected>" + monthNames[i]);
			else
				html.append("<option value=" + i + ">" + monthNames[i]);
		}
		html.append("</select> - ");
		
		//year
		html.append("<input");
		html.append(HTML.getAttrHTML("name", "_" + section + "_" + fd.getName() + "_year"));
		if(defaultValue!=null) html.append(" value=" + year);
		html.append(" size=5>");

		return html.toString();
	}
	
	public Object createValueFromHTTPRequest(Map parameterValues, String section, String fieldName, Object oldValue){
		try{
			String strDay = ((String[])parameterValues.get("_" + section + "_" + fieldName + "_day"))[0];
			String strMonth = ((String[])parameterValues.get("_" + section + "_" + fieldName + "_month"))[0];
			String strYear = ((String[])parameterValues.get("_" + section + "_" + fieldName + "_year"))[0];
			
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.DATE, Integer.parseInt(strDay));
			cal.set(Calendar.MONTH, Integer.parseInt(strMonth));
			cal.set(Calendar.YEAR, Integer.parseInt(strYear));
			
			return cal;
		}catch(Exception e){
			return null;
		}
	}
}

5.5.3 Role Object Extension Example #1 - organizationChartXML.jsp

<?xml version="1.0" encoding="UTF-8"?>
<%
response.setContentType("text/xml; charset=UTF-8");
response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
response.setHeader("Pragma","no-cache"); //HTTP 1.0
response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
%><%@page 
	pageEncoding="KSC5601" 
	import="javax.naming.Context,
	        javax.naming.InitialContext,
	        javax.naming.NamingException,
	        javax.rmi.PortableRemoteObject,
	        org.uengine.kernel.*,
	        org.uengine.util.dao.DefaultConnectionFactory,
	        java.util.*,
	        java.sql.*,
	        javax.sql.*,
	        java.io.*,
	        org.uengine.processmanager.*"
%>

<resources>
<%	
Connection conn;

conn = DefaultConnectionFactory.create().getConnection();
Statement stmt = conn.createStatement();

try
{
         //Get necessary user information that database needs.
	StringBuffer sql = new StringBuffer();
	sql.append(" select E.EMPCODE,                        ");
	sql.append("        E.EMPNAME,                     ");
	sql.append(" 	    E.PARTCODE,                ");
	sql.append(" 	    E.EMAIL,                    ");
	sql.append(" 	    E.GLobalCom,                ");
	sql.append(" 	    P.PARTNAME                ");
	sql.append(" from PArtTable P,                          ");
	sql.append("      EMPTABLE E                       ");
	sql.append(" where  P.PARTCODE  = E.PARTCODE        ");
	sql.append(" and   P.GlobalCom = E.GLobalCom            ");
	sql.append(" order by P.PARTCODE,E.EMPNAME            ");
	
	ResultSet rs = stmt.executeQuery(sql.toString());
	
	String curDivCode = "";
	String curPartCode = "";

	//Construct XML elements
	while (rs.next())
	{
	%><resource value="<%=rs.getString("EMPCODE")%>" name="<%= rs.getString("EMPNAME") %>"/><%
	}
	
}
finally
{
	if ( stmt != null ) try { stmt.close(); } catch (Exception e) {}
	if ( conn != null ) try { conn.close(); } catch (Exception e) {}
}
		
%></resources>

5.5.3 Role Object Extension Example #2 – Multiple Role Mapping Example

The following submit.jsp shows the second stage, ‘setTheRightPerson’ of troubleticket workitem handler which is responsible for rolemapping.

<%@include file="../../wihDefaultTemplate/header.jsp"%>		
<%@page import="javax.transaction.*"%>

<jsp:useBean id="processManagerFactory" scope="application" class="org.uengine.processmanager.ProcessManagerFactoryBean" />

<%
	ProcessManagerRemote pm = processManagerFactory.getProcessManager();

	String definitionId = request.getParameter("processDefinition");
	String instanceId = request.getParameter("instanceId");
	String tracingTag = request.getParameter("tracingTag");
	String taskId = request.getParameter("taskId");
	
	String troubleClass = request.getParameter("trouble_class");
	String troubleDesc = request.getParameter("trouble_desc");
	String rightPerson = request.getParameter("_rightPerson_rightPerson");
	
	InitialContext context = new InitialContext();

	UserTransaction tx = (GlobalContext.useManagedTransaction ? (UserTransaction)context.lookup(GlobalContext.USERTRANSACTION_JNDI_NAME) : null);

	try{
		if(tx!=null) tx.begin();		

		instanceId = pm.initialize(definitionId, instanceId, loggedRoleMapping);

		pm.setProcessVariable(instanceId, "", "trouble_class", troubleClass);
		pm.setProcessVariable(instanceId, "", "trouble_desc", troubleDesc);
		'''pm.putRoleMapping(instanceId, "rightPerson", rightPerson);  // rightPerson Role Mapping'''
		
		pm.completeWorkitem(instanceId, tracingTag, taskId, null);

		pm.applyChanges();

		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.commit();

	%>
	<h1><font color=green>		Workitem has been successfully completed
	<%

	}catch(Exception e){
		e.printStackTrace();
		
		if(tx!=null && tx.getStatus() != Status.STATUS_NO_TRANSACTION )
			tx.rollback();
		
		throw e;
	}finally{
		try{
			pm.remove();
		}catch(Exception e){}
	}
%>		

In troubleTicket process scenario, the second step is selecting people in charge for the role by manager. At here, we assign more than 1 person for the role. Especially, let us make changes on the source codes in bold face above with the way in bold face shown below.

RoleMapping rm = RoleMapping.create();
                  rm.setName(“'''rightPerson'''”);
		String ids = {“JB”,”JJY”};
                  for(int i=0; i< ids.length;i++ ){	
		  rm.setEndpoint(ids[i]);
		  rm.fill(instance);      // Retrieve corresponding user (id) information id).
		  '''rm.moveToAdd();'''     //Move role mapping cursor to the next.
}
pm.putRoleMapping(instanceId, rm);

There are 2 APIs that conduct role mapping

//The API that assigns one person to corresponding roleName's role

putRoleMapping(String instanceId, String roleName, String endpoint);


//The API that creates a Role Mapping class and conducts role mapping.

putRoleMapping(String instanceid, RoleMapping rm);

When we create a Role Mapping class, we must keep the same name as role mapping has. Fill() method is responsible for filling user information from the organization chart. When we need other information besides id, database connection is required, so it is better being invoked when it is necessary because of database performance. moveToAdd() method is simply explained that it conducts when moving the cursor for role mapping. Therefore, it is useful for multiple role mapping. Without moveToAdd() method invocation, only the last user gets mapped. Basically, multiple role mapping becomes a competition. A competition means that a task is assigned to multiple associates, however, the task is accepted by the only one person and completes the task.