Activiti 5.22.0 Annotated Source Code

repository·master·Indexed 21 days ago

https://github.com/lovemyorange/activitisourcecode

A heavily annotated version of the Activiti 5.22.0 source code featuring approximately 10,000 lines of Chinese comments. This repository serves as a learning resource for developers to understand the internal architecture, design patterns (such as Command and Chain of Responsibility), and core components of the Activiti workflow engine, including BPMN parsing, event dispatching, and the persistence layer.

Tokens
127.4K
Snippets
349
Records
473
Agent score
75%

What's inside activitisourcecode

  1. Overview of Activiti Explorer

    master

    Activiti Explorer is a web-based demonstration application included with Activiti. It is designed to showcase and exercise Activiti's functionality rather than serve as a production-ready end-user application.

    Key capabilities include:

    • Tasks: Manage user tasks (assigned to you) or group tasks (claimable). Supports standalone tasks not related to any process.
    • Process: View deployed process definitions and start new process instances.
    • Reporting: Generate and view saved reports.
    • Manage: (Administrator only) Manage users/groups, execute stuck jobs, view the database, and deploy new process definitions.
  2. Overview of Activiti 5.22.0 Source Code with Chinese Annotations

    master

    This repository contains the source code for Activiti version 5.22.0 with extensive Chinese annotations (approximately 10,000 lines). It is designed as a learning resource to help developers understand the internal workings of the Activiti workflow engine.

    Key areas covered by the annotations include:

    • Process Engine Configuration: ProcessEngineConfiguration and its subclasses.
    • BPMN Parsing: BpmnModel and related classes for first-layer parsing.
    • Event Dispatching: EventDispatcher and related classes.
    • Optimization: Activiti's four major cache classes.
    • Job Scheduling: Classes related to scheduled tasks.
    • PVM Parsing: Classes related to the second-layer parsing (PVM).
    • Listeners: Listener-related classes.
    • Design Patterns: Implementation of the Command pattern and Chain of Responsibility.
    • Atomic Operations: Classes supporting PVM execution (e.g., XXXoperation).
    • Flow Control: Behavior classes that determine process direction.
    • Persistence Layer: MyBatis integration (though coverage is lighter here due to its dependency on the MyBatis framework).
  3. Introduction to Activiti-Crystalball (Experimental)

    master

    activiti-crystalball (CrystalBall) is a discrete event simulation engine designed for the Activiti Business Process Management Platform. It allows developers to use simulation for:

    • Decision Support: Evaluating production workflows (e.g., determining if additional resources are needed to meet due dates).
    • Optimization and Understanding: Testing process changes and analyzing their impacts.
    • Training: Using simulated environments to train staff before a real rollout.

    Unlike separate simulation engines, CrystalBall is based directly on Activiti, meaning you can easily copy data, start simulations, and replay workflow behavior from history without creating separate models or reporting structures.

  4. Overview of Activiti 5.22.0

    master

    Activiti is a lightweight, Java-centric open-source BPMN engine designed for process automation. This specific repository contains the source code for version 5.22.0 with Chinese comments.

    It is noted that this version can be integrated with Spring Boot 2.0.6.RELEASE to develop web-based process management applications.

  5. Overview of Activiti Services

    master

    Activiti provides several stateless services to manage different aspects of the workflow engine:

    • RepositoryService: Manages 'static' data. Used for deploying and querying deployments and process definitions (the BPMN 2.0 blueprints).
    • RuntimeService: Manages 'dynamic' runtime state. Used to start process instances, manage process variables, and query executions (pointers to where a process is currently).
    • TaskService: Handles human interaction. Used to query, claim, and complete tasks assigned to users or groups.
    • IdentityService: Manages users and groups. Note: The engine does not verify if a user exists at runtime, allowing integration with external systems like LDAP.
    • FormService: (Optional) Manages start forms and task forms defined in the BPMN 2.0 process.
    • HistoryService: Provides access to historical data (e.g., start times, task durations, paths followed).
    • ManagementService: Used for administrative tasks like inspecting database tables and managing jobs (timers, async continuations).
  6. Use Data Objects in BPMN (Experimental)

    master

    Activiti supports defining data objects within a process or sub-process. These definitions are automatically converted into process variables using the value provided in the name attribute. You can also assign a default value using the <activiti:value> extension element.

    Supported XSD types: xsd:string, xsd:boolean, xsd:datetime, xsd:double, xsd:int, and xsd:long.

    <process id="dataObjectScope" name="Data Object Scope" isExecutable="true">
      <dataObject id="dObj123" name="StringTest123" itemSubjectRef="xsd:string">
        <extensionElements>
          <activiti:value>Testing123</activiti:value>
        </extensionElements>
      </dataObject>
      ...
    </process>
  7. Use Form Properties for built-in form rendering

    master

    Activiti allows you to define form properties within your process definition (BPMN XML) to facilitate UI rendering. These properties act as a mapping layer between complex Java process variables and a simple Map<String, String> that UI technologies can consume.

    Key Concepts

    • Mapping: Properties can map directly to process variables (by ID) or to nested properties of a Java object using UEL expressions (e.g., #{address.street}).
    • Default Behavior: If no variable attribute is specified, the submitted property is stored as a process variable with the same ID.
    • Type Conversion: Activiti handles conversion between form property types and Java types (e.g., a long property maps to java.lang.Long).
    • Validation: Using required="true" in the XML will cause an exception during submission if the field is missing.

    Supported Form Types

    • string
    • long
    • enum
    • date
    • boolean
    <userTask id="task">
      <extensionElements>
        <activiti:formProperty id="room" />
        <activiti:formProperty id="duration" type="long"/>
        <activiti:formProperty id="speaker" variable="SpeakerName" writable="false" />
        <activiti:formProperty id="street" expression="#{address.street}" required="true" />
      </extensionElements>
    </userTask>
  8. Use Timer Boundary Events

    master

    A timer boundary event acts as a stopwatch or alarm. When the activity it is attached to starts, the timer begins. When the timer fires, the activity is interrupted (by default) and the process follows the event's outgoing flow.

    Interrupting vs. Non-interrupting

    • Interrupting (Default): The activity being monitored is cancelled when the timer fires. Set cancelActivity="true" (or omit the attribute).
    • Non-interrupting: The original activity continues running, but an additional execution path is triggered via the event's outgoing flow. Set cancelActivity="false".

    Important: Timer boundary events require the job or async executor to be enabled in activiti.cfg.xml via jobExecutorActivate or asyncExecutorActivate set to true.

    <!-- Interrupting Timer Boundary Event -->
    <boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
      <timerEventDefinition>
        <timeDuration>PT4H</timeDuration>
      </timerEventDefinition>
    </boundaryEvent>
    
    <!-- Non-interrupting Timer Boundary Event -->
    <boundaryEvent id="escalationTimer" cancelActivity="false" attachedToRef="firstLineSupport"/>
  9. Understand Activiti History entities

    master

    History is the component that captures and permanently stores what happened during process execution. Unlike runtime data, history data remains in the database even after process instances have completed. This data is used for reporting and in Activiti Explorer.

    There are 5 core history entities:

    • HistoricProcessInstance: Information about current and past process instances.
    • HistoricVariableInstance: The latest value of a process variable or task variable.
    • HistoricActivityInstance: Information about a single execution of an activity (a node in the process).
    • HistoricTaskInstance: Information about current and past (completed and deleted) task instances.
    • HistoricDetail: Various types of information related to process instances, activity instances, or task instances (e.g., variable updates or form properties).
  10. Use Sub-Processes (Embedded vs. Event)

    master

    Embedded Sub-Process

    A standard Sub-Process is a grouping of activities within a parent process.

    • Use cases: Hierarchical modeling (collapsing details) and creating a new scope for events (e.g., a boundary timer that only affects activities inside the sub-process).
    • Constraints: Must have exactly one none start event, at least one end event, and sequence flows cannot cross its boundaries.

    Event Sub-Process

    An Event Sub-Process is triggered by a specific event (Message, Error, Signal, Timer, or Compensation) rather than a sequence flow.

    • Triggering: Subscription to the start event is created when the hosting scope is created.
    • Interrupting vs. Non-interrupting:
      • Interrupting: Cancels any executions in the current scope.
      • Non-interrupting: Spawns a new concurrent execution.
    • Activiti Limitations: Currently only supports interrupting event sub-processes, and only those triggered by Error or Message start events.
    • Implementation: Set triggeredByEvent="true" on the <subProcess> element.
    <!-- Event Sub-Process Example -->
    <subProcess id="eventSubProcess" triggeredByEvent="true">
    	<startEvent id="catchError">
    		<errorEventDefinition errorRef="error" />
    	</startEvent>
    	<sequenceFlow id="flow2" sourceRef="catchError" targetRef="taskAfterErrorCatch" />
    	<userTask id="taskAfterErrorCatch" name="Provide additional data" />
    </subProcess>
  11. Use Exclusive Gateways (XOR)

    master

    An exclusive gateway (XOR gateway) is used to model decision points. When execution reaches the gateway, all outgoing sequence flows are evaluated in the order they are defined.

    Selection Logic:

    • The first sequence flow whose condition evaluates to true is selected.
    • If multiple flows have true conditions, only the first one defined in the XML is chosen.
    • If no sequence flow condition is met, an exception is thrown (unless a default sequence flow is configured).
    • A gateway without an icon inside defaults to an exclusive gateway.
  12. Configure Start Events

    master

    Start events indicate where a process begins. They are always 'catching' events.

    None Start Event: Used when the process is started manually via the API (e.g., startProcessInstanceByXXX()). It has no sub-elements in XML.

    • Extension: activiti:formKey can be used to reference a form template.

    Timer Start Event: Used to start a process at a specific time or on intervals. These are scheduled as soon as the process is deployed.

    Message Start Event: Starts a process when a specific named message is received.

    • Constraint: Message names must be unique across a process definition and across all deployed process definitions.
    • Constraint: Message start events are only supported on top-level processes (not embedded sub-processes).

    Signal Start Event: Starts a process when a named signal is fired. All process definitions with a signal start event matching the signal name will be started.

    Error Start Event: Used to trigger an Event Sub-Process. It cannot be used to start a standard process instance.

    <!-- None Start Event with formKey extension -->
    <startEvent id="request" activiti:formKey="org/activiti/examples/taskforms/request.form" />
    
    <!-- Timer Start Event (repeating cycle) -->
    <startEvent id="theStart">
      <timerEventDefinition>
        <timeCycle>R4/2011-03-11T12:13/PT5M</timeCycle>
      </timerEventDefinition>
    </startEvent>
    
    <!-- Message Start Event -->
    <startEvent id="messageStart" >
        <messageEventDefinition messageRef="tns:newInvoice" />
    </startEvent>
    
    <!-- Signal Start Event -->
    <startEvent id="theStart">
        <signalEventDefinition id="theSignalEventDefinition" signalRef="theSignal"  />
    </startEvent>