Activiti Process Definition Language and activiti Process Definition
1. process)
The root element of a process in the bpmn file. A process represents a workflow.
2. sequenceFlow)
A Sequential stream is a line connecting two process nodes, representing the exit of a node. After a node is executed, the process continues to run along all outgoing sequential streams of the node. That is to say, the default behavior of BPMN 2.0 is concurrency: two outgoing sequential streams will create two separate Concurrent Flow branches.
A Sequential stream consists of four attributes:
Id: Unique identifier used to differentiate different sequential streams.
SourceRef: source node ID of the link
TargetRef: ID of the target node of the connection.
Name (optional): name of the connection line, which is not applicable to businesses and is mainly used for display.
Note:
1) The End Node has no exit
2) Other nodes have one or more egress ports. If an exit exists, it indicates a single-line process. If multiple exits exist, it indicates that the concurrent process is enabled.
3. Nodes
1. Start event node (startEvent)
The START event is used to indicate where the process starts. The type of the Start event (the process is started when an event is received, or started at a specified time, etc.) defines how the process is started, which is displayed in different small charts of the event. In XML, these types are distinguished by declaring different sub-elements.
1) Empty start event
A null start event technically means that no trigger condition is specified for the process instance to start. The most common start method means that the process must be manually triggered by calling the startProcessInstanceByXXX method of the api. Note: Each sub-process has an empty start event.
ProcessInstanceprocessInstance = runtimeService. startProcessInstanceByXXX ();
Graphic Tag: An empty start event is displayed as a circle with no internal charts (no trigger type)
The XML structure is as follows: <startEventid = "start" name = "my start event"/>
2) Scheduled Start event
The Scheduled Start event is used to create a process instance at a specified time. It can be used at the same time for only one start process and the process that should be started multiple times at a specific interval.
Note:
1. subprocesses cannot use scheduled start events.
2. Scheduled Start event calculation starts after the process is released. You do not need to call startProcessInstanceByXXX. Although you only call the method for starting the process, too many processes will be started when startProcessInstanceByXXX is called.
3. When a new version of the Process deployment contains a scheduled start event, the corresponding previous timer will be deleted. This is because you usually do not want to automatically start the process instance of the old version of the process.
Graphic Tag: the scheduled start event is displayed as a circle with a table in it.
XML content:
The XML content of a scheduled start event is a declaration of a common start event, which contains a scheduled definition sub-element.
Example: The process is started four times, with each interval of 5 minutes, starting from, January 1, September 18, 2013.
<startEvent id="theStart"> <timerEventDefinition> <timeCycle>R4/2013-09-18T12:13/PT5M</timeCycle> </timerEventDefinition> </startEvent>
Example: The process is started once according to the selected time.
<startEventid="theStart"> <timerEventDefinition> <timeDate>2013-10-31T23:59:24</timeDate> </timerEventDefinition> </startEvent>
2. endEvent)
The end event indicates the end of the (sub) process (Branch. The end event is a trigger event. This means that when the process reaches the end event, a result is triggered. The result type is represented by the internal Black icon of the event.
1) Empty end event
An empty end event means that the throw result is not specified when the event is reached. In this way, the engine will directly end the Branch currently being executed without doing anything else.
Graphic Tag: An empty ending event is a rough circle with no small chart (no result type)
XML content: <endEvent id = "end" name = "my end event"/>
The XML content of an empty ending event is the definition of a normal ending event and does not contain child elements (other types of ending events will contain child elements of the declared type ).
3. Task)
1) receive Task nodes(ReceiveTask)
A receiving task is a simple task that waits for the arrival of the corresponding message. Currently, the official website only implements the java semantics of this task. When the process reaches the receiving task, the Process status is saved to the database.
After a task is created, the process enters the waiting state until the engine receives a specific message, which triggers the process to continue execution through the receiving task.
Graphical Tag: The receive task is displayed as a task (rounded rectangle) with a message tag in the upper right corner. The message is white (the black icon indicates the sending semantics)
XML content: <deleetask id = "waitState" name = "wait"/>
RuntimeService can be called after the current task (generally the task is completed automatically but takes some time) is completed and the process goes backward. signal (executionId) is used to pass the id of the process on the receiving task.
The Demo code is as follows:
ProcessInstance pi =runtimeService.startProcessInstanceByKey("receiveTask");Execution execution=runtimeService.createExecutionQuery() .processInstanceId(pi.getId())
.activityId("waitState")
.singleResult();assertNotNull(execution);runtimeService.signal(execution.getId());
2) User task node (userTask)
User Tasks are used to set jobs that must be completed by personnel. When the process is executed to a user task, a new task is created and added to the task list of the specified person or group.
Graphical tag: a user task is displayed as a normal task (rounded rectangle) with a small user icon in the upper left corner.
The user task in the XML content XML is defined as follows. The id attribute is required. The name attribute is optional.
<UserTask id = "theTask" name = "Important task"/>
You can also set descriptions for user tasks (in fact, descriptions can be set for all BPMN 2.0 elements ). You can add the documentation element to define the description.
<userTask id="theTask" name="Schedule meeting"> <documentation> Schedule an engineering meeting for next week with the new hire. </documentation>
In practical applications, after receiving a task, you can refer to the task description to handle the task. The description text can be obtained through the standard java method: task. getDescription ()
Task Allocation
Manual participation is required for handling user tasks. User Tasks can be divided into two categories. Private and public tasks (accessible tasks ).
Private task
A private task is a task directly assigned to a specified user. Only one user can be the executor of a task. In activiti, a user is called an executor. User Tasks with Executors (Private tasks) are invisible to other users. Only the list of personal tasks of the performer can appear.
Assign user tasks directly to the specified user to use the assignee attribute. The XML Code is as follows:
<UserTask id = "theTask" name = "my task" activiti: assignee = "sirius"/>
The value corresponding to the Assignee attribute is a user ID.
Tasks directly assigned to users can be handled through TaskService as follows:
List <Task> tasks = taskService. createTaskQuery (). taskAssignee ("sirius "). list (); Task task = tasks. get (0); // assume that the first part of the task set is the taskService to be processed. complete (task. getId ());
Public task
Some user tasks cannot determine the specific handler when they are assigned. In this case, the tasks can also be added to the candidate task list of the personnel, so that these personnel can selectively claim and handle the tasks.
The assignment of public tasks can be divided into two types: specified candidate users and candidate groups.
A) add the task to the candidate task list of a group of users and use the candidateUsers attribute. The XML content is as follows:
<UserTaskid = "theTask" name = "my task" activiti: candidateUsers = "sirius, kermit"/>
The candidateUsers attribute contains the user ID. Separate multiple user IDs with commas (half-width.
B) add a task to one or more candidate groups. In this case, the task is visible to all users in the group. First, ensure that there are users in each group, create a user and a group using the IdentityService object, and add the user to the corresponding group.
Configure the group task and use the candidateGroups attribute. The XML content is as follows:
<UserTask id = "theTask" name = "my task" activiti: candidateGroups = "testGroup, developGroup"/>
Tasks indirectly assigned to users can be operated as follows through TaskService:
List <Task> tasks = taskService. createTaskQuery (). taskCandidateUser ("sirius "). list (); Task task = tasks. get (0); // assume that the first part of the task set is the task String taskId = task. getId (); taskService. claim (taskId, "sirius"); // claim a task to make the user the executor of the task taskService. complete (taskId );
Note:
1. To maintain users and groups, use user management service objects and use processEngine to obtain IdentityService.
2. To assign a group task, you must first create a group and have users in the group. The most critical attribute of users and groups is ID.
3. Use newUser (userId) and newGroup (groupId) to create users and groups.
4. Use createMembership (userId, groupId) to attach the user to the group.
5. For a candidate task, you must first claim the task and make the user the executor of the task.
If the preceding method is not flexible enough, we can also customize a task allocation processor and dynamically set the task attributes through code. The XML Code is as follows:
<userTask id="task1" name="My task"> <extensionElements> <activiti:taskListener event="create" class="org.activiti.MyAssignmentHandler"/> </extensionElements></userTask>
DelegateTask is passed to the TaskListener implementation, through which the executor, candidate, and candidate group can be set:
Public class MyAssignmentHandler implements TaskListener {Public void Policy (DelegateTask delegateTask) {// execute the user search code... // set the obtained user to the task delegateTask that triggers the event. setAssignee ("sirius"); // delegateTask. addCandidateUser ("kermit"); // delegateTask. addCandidateGroup ("testGroup ");...}}
Although both of the above can be collectively referred to as task nodes, there are essential differences:
1. receiveTask mainly indicates Automatic execution by machines, and userTask indicates manual intervention.
2. after the receiveTask task is generated, a record will be added to the act_ru_execution table, and after the userTask is generated, the record will be in act_ru_execution and act_ru_task (mainly recording the release time, handler, and other information of the task) each generates a record.
3. Use the signal method of RuntimeService to submit the receiveTask task, and use the complete method of TaskService to submit the userTask task.
How does ACTIVITI obtain the next node?
First, obtain the current task according to the process ID :??
Java code ????
List <Task ?? Tasks ?? = ?? TaskService. createTaskQuery (). processInstanceId (procInstanceId). list ();????
Then obtain the process definition of the current process according to the current task, and then obtain all the nodes according to the process definition :??
Java code ????
ProcessDefinitionEntity ?? Def ?? = ?? (ProcessDefinitionEntity )?? (RepositoryServiceImpl) rs). getDeployedProcessDefinition (task. getProcessDefinitionId ());???????? List <ActivityImpl ?? ActivitiList ?? = ?? Def. getActivities ();????
// Rs refers to the RepositoryService instance ???? Obtain the execution ID of the current process, the execution instance, and the ID of the current process node according to the task :??
Java code ????
String ?? ExcId ?? = ?? Task. getExecutionId ();????
ExecutionEntity ?? Execution ?? = ?? (ExecutionEntity )?? Runtimeservice.createexecutionquery(cmd.exe cutionId (excId). singleResult ();????
String ?? ActivitiId ?? = ?? Execution. getActivityId ();????
Then cyclically activitiList and judge the nodes in the current process. Then, obtain the current node instance, obtain all the paths from the current node based on the node instance, and then obtain the next node instance according to the path :??
Java code ???? For (ActivityImpl ?? ActivityImpl: activitiList ){????
String ?? Id ?? = ?? ActivityImpl. getId ();???? If (activitiId. equals (id )){????
System. out. println (
"Current task :"
+ ActivityImpl. getProperty ("name "));?? // Output a certain attribute of a node ???? List <PvmTransition ?? OutTransitions ?? = ?? ActivityImpl. getOutgoingTransitions ();
// Obtain all lines from a node ???? For (PvmTransition ?? Tr: outTransitions ){????
PvmActivity ?? Ac ?? = ?? Tr. getDestination ();??
// Obtain the End Node of the line ???? System. out. println (
"Next task :"
Activiti workflow concept is unclear
Developer.android.com/images/activity_lifecycle.png