/**
* 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.List;
import java.util.Map;
import java.util.UUID;
import org.foxbpm.kernel.KernelException;
import org.foxbpm.kernel.event.KernelEvent;
import org.foxbpm.kernel.process.impl.KernelFlowNodeImpl;
import org.foxbpm.kernel.process.impl.KernelProcessDefinitionImpl;
import org.foxbpm.kernel.runtime.InterpretableProcessInstance;
import org.foxbpm.kernel.runtime.KernelProcessInstance;
import org.foxbpm.kernel.runtime.ProcessInstanceStatus;
public class KernelProcessInstanceImpl extends KernelVariableScopeImpl implements InterpretableProcessInstance {
/**
*
*/
private static final long serialVersionUID = 1L;
protected KernelProcessDefinitionImpl processDefinition;
protected KernelTokenImpl rootToken;
protected KernelFlowNodeImpl startFlowNode;
/** 流程令牌集合 */
protected List<KernelTokenImpl> tokens;
/** 流程实例状态 */
protected String instanceStatus;
// 父流程
protected KernelProcessInstanceImpl parentProcessInstance;
// 父流程实例令牌
protected KernelTokenImpl parentProcessInstanceToken;
protected boolean isEnded = false;
/** 是否暂停 */
protected boolean isSuspended = false;
public boolean isSuspended() {
return isSuspended;
}
public void setSuspended(boolean isSuspended) {
this.isSuspended = isSuspended;
}
/**
* 获取父流程实例
*
* @return
*/
public KernelProcessInstanceImpl getParentProcessInstance() {
ensureParentProcessInstanceInitialized();
return parentProcessInstance;
}
/**
* 设置父流程实例
*
* @param parentProcessInstance
* 父流程实例
*/
public void setParentProcessInstance(KernelProcessInstanceImpl parentProcessInstance) {
this.parentProcessInstance = parentProcessInstance;
}
public void ensureParentProcessInstanceTokenInitialized() {
}
public KernelTokenImpl getParentProcessInstanceToken() {
ensureParentProcessInstanceTokenInitialized();
return parentProcessInstanceToken;
}
public void setParentProcessInstanceToken(KernelTokenImpl parentProcessInstanceToken) {
this.parentProcessInstanceToken = parentProcessInstanceToken;
}
// 需要重写这个方法从持久层拿
protected void ensureParentProcessInstanceInitialized() {
}
public KernelProcessInstanceImpl() {
this(null);
}
public KernelProcessInstanceImpl(KernelFlowNodeImpl flowNode) {
// 设置流程实例启动的节点
this.startFlowNode = flowNode;
}
public KernelTokenImpl createRootToken() {
if (rootToken == null) {
this.rootToken = createToken();
this.rootToken.setProcessInstance(this);
return this.rootToken;
} else {
throw new KernelException("跟令牌已经存在,不能再次创建!");
}
}
/** 子类需要重写这个方法 */
public KernelTokenImpl createToken() {
KernelTokenImpl token = new KernelTokenImpl();
// 创建根令牌
addToken(token);
return token;
}
/** 子类需要重写这个方法创建自己的ID */
public String createTokenId() {
return UUID.randomUUID().toString();
}
/** 创建子令牌 */
public KernelTokenImpl createChildrenToken(KernelTokenImpl parent) {
KernelTokenImpl childrenToken = createToken();
// 设置令牌的流程实例对象
childrenToken.setProcessInstance(this);
childrenToken.setProcessDefinition(getProcessDefinition());
// 设置令牌所在的节点
childrenToken.setFlowNode(parent.getFlowNode());
childrenToken.setParent(parent);
List<KernelTokenImpl> children = parent.getChildren();
if(children == null){
children = new ArrayList<KernelTokenImpl>();
parent.setChildren(children);
}
children.add(childrenToken);
// 将生成的新节点放入流程实例令牌列表中
// addToken(childrenToken);
return childrenToken;
}
public void signal() {
getRootToken().signal();
}
public void signal(String tokenId) {
// getTokens 没有子类重写所以直接调用属性
if(tokenId==null||tokenId.equals("")){
throw new KernelException("需要驱动的令牌编号为空!");
}
if (tokens != null && tokens.size() > 0) {
for (KernelTokenImpl kernelTokenImpl : tokens) {
if (kernelTokenImpl.getId().equals(tokenId)) {
kernelTokenImpl.signal();
return;
}
}
}
// 异常
}
/** 启动流程实例 */
public void start() {
KernelTokenImpl tempToken = getRootToken();
if (tempToken.getFlowNode() == null) {
// 触发流程实例启动事件
tempToken.fireEvent(KernelEvent.PROCESS_START);
// 将令牌放置到开始节点中
tempToken.enter(startFlowNode);
} else {
throw new KernelException("流程实例已经启动!");
}
}
/** 创建一个流程实例,子类需要重写他 */
protected KernelProcessInstanceImpl newProcessInstance() {
return new KernelProcessInstanceImpl();
}
public KernelProcessInstance createSubProcessInstance(KernelProcessDefinitionImpl processDefinition) {
return createSubProcessInstance(processDefinition, this.rootToken);
}
public KernelProcessInstance createSubProcessInstance(KernelProcessDefinitionImpl processDefinition, KernelTokenImpl token) {
KernelProcessInstanceImpl subProcessInstance = (KernelProcessInstanceImpl) processDefinition
.createProcessInstanceForInitial(processDefinition.getInitial());
subProcessInstance.setParentProcessInstance(this);
subProcessInstance.setParentProcessInstanceToken(token);
return subProcessInstance;
}
/** 这个方法需要子类重写 */
public void initialize() {
createRootToken();
}
/** 这个方法需要子类重写 */
public String getId() {
return null;
}
/** 子类需要重写这个方法从持久层拿令牌 */
public void ensureRootTokenInitialized() {
}
public KernelTokenImpl getRootToken() {
ensureRootTokenInitialized();
return rootToken;
}
public KernelProcessDefinitionImpl getProcessDefinition() {
ensureProcessDefinitionInitialized();
return processDefinition;
}
/** 子类需要重写这个方法从持久层拿流程定义 */
public void ensureProcessDefinitionInitialized() {
}
public void setProcessDefinition(KernelProcessDefinitionImpl processDefinition) {
this.processDefinition = processDefinition;
}
public List<KernelTokenImpl> getTokens() {
ensureTokensInitialized();
return tokens;
}
/** 实例令牌集合初始化 子类需要重写 */
protected void ensureTokensInitialized() {
if (tokens == null) {
tokens = new ArrayList<KernelTokenImpl>();
}
}
public void addToken(KernelTokenImpl token) {
ensureTokensInitialized();
if (tokens != null) {
tokens.add(token);
}
}
public void setTokens(List<KernelTokenImpl> tokens) {
this.tokens = tokens;
}
public boolean isEnded() {
return isEnded;
}
public boolean hasVariable(String variableName) {
return false;
}
public void setVariable(String variableName, Object value) {
// TODO Auto-generated method stub
}
public Object getVariable(String variableName) {
// TODO Auto-generated method stub
return null;
}
public Map<String, Object> getVariables() {
// TODO Auto-generated method stub
return null;
}
public void deleteCascade(String deleteReason) {
// TODO Auto-generated method stub
}
public void end() {
this.instanceStatus = ProcessInstanceStatus.COMPLETE;
isEnded = true;
KernelTokenImpl tempToken = getRootToken();
tempToken.end();
tempToken.fireEvent(KernelEvent.PROCESS_END);
if (getParentProcessInstance() != null) {
signalParentProcessInstance();
}
}
public void abort() {
this.instanceStatus = ProcessInstanceStatus.ABORT;
isEnded = true;
KernelTokenImpl tempToken = getRootToken();
tempToken.end(false);
tempToken.fireEvent(KernelEvent.PROCESS_ABORT);
if (getParentProcessInstance() != null) {
this.getParentProcessInstance().abort();
// signalParentProcessInstance();
}
}
public void suspendInstance(){
this.instanceStatus=ProcessInstanceStatus.SUSPEND;
setSuspended(true);
for (KernelTokenImpl token : getTokens()) {
token.suspendToken();
}
}
public void continueInstance(){
this.instanceStatus=ProcessInstanceStatus.RUNNING;
setSuspended(false);
for (KernelTokenImpl token : getTokens()) {
token.continueToken();
}
}
/** 子类可以重写这个方法实现自己的启动子流程方法 */
protected void signalParentProcessInstance() {
getParentProcessInstanceToken().signal();
}
public void setRootToken(KernelTokenImpl rootToken) {
this.rootToken = rootToken;
}
public KernelFlowNodeImpl getStartFlowNode() {
return startFlowNode;
}
public String getInstanceStatus() {
return instanceStatus;
}
public void setInstanceStatus(String instanceStatus) {
this.instanceStatus = instanceStatus;
}
}