diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Activity.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Activity.java index f24d3cb3d99..0c59696b8c1 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Activity.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Activity.java @@ -16,18 +16,36 @@ import java.util.List; /** - * @author Tijs Rademakers + * Activity 抽象类代表了 BPMN 流程图中的一个活动节点。 + * 它是所有具体活动类型的基类,提供了活动的基本属性和行为。 */ public abstract class Activity extends FlowNode { + // 默认流程的ID,用于在活动中作为默认的流转路径 protected String defaultFlow; + + // 标识该活动是否是补偿活动 protected boolean forCompensation; + + // 多实例循环特性,描述活动如何多次执行 protected MultiInstanceLoopCharacteristics loopCharacteristics; + + // 输入/输出规范,定义了活动的数据输入和输出 protected IOSpecification ioSpecification; + + // 数据输入关联,定义了与活动的数据输入相关的数据 protected List dataInputAssociations = new ArrayList<>(); + + // 数据输出关联,定义了与活动的数据输出相关的数据 protected List dataOutputAssociations = new ArrayList<>(); + + // 边界事件,与活动关联的事件,如错误事件或消息事件 protected List boundaryEvents = new ArrayList<>(); + + // 失败作业重试时间周期值,用于定义作业失败时的重试策略 protected String failedJobRetryTimeCycleValue; + + // 异常映射条目,定义了活动发生异常时的处理规则 protected List mapExceptions = new ArrayList<>(); public String getFailedJobRetryTimeCycleValue() { @@ -106,18 +124,28 @@ public void setMapExceptions(List mapExceptions) { this.mapExceptions = mapExceptions; } + /** + * 设置这个活动节点的属性为另一个 Activity 节点的属性。 + * 该方法用于复制活动节点或在活动节点之间共享属性。 + */ public void setValues(Activity otherActivity) { super.setValues(otherActivity); + // 复制其他活动的属性 setFailedJobRetryTimeCycleValue(otherActivity.getFailedJobRetryTimeCycleValue()); setDefaultFlow(otherActivity.getDefaultFlow()); setForCompensation(otherActivity.isForCompensation()); + + // 复制多实例循环特性 if (otherActivity.getLoopCharacteristics() != null) { setLoopCharacteristics(otherActivity.getLoopCharacteristics().clone()); } + + // 复制输入/输出规范 if (otherActivity.getIoSpecification() != null) { setIoSpecification(otherActivity.getIoSpecification().clone()); } + // 复制数据输入和输出关联 dataInputAssociations = new ArrayList<>(); if (otherActivity.getDataInputAssociations() != null && !otherActivity.getDataInputAssociations().isEmpty()) { for (DataAssociation association : otherActivity.getDataInputAssociations()) { @@ -132,6 +160,7 @@ public void setValues(Activity otherActivity) { } } + // 复制边界事件 boundaryEvents.clear(); boundaryEvents.addAll(otherActivity.getBoundaryEvents()); } diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/AdhocSubProcess.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/AdhocSubProcess.java index e8443c7bb58..5049718a07f 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/AdhocSubProcess.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/AdhocSubProcess.java @@ -13,45 +13,60 @@ package org.flowable.bpmn.model; /** - * @author Tijs Rademakers + * AdhocSubProcess 类表示一个非结构化的子流程,其中包含的活动可以以任意顺序执行。 + * 这种子流程通常用于更灵活、不预定义路径的业务逻辑。 */ public class AdhocSubProcess extends SubProcess { + // 定义子流程活动的执行顺序为并行或序列 public static final String ORDERING_PARALLEL = "Parallel"; public static final String ORDERING_SEQUENTIALL = "Sequential"; + // 定义子流程完成的条件 protected String completionCondition; + + // 子流程的执行顺序,可以是并行或序列 protected String ordering = ORDERING_PARALLEL; + + // 如果一个活动完成或者流程触发了一个中断事件,是否取消其它还在执行的实例 protected boolean cancelRemainingInstances = true; + // 获取子流程完成条件的方法 public String getCompletionCondition() { return completionCondition; } + // 设置子流程完成条件的方法 public void setCompletionCondition(String completionCondition) { this.completionCondition = completionCondition; } + // 获取子流程的执行顺序的方法 public String getOrdering() { return ordering; } + // 设置子流程的执行顺序的方法 public void setOrdering(String ordering) { this.ordering = ordering; } + // 判断子流程的执行顺序是否为并行的方法 public boolean hasParallelOrdering() { return !ORDERING_SEQUENTIALL.equals(ordering); } + // 判断子流程的执行顺序是否为序列的方法 public boolean hasSequentialOrdering() { return ORDERING_SEQUENTIALL.equals(ordering); } + // 获取是否取消剩余实例的方法 public boolean isCancelRemainingInstances() { return cancelRemainingInstances; } + // 设置是否取消剩余实例的方法 public void setCancelRemainingInstances(boolean cancelRemainingInstances) { this.cancelRemainingInstances = cancelRemainingInstances; } diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BaseElement.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BaseElement.java index b19e7b792c1..1ba86ec0728 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BaseElement.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BaseElement.java @@ -20,15 +20,24 @@ import org.apache.commons.lang3.StringUtils; /** - * @author Tijs Rademakers + * BaseElement 类是 BPMN 流程定义中所有元素的基础抽象类。 + * 它定义了所有元素共有的基本属性,如id、扩展元素和属性。 */ public abstract class BaseElement implements HasExtensionAttributes { + // 元素的唯一标识符 protected String id; + + // 元素在XML文档中的行号 protected int xmlRowNumber; + + // 元素在XML文档中的列号 protected int xmlColumnNumber; + + // 扩展元素的集合,这些是非标准的额外信息,可以附加到任何BPMN元素上 protected Map> extensionElements = new LinkedHashMap<>(); - /** extension attributes could be part of each element */ + + // 扩展属性的集合,这些可以是任何BPMN元素的额外属性 protected Map> attributes = new LinkedHashMap<>(); public String getId() { @@ -104,11 +113,17 @@ public void addAttribute(ExtensionAttribute attribute) { } } + /** + * 设置当前元素的所有扩展属性。 + */ @Override public void setAttributes(Map> attributes) { this.attributes = attributes; } + /** + * 复制另一个 BaseElement 的属性到当前元素。 + */ public void setValues(BaseElement otherElement) { setId(otherElement.getId()); @@ -141,6 +156,9 @@ public void setValues(BaseElement otherElement) { } } + /** + * 克隆当前元素的方法,每个具体的子类都需要实现这个方法。 + */ @Override public abstract BaseElement clone(); } diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BoundaryEvent.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BoundaryEvent.java index 5568edd4684..79f56cc027c 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BoundaryEvent.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/BoundaryEvent.java @@ -15,39 +15,47 @@ import com.fasterxml.jackson.annotation.JsonIgnore; /** - * @author Tijs Rademakers + * BoundaryEvent 类表示附加到活动边界的事件。 + * 这种事件在活动执行期间发生,用于模型化例如错误处理或消息中断等情况。 */ public class BoundaryEvent extends Event { @JsonIgnore - protected Activity attachedToRef; - protected String attachedToRefId; - protected boolean cancelActivity = true; + protected Activity attachedToRef; // 该事件附加到的活动引用 + protected String attachedToRefId; // 该事件附加到的活动的ID + protected boolean cancelActivity = true; // 当事件触发时,是否取消活动的执行 + // 获取附加到的活动引用 public Activity getAttachedToRef() { return attachedToRef; } + // 设置附加到的活动引用 public void setAttachedToRef(Activity attachedToRef) { this.attachedToRef = attachedToRef; } + // 获取附加到的活动ID public String getAttachedToRefId() { return attachedToRefId; } + // 设置附加到的活动ID public void setAttachedToRefId(String attachedToRefId) { this.attachedToRefId = attachedToRefId; } + // 判断事件触发时是否取消活动 public boolean isCancelActivity() { return cancelActivity; } + // 设置事件触发时是否取消活动 public void setCancelActivity(boolean cancelActivity) { this.cancelActivity = cancelActivity; } + // 克隆一个边界事件对象 @Override public BoundaryEvent clone() { BoundaryEvent clone = new BoundaryEvent(); @@ -55,6 +63,7 @@ public BoundaryEvent clone() { return clone; } + // 从另一个 BoundaryEvent 对象复制属性值 public void setValues(BoundaryEvent otherEvent) { super.setValues(otherEvent); setAttachedToRefId(otherEvent.getAttachedToRefId()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Event.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Event.java index 61b2527169c..93b65c312a4 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Event.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Event.java @@ -16,42 +16,57 @@ import java.util.List; /** - * @author Tijs Rademakers + * Event 抽象类表示 BPMN 流程图中的一个事件节点。 + * 事件是流程中发生的动作或结果,比如开始、结束或捕获信号等。 + * 本类是所有具体事件节点的基类,比如开始事件、结束事件或中间事件。 */ public abstract class Event extends FlowNode { + // 与事件相关的事件定义列表 protected List eventDefinitions = new ArrayList<>(); + + // 事件的输入参数列表 protected List inParameters = new ArrayList<>(); + + // 事件的输出参数列表 protected List outParameters = new ArrayList<>(); + // 获取事件定义的方法 public List getEventDefinitions() { return eventDefinitions; } + // 设置事件定义的方法 public void setEventDefinitions(List eventDefinitions) { this.eventDefinitions = eventDefinitions; } + // 向事件添加一个事件定义 public void addEventDefinition(EventDefinition eventDefinition) { eventDefinitions.add(eventDefinition); } - + + // 获取输入参数的方法 public List getInParameters() { return inParameters; } + // 设置输入参数的方法 public void setInParameters(List inParameters) { this.inParameters = inParameters; } + // 获取输出参数的方法 public List getOutParameters() { return outParameters; } + // 设置输出参数的方法 public void setOutParameters(List outParameters) { this.outParameters = outParameters; } + // 从另一个 Event 对象复制属性值的方法 public void setValues(Event otherEvent) { super.setValues(otherEvent); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/EventListener.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/EventListener.java index d6213292a68..7426ed15e52 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/EventListener.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/EventListener.java @@ -13,39 +13,52 @@ package org.flowable.bpmn.model; /** - * Element for defining an event listener to hook in to the global event-mechanism. - * - * @author Frederik Heremans - * @author Joram Barrez + * EventListener 类用于定义全局事件监听器。 + * 这些监听器可以在流程引擎中发生的特定事件时执行自定义的逻辑。 */ public class EventListener extends BaseElement { + // 要监听的事件类型,可以是一个特定事件或一组事件 protected String events; + + // 监听器实现的类型,如 'class'、'expression'、'delegateExpression' 或 'script' protected String implementationType; + + // 实现的具体内容,取决于 implementationType 的值 protected String implementation; + + // 与监听器关联的实体类型 protected String entityType; + + // 与事务相关的属性,定义监听器在事务的何种状态下被触发 protected String onTransaction; + // 获取监听的事件类型 public String getEvents() { return events; } + // 设置监听的事件类型 public void setEvents(String events) { this.events = events; } + // 获取实现类型 public String getImplementationType() { return implementationType; } + // 设置实现类型 public void setImplementationType(String implementationType) { this.implementationType = implementationType; } + // 获取实现 public String getImplementation() { return implementation; } + // 设置实现 public void setImplementation(String implementation) { this.implementation = implementation; } @@ -62,10 +75,12 @@ public String getOnTransaction() { return onTransaction; } + // 设置事务状态 public void setOnTransaction(String onTransaction) { this.onTransaction = onTransaction; } + // 克隆事件监听器的方法 @Override public EventListener clone() { EventListener clone = new EventListener(); @@ -73,6 +88,7 @@ public EventListener clone() { return clone; } + // 从另一个 EventListener 对象复制属性值的方法 public void setValues(EventListener otherListener) { super.setValues(otherListener); setEvents(otherListener.getEvents()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElement.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElement.java index 31d96f69814..905c037a13e 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElement.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElement.java @@ -18,46 +18,93 @@ import com.fasterxml.jackson.annotation.JsonIgnore; /** - * @author Tijs Rademakers + * FlowElement 抽象类是 BPMN 流程图中所有元素的基类。 + * 它定义了流程元素的基本属性,如名称和文档说明,并提供了执行监听器的管理。 + + * 以下是 `FlowElement` 的一些直接和间接实现类的概览: + * 1. **SequenceFlow**:表示流程图中的一条流动的路径,连接两个流程节点。 + * 2. **DataStoreReference**:用于描述流程中用于存储数据的实体。 + * 3. **DataObject** 和 **ValuedDataObject** 及其子类 + * (如 `StringDataObject`, `BooleanDataObject`, `LongDataObject` 等):表示流程中的数据对象,可以携带流程执行过程中的数据。 + * 4. **FlowNode**:`FlowNode` 是流程节点的基类,代表流程图中的一个点,比如活动或事件。 + * - **Activity**:活动是流程中的工作单元,比如任务。 + * - **CallActivity**:表示一个调用活动,它可以调用流程图中的另一个流程。 + * - **SubProcess**:表示子流程,它是流程中的一个流程片段。 + * - **Transaction**:特殊的子流程,用于事务管理。 + * - **EventSubProcess**:事件触发的子流程。 + * - **AdhocSubProcess**:非结构化的子流程,其中的活动没有严格的执行顺序。 + * - **Task**:表示一个任务,是活动的一种。 + * - **ScriptTask**:执行脚本的任务。 + * - **ManualTask**:人工执行的任务。 + * - **ReceiveTask**:等待特定消息到达的任务。 + * - **BusinessRuleTask**:用于执行业务规则的任务。 + * - **UserTask**:用户交互的任务。 + * - **Gateway**:网关用于控制流程的分支和汇合。 + * - **ExclusiveGateway**:排他网关,基于条件选择一条执行路径。 + * - **InclusiveGateway**:包容性网关,可以基于条件选择多条路径。 + * - **ParallelGateway**:并行网关,用于分发和汇聚并行执行路径。 + * - **EventGateway**:事件网关,用于根据事件决定流程的方向。 + * - **Event**:事件是流程中发生的事情,比如开始、结束或其他中间事件。 + * - **StartEvent**:标识流程的开始。 + * - **EndEvent**:标识流程的结束。 + * - **IntermediateCatchEvent**:用于处理流程中的等待和捕获事件。 + * - **BoundaryEvent**:附加到活动边界的事件,用于处理活动中的特定情况。 + * - **ThrowEvent**:用于抛出事件。 + * 这个层次结构允许流程定义具有各种复杂性,从简单的任务到复杂的子流程,每个元素都可以有它自己的行为和属性。 */ public abstract class FlowElement extends BaseElement implements HasExecutionListeners { + // 流程元素的名称 protected String name; + + // 流程元素的文档说明 protected String documentation; + + // 流程元素的执行监听器列表 protected List executionListeners = new ArrayList<>(); + + // 流程元素的父容器,可以是流程本身或子流程等 protected FlowElementsContainer parentContainer; + // 获取名称的方法 public String getName() { return name; } + // 设置名称的方法 public void setName(String name) { this.name = name; } + // 获取文档说明的方法 public String getDocumentation() { return documentation; } + // 设置文档说明的方法 public void setDocumentation(String documentation) { this.documentation = documentation; } + // 获取执行监听器的方法 @Override public List getExecutionListeners() { return executionListeners; } + // 设置执行监听器的方法 @Override public void setExecutionListeners(List executionListeners) { this.executionListeners = executionListeners; } + // 获取父容器的方法 @JsonIgnore public FlowElementsContainer getParentContainer() { return parentContainer; } + // 获取子流程的方法,如果父容器是子流程的话 @JsonIgnore public SubProcess getSubProcess() { SubProcess subProcess = null; @@ -68,13 +115,16 @@ public SubProcess getSubProcess() { return subProcess; } + // 设置父容器的方法 public void setParentContainer(FlowElementsContainer parentContainer) { this.parentContainer = parentContainer; } + // 抽象方法,用于克隆流程元素 @Override public abstract FlowElement clone(); + // 设置这个元素的属性为另一个 FlowElement 元素的属性的方法 public void setValues(FlowElement otherElement) { super.setValues(otherElement); setName(otherElement.getName()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElementsContainer.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElementsContainer.java index 2890b69bcc3..7cefeda7595 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElementsContainer.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowElementsContainer.java @@ -1,51 +1,124 @@ -/* Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package org.flowable.bpmn.model; import java.util.Collection; import java.util.Map; /** - * @author Tijs Rademakers + * FlowElementsContainer 接口定义了一个容器,用于存储和管理 BPMN 流程图中的流程元素和工件。 + * 它是所有包含流程元素(如流程定义、子流程等)的类的基础接口。 + + * 1. **SubProcess** : 这是一个通用的子流程,它自身是一个流程容器,可以包含其他流程元素,如任务、网关和事件。 + * 子流程是流程的一部分,它们可以在主流程中重复使用。 + * 2. **Transaction** : 这是特殊类型的子流程,模型化一个事务,其行为类似于数据库事务。 + * 事务子流程确保内部的所有活动要么全部完成,要么在出现错误时全部撤销。 + * 3. **EventSubProcess** : 这是一个在特定事件触发时开始执行的子流程。 + * 事件子流程不是流程的正常执行流的一部分,它可以在流程的任何点被触发。 + * 4. **AdhocSubProcess** : 这是一个非结构化的子流程,允许包含的活动没有严格的顺序。 + * 它用于建模不需要固定启动和结束点的活动集合。 + * 5. **Process** : 这代表了一个完整的BPMN流程,是最顶层的容器,包含一个完整的流程定义,可以包含子流程、任务、网关、事件以及其他流程元素。 + * 这些实现允许 Flowable 引擎创建复杂的流程结构,支持从简单的直线型流程到包含多层嵌套和复杂业务逻辑的流程。 + * 每种类型的 `FlowElementsContainer` 实现都有其特定用途和行为,以适应不同的业务需求和工作流程场景。 */ public interface FlowElementsContainer { + /** + * 根据 ID 获取流程元素。 + * + * @param id 流程元素的 ID。 + * @return 对应的流程元素,如果不存在则返回 null。 + */ FlowElement getFlowElement(String id); + /** + * 获取所有流程元素的集合。 + * + * @return 包含所有流程元素的集合。 + */ Collection getFlowElements(); - + + /** + * 获取以 ID 为键的流程元素映射。 + * + * @return 包含所有流程元素的映射。 + */ Map getFlowElementMap(); + /** + * 向容器中添加一个流程元素。 + * + * @param element 要添加的流程元素。 + */ void addFlowElement(FlowElement element); + /** + * 将一个流程元素添加到映射中。 + * + * @param element 要添加的流程元素。 + */ void addFlowElementToMap(FlowElement element); + /** + * 根据元素 ID 从容器中移除一个流程元素。 + * + * @param elementId 要移除的流程元素的 ID。 + */ void removeFlowElement(String elementId); + /** + * 从映射中移除一个流程元素。 + * + * @param elementId 要移除的流程元素的 ID。 + */ void removeFlowElementFromMap(String elementId); + /** + * 根据 ID 获取工件。 + * + * @param id 工件的 ID。 + * @return 对应的工件,如果不存在则返回 null。 + */ Artifact getArtifact(String id); + /** + * 获取所有工件的集合。 + * + * @return 包含所有工件的集合。 + */ Collection getArtifacts(); - + + /** + * 获取以 ID 为键的工件映射。 + * + * @return 包含所有工件的映射。 + */ Map getArtifactMap(); + /** + * 向容器中添加一个工件。 + * + * @param artifact 要添加的工件。 + */ void addArtifact(Artifact artifact); - + + /** + * 将一个工件添加到映射中。 + * + * @param artifact 要添加的工件。 + */ void addArtifactToMap(Artifact artifact); + /** + * 根据工件 ID 从容器中移除一个工件。 + * + * @param artifactId 要移除的工件的 ID。 + */ void removeArtifact(String artifactId); + /** + * 获取容器的 ID。 + * + * @return 容器的唯一标识符。 + */ String getId(); } diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowNode.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowNode.java index 17f8b54eab3..946a3fae05f 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowNode.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowNode.java @@ -19,18 +19,27 @@ import com.fasterxml.jackson.annotation.JsonIgnore; /** - * @author Tijs Rademakers - * @author Joram Barrez + * FlowNode 抽象类代表了 BPMN 流程图中的一个流程节点。 + * 它是所有流程节点(如任务、网关、事件等)的基础类,并提供了节点的基本属性和行为。 */ public abstract class FlowNode extends FlowElement { + // 表示节点是否是异步的 protected boolean asynchronous; + + // 表示节点离开时是否是异步的 protected boolean asynchronousLeave; + + // 表示节点是否是非独占的 protected boolean notExclusive; + // 节点的入口序列流列表 protected List incomingFlows = new ArrayList<>(); + + // 节点的出口序列流列表 protected List outgoingFlows = new ArrayList<>(); + // 节点的行为对象,可以用来定义节点特定的行为 @JsonIgnore protected Object behavior; @@ -94,6 +103,22 @@ public void setOutgoingFlows(List outgoingFlows) { this.outgoingFlows = outgoingFlows; } + /** + * 设置这个节点的属性为另一个 FlowNode 节点的属性。 + * 这个方法通常用于复制节点或在节点之间共享属性。 + + * 这个 `setValues` 方法的作用是将一个 `FlowNode` (流程节点)的属性复制到另一个 `FlowNode` 上。 + * 这个方法常用于在BPMN流程模型中复制或共享节点的属性。让我们用一个简单的方式来解释这个方法: + * 想象一下,在一个业务流程图中,你有一个特定的任务节点(比如审批任务),这个节点有一些特定的设置,比如它是异步的、非独占的,还有一些特定的入口和出口路径。 + * 现在,如果你想创建一个新的节点,这个新节点需要和原来的节点有完全相同的行为和路径设置。 + * 这时,你就可以使用 `setValues` 方法。你只需要传入原来的节点(`otherNode`),这个方法就会自动把所有的设置从原来的节点复制到新节点上。 + * 具体来说,它会做以下几件事情: + * 1. **复制基本属性**:比如节点是否是异步的、是否非独占的等。 + * 2. **复制入口流**:即复制所有指向这个节点的路径。 + * 3. **复制出口流**:即复制所有从这个节点出发的路径。 + * 通过这样做,你就可以很容易地创建一个与原来节点行为完全一样的新节点,而不需要手动设置每一个属性。 + * 这在流程设计中尤其有用,因为它可以节省大量的时间和避免重复劳动。 + */ public void setValues(FlowNode otherNode) { super.setValues(otherNode); setAsynchronous(otherNode.isAsynchronous()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowableListener.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowableListener.java index fcfefce8168..933ff7491a3 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowableListener.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/FlowableListener.java @@ -19,28 +19,41 @@ import com.fasterxml.jackson.annotation.JsonIgnore; /** - * @author Tijs Rademakers + * FlowableListener 类表示在流程执行过程中的特定事件上配置的监听器。 + * 这些监听器可以用于执行一些附加的自定义逻辑,如任务完成时发送通知。 */ public class FlowableListener extends BaseElement implements HasScriptInfo { + // 监听器触发的事件类型,如 'create'、'complete' 等 protected String event; + + // 监听器实现的类型,如 'class'、'expression'、'delegateExpression' 或 'script' protected String implementationType; + + // 实现的具体内容,取决于 implementationType 的值 protected String implementation; + + // 字段扩展列表,允许为监听器提供额外的参数 protected List fieldExtensions = new ArrayList<>(); + + // 与事务相关的监听器属性,定义监听器在事务的何种状态下被触发 protected String onTransaction; + + // 自定义属性解析器的实现类型 protected String customPropertiesResolverImplementationType; + + // 自定义属性解析器的具体实现 protected String customPropertiesResolverImplementation; + // 监听器的实例,可以直接设置,这样的话这个实例会被重复使用 @JsonIgnore - protected Object instance; // Can be used to set an instance of the listener directly. That instance will then always be reused. + protected Object instance; - /** - * ScriptInfo is populated for implementationType 'script' - */ + // 如果实现类型是 'script',这里会保存脚本的相关信息 protected ScriptInfo scriptInfo; + // 构造函数中生成一个随机的UUID作为监听器的唯一标识符 public FlowableListener() { - // Always generate a random identifier to look up the listener while executing the logic setId(UUID.randomUUID().toString()); } @@ -129,7 +142,7 @@ public ScriptInfo getScriptInfo() { public void setScriptInfo(ScriptInfo scriptInfo) { this.scriptInfo = scriptInfo; } - + // 克隆监听器的方法,用于创建此监听器的副本 @Override public FlowableListener clone() { FlowableListener clone = new FlowableListener(); @@ -137,6 +150,7 @@ public FlowableListener clone() { return clone; } + // 从另一个 FlowableListener 对象复制属性值的方法 public void setValues(FlowableListener otherListener) { super.setValues(otherListener); setEvent(otherListener.getEvent()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Gateway.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Gateway.java index bf23a594793..dd741b5edf1 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Gateway.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Gateway.java @@ -13,23 +13,46 @@ package org.flowable.bpmn.model; /** - * @author Tijs Rademakers + * Gateway 抽象类代表了 BPMN 流程图中的网关节点。 + * 网关用于控制流程的分支和合并,基于一定的条件来决定流程的走向。 + * Gateway 是所有具体网关类型的基类,例如排他网关、并行网关等。 + + * 在BPMN(业务流程模型和符号)中,网关是控制流程中分支和合并决策的元素。 + * 你可以把它们想象成流程图中的交通信号灯或路口指示牌,它们告诉流程在达到某个点时应该如何“决策”并选择接下来的路径。 + * 这里有几种常见的网关类型: + * 1. **排他网关(Exclusive Gateway)**:就像多个道路交汇处的一个交通信号灯,根据流量(在这里指的是流程条件)的不同,排他网关只允许流程沿着一个方向流动。 + * 比如,如果审批金额超过1000元,流程就会转向“高级审批”路径;如果不超过,就会转向“快速审批”路径。 + * 2. **并行网关(Parallel Gateway)**:这就像打开了多个收费站的通道,所有车辆(在这里指的是流程的分支)都可以同时通过。 + * 并行网关用于同时启动多个流程路径,或者在这些并行路径都完成时再次汇聚。 + * 3. **包容网关(Inclusive Gateway)**:想象一个大型停车场的出入口,它可以同时允许多辆车进入和离开,但不一定是所有的车辆。 + * 包容网关可以基于条件选择多条路径,也可以选择所有的路径。 + * 4. **复杂网关(Complex Gateway)**:这就像一个有着多个传感器和控制器的高级交通管理系统,它可以根据复杂的规则和条件来决定流量的走向。 + * 复杂网关用于处理更复杂的分支和合并逻辑,这些逻辑通常无法通过其他网关类型来实现。 + * 5. **事件网关(Event Gateway)**:可以将其视为一种特殊类型的网关,它基于事件的发生来决定流程的路径。 + * 比如,它可能等待一个定时事件,当时间到达时,流程就会向特定的方向流动。 + * 网关在BPMN流程中非常重要,它们确保流程可以根据业务规则和逻辑正确地执行。 */ public abstract class Gateway extends FlowNode { + // 默认流属性,用于在网关分支条件都不满足时,提供一个默认的执行流程路径 protected String defaultFlow; + // 获取默认流属性的方法 public String getDefaultFlow() { return defaultFlow; } + // 设置默认流属性的方法 public void setDefaultFlow(String defaultFlow) { this.defaultFlow = defaultFlow; } + // 抽象方法,用于克隆网关节点 @Override public abstract Gateway clone(); + // 设置这个网关的属性为另一个 Gateway 的属性 + // 该方法用于复制网关节点或在网关之间共享属性 public void setValues(Gateway otherElement) { super.setValues(otherElement); setDefaultFlow(otherElement.getDefaultFlow()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/HasExtensionAttributes.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/HasExtensionAttributes.java index 1c250e40c7b..20dca18cf4e 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/HasExtensionAttributes.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/HasExtensionAttributes.java @@ -16,26 +16,45 @@ import java.util.Map; /** - * Interface for accessing Element attributes. - * - * @author Martin Grofcik + * HasExtensionAttributes 接口用于访问和管理BPMN元素的扩展属性。 + * 扩展属性允许用户在BPMN元素上添加额外的信息,这些信息不是BPMN标准的一部分。 */ public interface HasExtensionAttributes { - /** get element's attributes */ + + /** + * 获取元素的所有扩展属性。 + * + * @return 包含扩展属性的Map,键是属性名称,值是包含扩展属性的列表。 + */ Map> getAttributes(); /** - * return value of the attribute from given namespace with given name. - * - * @param namespace - * @param name - * @return attribute value or null in case when attribute was not found + * 根据命名空间和名称获取特定的属性值。 + * + * @param namespace 命名空间URI,如果属性没有命名空间,则为null。 + * @param name 属性的本地名称。 + * @return 属性的值,如果找不到对应的属性,则返回null。 + + * 命名空间在XML和与之相关的技术中是一个重要的概念,用于避免元素或属性名的冲突。 + * 它类似于在现实生活中的姓氏,有助于区分同名的不同人。在编程或标记语言中,命名空间用于区分具有相同名称但不同来源或意义的元素或属性。 + * 例如,在BPMN(业务流程模型和符号)模型中,可能会有来自不同组织或标准的扩展属性。 + * 为了区分这些属性,每个组织可以定义自己的命名空间URI(统一资源标识符),这样即使属性名称相同,由于它们属于不同的命名空间,也可以被视为完全不同的属性。 + * 命名空间URI通常看起来像网址,但它们实际上并不需要指向任何实际的网络位置,它们仅作为一个独一无二的标识符。 + * 在 `getAttributeValue` 方法的上下文中,如果你知道一个属性属于特定的命名空间,你可以使用这个命名空间URI和属性名称来准确地获取该属性的值。 */ String getAttributeValue(String namespace, String name); - /** add attribute to the object */ + /** + * 向元素添加一个扩展属性。 + * + * @param attribute 要添加的扩展属性对象。 + */ void addAttribute(ExtensionAttribute attribute); - /** set all object's attributes */ + /** + * 设置元素的所有扩展属性。 + * + * @param attributes 包含要设置的扩展属性的Map。 + */ void setAttributes(Map> attributes); } diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/MultiInstanceLoopCharacteristics.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/MultiInstanceLoopCharacteristics.java index ad6fde117a9..bf6f1c1c60f 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/MultiInstanceLoopCharacteristics.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/MultiInstanceLoopCharacteristics.java @@ -13,21 +13,39 @@ package org.flowable.bpmn.model; /** - * @author Tijs Rademakers - * @author Joram Barrez + * MultiInstanceLoopCharacteristics 类表示 BPMN 流程图中的多实例循环特性。 + * 这些特性定义了一个活动如何重复执行,以及如何处理这些重复执行的实例。 */ public class MultiInstanceLoopCharacteristics extends BaseElement { + // 用于多实例循环的输入数据项 protected String inputDataItem; + + // 一个表达式或变量,定义了包含多实例集合的字符串 protected String collectionString; + + // 处理集合的处理器 protected CollectionHandler collectionHandler; + + // 循环的基数,定义了多实例循环将执行的次数 protected String loopCardinality; + + // 完成条件,定义了多实例循环何时停止 protected String completionCondition; + + // 每个循环实例的元素变量 protected String elementVariable; + + // 每个循环实例的索引变量 protected String elementIndexVariable; + + // 指示循环是否顺序执行 protected boolean sequential; + + // 指示在异步离开时是否没有等待状态 protected boolean noWaitStatesAsyncLeave; + // 变量聚合定义,定义了多实例循环结束时如何聚合变量 protected VariableAggregationDefinitions aggregations; public String getInputDataItem() { @@ -125,6 +143,9 @@ public MultiInstanceLoopCharacteristics clone() { return clone; } + /** + * 设置这个多实例循环特性对象的属性为另一个对象的属性。 + */ public void setValues(MultiInstanceLoopCharacteristics otherLoopCharacteristics) { super.setValues(otherLoopCharacteristics); setInputDataItem(otherLoopCharacteristics.getInputDataItem()); diff --git a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Process.java b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Process.java index 6367a410ac4..0ed6925a045 100644 --- a/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Process.java +++ b/modules/flowable-bpmn-model/src/main/java/org/flowable/bpmn/model/Process.java @@ -21,30 +21,68 @@ import org.apache.commons.lang3.StringUtils; /** - * @author Tijs Rademakers - * @author Joram Barrez + * Process 类表示一个完整的BPMN流程定义。 + * 它包含了流程中的所有元素,包括活动、网关、事件、数据对象以及候选启动者等。 */ public class Process extends BaseElement implements FlowElementsContainer, HasExecutionListeners { + // 流程的名称 protected String name; + + // 指示流程是否可执行的标志 protected boolean executable = true; + + // 流程的文档描述 protected String documentation; + + // 流程的输入输出规范 protected IOSpecification ioSpecification; + + // 流程的执行监听器列表 protected List executionListeners = new ArrayList<>(); + + /** + * 流程的泳道列表 + * 在BPMN(业务流程模型和符号)中,泳道(Lane)是一种用于组织和分类流程中的活动的工具。 + + * 你可以把泳道想象成一个游泳池中的分道线,每条泳道可以代表一个特定的部门、角色、系统或参与者,它们负责流程中的不同活动或任务。 + * 举个例子,想象一个典型的采购流程,这个流程可能包括三个主要参与者:申请人、审批人和采购部门。在流程图中,你可以为每个参与者创建一个泳道: + * - **申请人泳道**:包含提交采购请求的活动。 + * - **审批人泳道**:包含审批或拒绝请求的活动。 + * - **采购部门泳道**:包含执行采购订单和管理供应商关系的活动。 + * 使用泳道的好处是,它可以清晰地显示哪些活动是由哪个部门或个人负责,使得流程的职责分工一目了然。 + * 这有助于简化流程理解和沟通,同时确保每个任务都有明确的责任主体。在流程管理系统中,泳道还可以用来控制权限,确保只有相关责任人才能看到或执行特定的任务。 + */ protected List lanes = new ArrayList<>(); + + // 流程的流程元素列表 protected List flowElementList = new ArrayList<>(); + + // 流程的数据对象列表 protected List dataObjects = new ArrayList<>(); + + // 流程的工件列表 protected List artifactList = new ArrayList<>(); + + // 流程的候选启动用户列表 protected List candidateStarterUsers = new ArrayList<>(); + + // 流程的候选启动组列表 protected List candidateStarterGroups = new ArrayList<>(); + + // 流程的事件监听器列表 protected List eventListeners = new ArrayList<>(); + + // 流程元素的映射(id -> 元素) protected Map flowElementMap = new LinkedHashMap<>(); + + // 工件的映射(id -> 工件) protected Map artifactMap = new LinkedHashMap<>(); - // Added during process definition parsing + // 在流程定义解析期间添加的初始流程元素 protected FlowElement initialFlowElement; - - // Performance settings + + // 性能设置:是否启用急切的执行树获取 protected boolean enableEagerExecutionTreeFetching; public Process() { @@ -377,6 +415,7 @@ public Process clone() { return clone; } + // 从另一个 Process 对象复制属性值的方法 public void setValues(Process otherElement) { super.setValues(otherElement); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/FlowNodeActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/FlowNodeActivityBehavior.java index ea384ad9227..6b579bec4a0 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/FlowNodeActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/FlowNodeActivityBehavior.java @@ -42,6 +42,16 @@ public void execute(DelegateExecution execution) { /** * 离开 BPMN 2.0 活动的默认方式:评估出去序列流上的条件,并且对那些评估为 true 的流进行流转。 + * 这个 `leave` 方法的注释描述了它在 BPMN 2.0(业务流程模型和符号)流程中的作用。让我们用一个简单的方式来解释这个方法: + * 当一个流程在 BPMN 中的某个活动(比如一个任务或决策节点)完成后,它需要决定下一步往哪个方向走。 + * 在 BPMN 中,一个活动可能有多个出口,这些出口被称为“序列流”。 + * 这些序列流可以有条件,比如:“如果任务完成,则沿着这条路径继续”或“如果满足某个条件,则走另一条路径”。 + * `leave` 方法的作用就是来决定在一个活动完成后,流程应该沿哪些路径继续前进。具体来说,它会做以下几件事: + * 1. 查看所有从这个活动出发的序列流。 + * 2. 对每个序列流上的条件进行评估。 + * 3. 对那些条件评估结果为真(true)的序列流进行流转,也就是沿这些路径继续流程。 + * 举个例子,想象一个流程中有一个“审批”活动,从这个活动出发有两条路径:一条是在审批通过时走的,另一条是审批未通过时走的。 + * `leave` 方法就会检查审批的结果,然后决定是继续沿着“通过”路径走,还是沿着“未通过”路径走。 */ public void leave(DelegateExecution execution) { bpmnActivityBehavior.performDefaultOutgoingBehavior((ExecutionEntity) execution); @@ -57,6 +67,22 @@ public void leaveIgnoreConditions(DelegateExecution execution) { /** * 触发方法:默认情况下抛出异常,表明此活动不等待触发。 * 需要接受信号的具体活动行为应该重写这个方法。 + * + * 这个 `trigger` 方法的注释描述了它在业务流程中的作用,尤其是在处理信号和事件方面。让我们用一个通俗的方式来解释这个方法: + * 在业务流程管理(BPM)中,有些活动可能需要外部的触发来继续执行,比如等待一个特定的信号或事件。 + * 这种外部触发通常用于控制流程的流转,尤其是在涉及到异步事件或消息时。 + * 注释中的“触发方法”指的是这个方法被设计用来响应这类外部的信号或事件。 + * 以下是这个方法的一些关键点: + * 1. 默认行为:这个方法的默认实现是直接抛出一个异常,表明当前的活动不是设计来等待外部的触发。 + * 这意味着如果这个方法在没有被重写的情况下被调用,它会指出当前活动并不期望或不处理任何外部信号。 + * 2. 重写方法:注释中提到,如果有具体的活动行为需要接受外部信号(如等待一个特定的消息或事件),那么这个方法应该被重写。 + * 重写的方法将包含处理信号的逻辑,例如在接收到信号后继续执行流程,或者根据信号数据做出特定的动作。 + * 3. 参数解释: + * - `DelegateExecution execution`:当前的执行上下文,提供了流程实例的状态和变量。 + * - `String signalName`:触发此方法的信号的名称。 + * - `Object signalData`:与信号相关的额外数据或信息。 + * 简单来说,这个 `trigger` 方法就像是一个等待接收特定信号的监听器。 + * 在流程的标准实现中,它默认不做任何事情(即不接收任何信号),但如果某个流程活动需要对特定的外部事件做出反应,那么这个方法可以被重写以处理这些事件。 */ @Override public void trigger(DelegateExecution execution, String signalName, Object signalData) {