/**
* Copyright 1996-2014 FoxBPM ORG.
*
* 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.
*
* @author kenshin
*/
package org.foxbpm.kernel.runtime.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.foxbpm.kernel.KernelException;
import org.foxbpm.kernel.event.KernelEvent;
import org.foxbpm.kernel.process.KernelBaseElement;
import org.foxbpm.kernel.process.KernelFlowNode;
import org.foxbpm.kernel.process.KernelProcessDefinition;
import org.foxbpm.kernel.process.KernelSequenceFlow;
import org.foxbpm.kernel.process.impl.KernelFlowNodeImpl;
import org.foxbpm.kernel.process.impl.KernelProcessDefinitionImpl;
import org.foxbpm.kernel.process.impl.KernelSequenceFlowImpl;
import org.foxbpm.kernel.runtime.FlowNodeExecutionContext;
import org.foxbpm.kernel.runtime.InterpretableExecutionContext;
import org.foxbpm.kernel.runtime.KernelProcessInstance;
import org.foxbpm.kernel.runtime.KernelToken;
import org.foxbpm.kernel.runtime.ListenerExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KernelTokenImpl extends KernelVariableScopeImpl implements FlowNodeExecutionContext, ListenerExecutionContext, KernelToken,
InterpretableExecutionContext {
private static Logger LOG = LoggerFactory.getLogger(KernelTokenImpl.class);
/**
*
*/
private static final long serialVersionUID = 1L;
protected KernelProcessInstanceImpl processInstance;
protected boolean isEnded = false;
protected boolean isActive = true;
protected KernelFlowNodeImpl currentFlowNode;
/**
* 临时需要跳转的节点
*/
protected KernelFlowNodeImpl toFlowNode;
protected String name;
protected KernelTokenImpl parent;
protected boolean isLocked = false;
protected boolean isSuspended = false;
protected boolean isSubProcessRootToken = false;
protected KernelSequenceFlowImpl sequenceFlow;
protected KernelProcessDefinitionImpl processDefinition;
/**
* 子令牌集合
*/
protected List<KernelTokenImpl> children;
protected HashMap<String, KernelTokenImpl> namedChildren = new HashMap<String, KernelTokenImpl>();
// 事件 ///////////////////////////////////////////////////////////////////
protected String eventName;
protected KernelBaseElement eventSource;
protected int KernelListenerIndex = 0;
protected KernelEvent nextEvent;
protected boolean isOperating = false;
protected Map<String, Object> properties;
public KernelFlowNodeImpl getFlowNode() {
ensureFlowNodeInitialized();
return currentFlowNode;
}
/** 子类需要重写这个类 */
protected void ensureFlowNodeInitialized() {
// TODO Auto-generated method stub
}
public void setFlowNode(KernelFlowNodeImpl flowNode) {
this.currentFlowNode = flowNode;
}
public String getId() {
return null;
}
public KernelProcessInstanceImpl getProcessInstance() {
ensureProcessInstanceInitialized();
return processInstance;
}
/** 子类需要重写这个方法 */
protected void ensureProcessInstanceInitialized() {
// TODO Auto-generated method stub
}
public void setProcessInstance(KernelProcessInstanceImpl processInstance) {
this.processInstance = processInstance;
}
public void ensureEnterInitialized(KernelFlowNodeImpl flowNode) {
/** 设置令牌所在节点 */
setFlowNode(flowNode);
}
public void enter(KernelFlowNodeImpl flowNode) {
LOG.debug("进入节点: {}({}),令牌号: {}({}).", flowNode.getName(), flowNode.getId(), getName(), getId());
/** 移除临时执行内容对象 */
clearExecutionContextData();
/** 初始化节点进入参数 */
ensureEnterInitialized(flowNode);
/** 触发节点进入事件 */
fireEvent(KernelEvent.NODE_ENTER);
/** 执行节点行为 */
flowNode.getKernelFlowNodeBehavior().enter(this);
}
public void execute() {
fireEvent(KernelEvent.NODE_EXECUTE);
getFlowNode().getKernelFlowNodeBehavior().execute(this);
}
public void signal() {
getFlowNode().getKernelFlowNodeBehavior().leave(this);
}
public void signal(KernelFlowNodeImpl flowNode) {
signal(flowNode,true);
}
public void signal(KernelFlowNodeImpl flowNode,boolean nowFlowNodeCleanData) {
if (flowNode != null) {
if(nowFlowNodeCleanData){
getFlowNode().getKernelFlowNodeBehavior().cleanData(this);
}
setFlowNode(flowNode);
flowNode.getKernelFlowNodeBehavior().leave(this);
} else {
throw new KernelException("目标节点为空。");
}
}
public void fireEvent(KernelEvent kernelEvent) {
this.nextEvent = kernelEvent;
if (!isOperating) {
isOperating = true;
while (nextEvent != null) {
KernelEvent currentEvent = this.nextEvent;
this.nextEvent = null;
currentEvent.execute(this);
}
isOperating = false;
}
}
public Integer getKernelListenerIndex() {
return KernelListenerIndex;
}
public void setKernelListenerIndex(int kernelListenerIndex) {
KernelListenerIndex = kernelListenerIndex;
}
/*** 默认离开,验证每个线条。 */
public void leave() {
// 定义可通过线条集合
List<KernelSequenceFlow> sequenceFlowList = new ArrayList<KernelSequenceFlow>();
// 并行网关会忽略掉后面的线条的条件
// 获取正常离开的所有线条
for (KernelSequenceFlow sequenceFlow : getFlowNode().getOutgoingSequenceFlows()) {
// 验证线条上的条件
if (sequenceFlow.isContinue(this)) {
sequenceFlowList.add(sequenceFlow);
}
}
leave(sequenceFlowList);
}
/*** 根据指定的线条离开 */
public void leave(KernelSequenceFlow sequenceFlow) {
List<KernelSequenceFlow> sequenceFlows = new ArrayList<KernelSequenceFlow>();
sequenceFlows.add(sequenceFlow);
leave(sequenceFlows);
}
/*** 根据指定的线条离开 */
public void leave(List<KernelSequenceFlow> sequenceFlowList) {
// 发生节点离开事件
fireEvent(KernelEvent.NODE_LEAVE);
KernelFlowNodeImpl flowNode = getFlowNode();
// 执行线条的进入方法
flowNode.getKernelFlowNodeBehavior().cleanData(this);
// kenshin 2013.1.2
// 用来处理非线条流转令牌,如退回、跳转
if (this.toFlowNode != null) {
// 发现上下文中有直接跳转节点,则流程引擎不走正常处理直接跳转到指定借点。
LOG.debug("==执行跳转机制,跳转目标: {}({}),离开节点: {}({}),令牌号: {}({}).", toFlowNode.getName(), toFlowNode.getId(), flowNode.getName(),
flowNode.getId(), this.getName(), this.getId());
enter(toFlowNode);
setToFlowNode(null);
return;
}
// 节点后面没有线的处理
if (sequenceFlowList == null || sequenceFlowList.size() == 0) {
if (flowNode.getOutgoingSequenceFlows().size() == 0) {
throw new KernelException("节点: " + flowNode.getName() + "(" + flowNode.getId() + ") 后面没有配置处理线条!");
} else {
throw new KernelException("节点: " + flowNode.getName() + "(" + flowNode.getId() + ") 后面的条件都不满足导致节点后面没有处理线条,请检查后续线条条件!");
}
}
// 节点后面就一条线的处理
if (sequenceFlowList.size() == 1) {
take(sequenceFlowList.get(0));
return;
}
// 节点后面大于一条线的处理
if (sequenceFlowList.size() > 1) {
takeAll(sequenceFlowList);
return;
}
}
/** 清理令牌数据 */
public void clearExecutionContextData() {
this.setSequenceFlow(null);
this.setToFlowNode(null);
}
// 分支处理///////////////////////////////
public ForkedToken createForkedToken(KernelTokenImpl parent, String sequenceFlowId) {
// 创建一个令牌实例
KernelTokenImpl childToken = getProcessInstance().createChildrenToken(parent);
childToken.setName(sequenceFlowId);
// 创建分支令牌
ForkedToken forkedToken = null;
forkedToken = new ForkedToken(childToken, sequenceFlowId);
return forkedToken;
}
public static class ForkedToken {
public KernelTokenImpl token = null;
String leavingSequenceFlowId = null;
public ForkedToken(KernelTokenImpl token, String leavingSequenceFlowId) {
this.token = token;
this.leavingSequenceFlowId = leavingSequenceFlowId;
}
}
public void take(KernelSequenceFlow sequenceFlow) {
sequenceFlow.take(this);
}
public void takeAll(List<KernelSequenceFlow> sequenceFlows) {
// 节点后面就一条线的处理
if (sequenceFlows.size() == 1) {
take(sequenceFlows.get(0));
return;
}
// 创建分支令牌集合
ArrayList<ForkedToken> forkedTokens = new ArrayList<ForkedToken>();
// 这里为什么做两个遍历,因为一定要在令牌都生成出来之后才能进行线条的take
// 遍历满足条件线条
for (KernelSequenceFlow sequenceFlow : sequenceFlows) {
// 获取线条名称
String sequenceFlowId = sequenceFlow.getId();
// 创建分支令牌并添加到集合中
forkedTokens.add(this.createForkedToken(this, sequenceFlowId));
}
// 遍历分支令牌集合
for (ForkedToken forkedToken : forkedTokens) {
// 获取令牌
KernelTokenImpl childToken = forkedToken.token;
// 获取令牌编号
String leavingSequenceFlowId = forkedToken.leavingSequenceFlowId;
// 执行节点离开方法
childToken.take(this.getFlowNode().findOutgoingSequenceFlow(leavingSequenceFlowId));
}
}
public void take(KernelFlowNodeImpl flowNode) {
enter(flowNode);
}
public void end() {
end(true);
}
public void end(boolean verifyParentTermination) {
// 如果令牌已经有结束时间则不执行令牌结束方法
if (!isEnded()) {
// 结束令牌.使他不能再启动父令牌
setActive(false);
// 结束日期的标志,表明此令牌已经结束。
setEnded(true);
// 结束所有子令牌
if (getChildren() != null) {
List<KernelTokenImpl> childrenTokens = getChildren();
for (KernelTokenImpl childrenToken : childrenTokens) {
if (!childrenToken.isEnded()) {
childrenToken.end(false);
}
}
}
// 清理当前节点遗留信息
getFlowNode().getKernelFlowNodeBehavior().cleanData(this);
if (verifyParentTermination) {
// 如果这是根令牌,则需要结束流程实例.
notifyParentOfTokenEnd();
}
}
}
protected void notifyParentOfTokenEnd() {
// 判断是否为根令牌
if (isRoot()) {
getProcessInstance().end();
} else {
if (getParent() != null) {
// 下面这句话是用来当前存在分支时 一个分支走到结束另一个分支没结束的时候,不能结束他的父令牌
// 只有当到达结束节点的令牌的同级分支都结束才能结束父令牌
// 子流程多实例的时候 每个子流程结束的时候去触发验证完成条件
if (isSignalParentToken()) {
// 推动父令牌向后执行
getParent().signal();
} else {
if (!getParent().hasActiveChildren()) {
getParent().end();
}
}
}
}
}
/** 获取所有的父令牌 */
public List<KernelTokenImpl> getAllParent() {
List<KernelTokenImpl> tokenList = new ArrayList<KernelTokenImpl>();
if(this.getParent()!=null){
recursionTokenParent(this.getParent(), tokenList);
}
return tokenList;
}
/** 递归流程父亲令牌 */
private static void recursionTokenParent(KernelTokenImpl token, List<KernelTokenImpl> tokenList) {
tokenList.add(token);
if (token.getParent() != null) {
recursionTokenParent(token.getParent(), tokenList);
}
}
/** 子类需要重写这个方法 */
protected boolean isSignalParentToken() {
return false;
}
public boolean hasActiveChildren() {
boolean foundActiveChildToken = false;
// 发现至少有一个子令牌,仍然活跃(没有结束.
List<KernelTokenImpl> childrenTokens = getChildren();
if (childrenTokens.size() > 0) {
for (KernelTokenImpl childrenToken : childrenTokens) {
if (childrenToken.isActive()) {
foundActiveChildToken = true;
return foundActiveChildToken;
}
}
}
return foundActiveChildToken;
}
/** 阻止令牌 */
public void inactivate() {
this.isActive = false;
}
public boolean isEnded() {
return isEnded;
}
public void setEnded(boolean isEnded) {
this.isEnded = isEnded;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
public boolean isActive() {
return isActive;
}
public String getEventName() {
return eventName;
}
public void setEventName(String eventName) {
this.eventName = eventName;
}
public KernelBaseElement getEventSource() {
return eventSource;
}
public void setEventSource(KernelBaseElement eventSource) {
this.eventSource = eventSource;
}
public KernelProcessDefinitionImpl getProcessDefinition() {
return getProcessInstance().getProcessDefinition();
}
public boolean isRoot() {
return (getParent() == null);
}
/** 子类需要重写这个方法从持久层拿父令牌 */
protected void ensureParentInitialized() {
}
public KernelTokenImpl getParent() {
ensureParentInitialized();
return parent;
}
public void setParent(KernelTokenImpl parent) {
this.parent = parent;
}
protected void ensureChildrenInitialized() {
}
public List<KernelTokenImpl> getChildren() {
ensureChildrenInitialized();
return children;
}
/** 获取所有的子令牌 */
public List<KernelTokenImpl> getAllChildren() {
List<KernelTokenImpl> tokenList = new ArrayList<KernelTokenImpl>();
for (KernelTokenImpl kernelTokenImpl : getChildren()) {
recursionTokenChildren(kernelTokenImpl, tokenList);
}
return tokenList;
}
/** 递归流程子令牌 */
private static void recursionTokenChildren(KernelTokenImpl token, List<KernelTokenImpl> tokenList) {
tokenList.add(token);
for (KernelTokenImpl kernelTokenImpl : token.getChildren()) {
recursionTokenChildren(kernelTokenImpl, tokenList);
}
}
public void setChildren(List<KernelTokenImpl> children) {
this.children = children;
}
public void addChild(KernelTokenImpl token) {
if (token != null) {
getChildren().add(token);
if (token.getId() != null) {
if (namedChildren.containsKey(token.getId())) {
throw new KernelException("令牌 " + token.getId() + "已经存在,无法加入");
}
namedChildren.put(token.getId(), token);
}
}
}
/** 终止所有子令牌 */
public void terminationChildToken() {
// 如果令牌已经有结束时间则不执行令牌结束方法
if (!isEnded()) {
// 结束所有子令牌
if (getChildren() != null) {
for (KernelTokenImpl child : getChildren()) {
child.end(false);
}
}
}
}
public KernelSequenceFlowImpl getSequenceFlow() {
return sequenceFlow;
}
public void setSequenceFlow(KernelSequenceFlowImpl sequenceFlow) {
this.sequenceFlow = sequenceFlow;
}
public void setProperty(String name, Object value) {
if (properties == null) {
properties = new HashMap<String, Object>();
}
properties.put(name, value);
}
public Object getProperty(String name) {
if (properties == null) {
return null;
}
return properties.get(name);
}
@SuppressWarnings("unchecked")
public Map<String, Object> getProperties() {
if (properties == null) {
return Collections.EMPTY_MAP;
}
return properties;
}
public void setProperties(Map<String, Object> properties) {
this.properties = properties;
}
public KernelFlowNodeImpl getToFlowNode() {
return toFlowNode;
}
public void setToFlowNode(KernelFlowNodeImpl toFlowNode) {
this.toFlowNode = toFlowNode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setSubProcessRootToken(boolean isSubProcessRootToken) {
this.isSubProcessRootToken = isSubProcessRootToken;
}
public String getProcessInstanceId() {
return getProcessInstance().getId();
}
public Object getVariableLocal(Object variableName) {
// TODO Auto-generated method stub
return null;
}
public List<KernelTokenImpl> findInactiveToken(KernelFlowNode flowNode) {
List<KernelTokenImpl> inactiveTokenInActivity = new ArrayList<KernelTokenImpl>();
List<KernelTokenImpl> otherToken = new ArrayList<KernelTokenImpl>();
List<? extends KernelTokenImpl> tokenChildren = getParent().getChildren();
for (KernelTokenImpl token : tokenChildren) {
if (token.getFlowNode().getId().equals(flowNode.getId())) {
if (!token.isActive()) {
inactiveTokenInActivity.add(token);
}
} else {
otherToken.add(token);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("非激活的令牌 在 '{}': {}", flowNode, inactiveTokenInActivity);
LOG.debug("激活的令牌 : {}", otherToken);
}
return inactiveTokenInActivity;
}
public FlowNodeExecutionContext createChildrenToken() {
KernelTokenImpl createdToken = getProcessInstance().createChildrenToken(this);
return createdToken;
}
public KernelProcessInstance createSubProcessInstance(KernelProcessDefinition processDefinition) {
KernelProcessInstance processInstance = getProcessInstance().createSubProcessInstance(
(KernelProcessDefinitionImpl) processDefinition, this);
return processInstance;
}
public void setProcessDefinition(KernelProcessDefinitionImpl processDefinition) {
this.processDefinition = processDefinition;
}
public boolean isLocked() {
return isLocked;
}
public void setLocked(boolean isLocked) {
this.isLocked = isLocked;
}
public boolean isSuspended() {
return isSuspended;
}
public void setSuspended(boolean isSuspended) {
this.isSuspended = isSuspended;
}
public void suspendToken(){
setSuspended(true);
}
public void continueToken(){
setSuspended(false);
}
}