/**
* Copyright 2007-2010 非也
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation。
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses. *
*/
package org.fireflow.pvm.kernel.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.fireflow.client.WorkflowSession;
import org.fireflow.client.impl.WorkflowSessionLocalImpl;
import org.fireflow.engine.context.RuntimeContext;
import org.fireflow.pvm.kernel.BookMark;
import org.fireflow.pvm.kernel.ExecutionEntrance;
import org.fireflow.pvm.kernel.KernelException;
import org.fireflow.pvm.kernel.KernelManager;
import org.fireflow.pvm.kernel.OperationContextName;
import org.fireflow.pvm.kernel.PObject;
import org.fireflow.pvm.kernel.PObjectKey;
import org.fireflow.pvm.kernel.Token;
import org.fireflow.pvm.kernel.TokenState;
import org.fireflow.pvm.pdllogic.BusinessStatus;
import org.fireflow.pvm.pdllogic.ContinueDirection;
import org.fireflow.pvm.pdllogic.ExecuteResult;
import org.fireflow.pvm.pdllogic.FaultHandler;
import org.fireflow.pvm.pdllogic.WorkflowBehavior;
/**
* @author 非也
* @version 2.0
*/
public abstract class AbstractPObject implements PObject {
protected PObjectKey key = null;
protected Object workflowElement = null;
protected WorkflowBehavior behavior = null;
protected boolean acceptCancellation = false;
protected boolean acceptCompensation = false;
// protected PObject cancellationHandler = null;//(2012-02-05,Cancel动作容易和handleTermination混淆,意义也不是特别大,暂且注销)
protected Map<String,PObject> faultHandlers = new HashMap<String,PObject>();
protected PObject defaultFaultHandler = null;
protected Map<String,PObject> compensationHandlers = new HashMap<String,PObject>();
protected PObject defaultCompensationHandler = null;
public AbstractPObject(PObjectKey key) {
this.key = key;
}
/*
* (non-Javadoc)
*
* @see org.fireflow.pvm.kernel.ProcessObject#getKey()
*/
public PObjectKey getKey() {
return key;
}
public void setKey(PObjectKey key) {
this.key = key;
}
/*
* (non-Javadoc)
*
* @see org.fireflow.pvm.kernel.ProcessObject#getWorkflowBehavior()
*/
public WorkflowBehavior getWorkflowBehavior() {
return this.behavior;
}
/*
* (non-Javadoc)
*
* @see org.fireflow.pvm.kernel.ProcessObject#getWorkflowElement()
*/
public Object getWorkflowElement() {
return this.workflowElement;
}
/*
* (non-Javadoc)
*
* @see
* org.fireflow.pvm.kernel.ProcessObject#setWorkflowBehavior(org.fireflow
* .pvm.pdllogic.WorkflowBehavior)
*/
public void setWorkflowBehavior(WorkflowBehavior processBehavior) {
this.behavior = processBehavior;
}
/*
* (non-Javadoc)
*
* @see
* org.fireflow.pvm.kernel.ProcessObject#setWorkflowElement(java.lang.Object
* )
*/
public void setWorkflowElement(Object wfElement) {
this.workflowElement = wfElement;
}
public boolean isCancellable() {
return this.acceptCancellation;
}
public void setCancellable(Boolean b) {
this.acceptCancellation = b;
}
public boolean isCompensable() {
return this.acceptCompensation;
}
public void setCompensable(Boolean b) {
this.acceptCompensation = b;
}
/* (2012-02-05,Cancel动作容易和handleTermination混淆,意义也不是特别大,暂且注销)
public PObject getCancellationHandler() {
return cancellationHandler;
}
public void setCancellationHandler(PObject pobject){
this.cancellationHandler = pobject;
}
*/
/**
* 异常处理句柄
* @return
*/
public PObject getFaultHandler(String errorCode){
return this.faultHandlers.get(errorCode);
}
public PObject getDefaultFaultHandler(){
return this.defaultFaultHandler;
}
public void setFaultHandler(String errorCode,PObject handler){
this.setFaultHandler(errorCode, handler, false);
}
public void setFaultHandler(String errorCode,PObject handler,boolean isDefaultFaultHandler){
this.faultHandlers.put(errorCode, handler);
if (isDefaultFaultHandler){
this.defaultFaultHandler = handler;
}
}
/**
* 补偿处理句柄
* @return
*/
public PObject getCompensationHandler(String compensationCode){
return this.compensationHandlers.get(compensationCode);
}
public PObject getDefaultCompensationHandler(){
return this.defaultCompensationHandler;
}
public void setCompensationHandler(String compensationCode,PObject handler){
this.setCompensationHandler(compensationCode, handler, false);
}
public void setCompensationHandler(String compensationCode,PObject handler,boolean isDefaultCompensationHandler){
this.compensationHandlers.put(compensationCode, handler);
if (isDefaultCompensationHandler){
this.defaultCompensationHandler = handler;
}
}
// ////////////////////////////////////////////////////////////////
// ///////////// 行为逻辑 ///////////////////////////////////
// ///////////////////////////////////////////////////////////////
/*
* (non-Javadoc)
*
* @seeorg.fireflow.pvm.kernel.ProcessObject#takeToken(org.fireflow.engine.
* WorkflowSession, org.fireflow.pvm.kernel.Token)
*/
public void takeToken(WorkflowSession session, Token token, Token sourceToken) {
if (!token.getState().equals(TokenState.INITIALIZED)) {
return;
//在synchronizer汇聚的情况下,takeToken可能被执行多次,所以不能抛出异常。
// throw new KernelException(
// "Illegal token state ,the TokenState.INITIALIZED is expected,but it is "
// + token.getState().name());
}
RuntimeContext ctx = ((WorkflowSessionLocalImpl) session)
.getRuntimeContext();
KernelManager kernelManager = ctx
.getDefaultEngineModule(KernelManager.class);
WorkflowBehavior behavior = this.getWorkflowBehavior();
Boolean canBeFired = behavior.prepare(session, token, this
.getWorkflowElement());
kernelManager.saveOrUpdateToken(token);
if (!canBeFired) {
return;// 继续等待
}
token.setState(TokenState.RUNNING);
kernelManager.saveOrUpdateToken(token);
behavior.onTokenStateChanged(session, token,
this.getWorkflowElement());
// 如果isAlive则执行业务逻辑
if (token.isBusinessPermitted()) {
executeBusinessLogicLogic(session, token);
} else {
this.forwardToken(session, token, token);
}
}
protected void executeBusinessLogicLogic(WorkflowSession session,
Token token) {
if (!token.getState().equals(TokenState.RUNNING)) {
throw new KernelException(this,
"Illegal token state ,the TokenState.RUNNING is expected,but it is "
+ token.getState().name());
}
ExecuteResult result = behavior.execute(session, token, this
.getWorkflowElement());
BusinessStatus status = result.getStatus();
if (status.equals(BusinessStatus.RUNNING)) {
// 正在运行中(一般是长任务)
return;
} else if (status.equals(BusinessStatus.FAULTING)) {// 异常
this.catchFault(session, token, result);
}
else if (status.equals(BusinessStatus.COMPLETED)) {// 已经结束
BookMark bookMark = new BookMark();
bookMark.setToken(token);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, token);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
RuntimeContext ctx = ((WorkflowSessionLocalImpl) session)
.getRuntimeContext();
KernelManager kernelManager = ctx
.getDefaultEngineModule(KernelManager.class);
kernelManager.addBookMark(bookMark);
} else {
throw new KernelException(this,
"Not supported workflow behavior status for NodeInstance.takeToken(...) ,"
+ "WorkflowBehaviorStatus.RUNNING or WorkflowBehaviorStatus.FAULTING or status.equals(WorkflowBehaviorStatus.COMPLETED is expected,but the status is "
+ status.name());// 非法的返回状态
}
}
/*
* (non-Javadoc)
*
* @see
* org.fireflow.pvm.kernel.ProcessObject#forwardToken(org.fireflow.engine
* .WorkflowSession, org.fireflow.pvm.kernel.Token)
*/
public void forwardToken(WorkflowSession session, Token token, Token sourceToken) {
//TODO 2012-02-03 token的状态有可能被前一个bookmark修改过,导致与数据库中的真实状态不匹配,所以在非hibernate情况下要校验一致性。
if (token.getState().getValue() > TokenState.DELIMITER.getValue()) {
return;
}
RuntimeContext runtimeContext = ((WorkflowSessionLocalImpl) session)
.getRuntimeContext();
KernelManager kernelManager = runtimeContext
.getDefaultEngineModule(KernelManager.class);
if (token.getState() != null
&& token.getState().equals(TokenState.RUNNING)) {
_forwardRunningToken(session,kernelManager,token,sourceToken);
} else if (token.getState() != null
&& token.getState().equals(TokenState.FAULTING)) {
Token parentToken = kernelManager.getParentToken(token);
PObject parent = null;
if (parentToken != null) {
parent = kernelManager.getProcessObject(parentToken);
}
Token callbackToken = null;
if (token.getCallbackTokenId() != null) {
callbackToken = kernelManager.getTokenById(token.getCallbackTokenId(),
token.getProcessType());
}
//不需要调用behavior.continueOn(session, token, this.getWorkflowElement());
//此种情况默认为ContinueDirection.CloseMe()
if (callbackToken != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(callbackToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
} else if (parentToken != null && parent != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(parentToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
if (!kernelManager.hasChildrenInQueue(token)) {
token.setState(TokenState.FAULTED);
kernelManager.saveOrUpdateToken(token);
behavior.onTokenStateChanged(session, token, this
.getWorkflowElement());
}
} else if (token.getState() != null
&& token.getState().equals(TokenState.COMPENSATING)) {
_forwardCompensatingToken(session,kernelManager,token,sourceToken);
} else if (token.getState() != null
&& token.getState().equals(TokenState.ABORTING)) {
//不需要调用behavior.continueOn(session, token, this.getWorkflowElement());
//此种情况默认为ContinueDirection.CloseMe()
Token parentToken = kernelManager.getParentToken(token);
PObject parent = null;
if (parentToken != null) {
parent = kernelManager.getProcessObject(parentToken);
}
Token callbackToken = null;
if (token.getCallbackTokenId() != null) {
callbackToken = kernelManager.getTokenById(token.getCallbackTokenId(),
token.getProcessType());
}
if (callbackToken != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(callbackToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
} else if (parentToken != null && parent != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(parentToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
if (!kernelManager.hasChildrenInQueue(token)) {
token.setState(TokenState.ABORTED);
kernelManager.saveOrUpdateToken(token);
behavior.onTokenStateChanged(session, token, this
.getWorkflowElement());
}
}
else {
throw new KernelException(this,
"Illegal token state ,the TokenState.RUNNING or TokenState.COMPENSATING or TokenState.CANCELLING is expected,but it is "
+ token.getState().name());
}
}
protected void catchFault(WorkflowSession session, Token token,
ExecuteResult behaviorResult) {
}
protected void _forwardRunningToken(WorkflowSession session ,KernelManager kernelManager,Token thisToken,Token sourceToken){
Token callbackToken = null;
if (thisToken.getCallbackTokenId() != null) {
callbackToken = kernelManager.getTokenById(thisToken.getCallbackTokenId(),
thisToken.getProcessType());
}
WorkflowBehavior behavior = this.getWorkflowBehavior();
ContinueDirection continueDirection = behavior.continueOn(session,
thisToken, this.getWorkflowElement());
if (continueDirection.getDirection() == ContinueDirection.WAITING_FOR_CLOSE) {
return;
} else if (continueDirection.getDirection() == ContinueDirection.RUN_AGAIN) {
this.executeBusinessLogicLogic(session, thisToken);
} else if (continueDirection.getDirection() == ContinueDirection.CLOSE_ME) {
if (continueDirection.getNextProcessObjectKeys() == null
|| continueDirection.getNextProcessObjectKeys().size() == 0) {
Token parentToken = kernelManager.getParentToken(thisToken);
PObject parent = kernelManager.getProcessObject(parentToken);
if (callbackToken!=null){
BookMark bookMark = new BookMark();
bookMark.setToken(callbackToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
else if (parentToken != null && parent != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(parentToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
if (!kernelManager.hasChildrenInQueue(thisToken)) {
thisToken.setState(TokenState.COMPLETED);
kernelManager.saveOrUpdateToken(thisToken);
behavior.onTokenStateChanged(session, thisToken, this
.getWorkflowElement());
}
} else {
List<PObjectKey> keys = continueDirection
.getNextProcessObjectKeys();
if (keys != null && keys.size() > 0) {
// 启动新的节点
for (PObjectKey key : keys) {
Token newToken = new TokenImpl(thisToken);
newToken.setElementId(key.getWorkflowElementId());
BookMark bookMark = new BookMark();
bookMark.setToken(newToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.TAKE_TOKEN);
kernelManager.addBookMark(bookMark);
}
}
thisToken.setState(TokenState.COMPLETED);
kernelManager.saveOrUpdateToken(thisToken);
behavior.onTokenStateChanged(session, thisToken, this
.getWorkflowElement());
}
} else if (continueDirection.getDirection() == ContinueDirection.START_NEXT_AND_WAITING_FOR_CLOSE) {
List<PObjectKey> keys = continueDirection
.getNextProcessObjectKeys();
if (keys != null && keys.size() > 0) {
// 启动新的节点
for (PObjectKey key : keys) {
Token newToken = new TokenImpl(thisToken);
newToken.setElementId(key.getWorkflowElementId());
BookMark bookMark = new BookMark();
bookMark.setToken(newToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.TAKE_TOKEN);
kernelManager.addBookMark(bookMark);
}
}
}
}
protected void _forwardCompensatingToken(WorkflowSession session ,KernelManager kernelManager,Token thisToken,Token sourceToken){
//不需要调用behavior.continueOn(session, token, this.getWorkflowElement());
//此种情况默认为ContinueDirection.CloseMe()
//首先检查本流程的(本节点的)compensationChain是否为空,
if (thisToken.getNextCompensationToken()!=null){
Token nextCompensationToken = kernelManager.getTokenById(thisToken.getNextCompensationToken(), thisToken.getProcessType());
BookMark bookMark = new BookMark();
bookMark.setToken(nextCompensationToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.HANDLE_COMPENSATION);
bookMark.setExtraArg(BookMark.COMPENSATION_CODE,
nextCompensationToken.getCompensationCode());
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, sourceToken);
kernelManager.addBookMark(bookMark);
}else{
Token parentToken = kernelManager.getParentToken(thisToken);
PObject parent = kernelManager.getProcessObject(parentToken);
Token callbackToken = null;
if (thisToken.getCallbackTokenId() != null) {
callbackToken = kernelManager.getTokenById(thisToken.getCallbackTokenId(),
thisToken.getProcessType());
}
if (callbackToken!=null){
BookMark bookMark = new BookMark();
bookMark.setToken(callbackToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
else if (parentToken != null && parent != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(parentToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
}
if (!kernelManager.hasChildrenInQueue(thisToken)) {
thisToken.setState(TokenState.COMPENSATED);
kernelManager.saveOrUpdateToken(thisToken);
behavior.onTokenStateChanged(session, thisToken, this
.getWorkflowElement());
}
}
/**
* 将子节点倒序执行补偿
* @param 表示补偿操作是否完成
*/
protected boolean _handleCompensation(KernelManager kernelManager,Token listenerToken,List<Token> childrenInCompensationOrder,String compensationCode,Token sourceToken){
if (childrenInCompensationOrder==null || childrenInCompensationOrder.size()==0)return true;
List<Token> compensationChain = new ArrayList<Token>();
for (int i=0;i<childrenInCompensationOrder.size();i++){
Token t = childrenInCompensationOrder.get(i);
PObject pobject = kernelManager.getProcessObject(t);
if (pobject.isAcceptCompensation(t, compensationCode)){
compensationChain.add(t);
}
}
for (int i=0;i<compensationChain.size();i++){
Token t = compensationChain.get(i);
t.setCompensationCode(compensationCode);
if (i<compensationChain.size()-1){
t.setNextCompensationToken(compensationChain.get(i+1).getId());
}
kernelManager.saveOrUpdateToken(t);
}
if (compensationChain.size()>0){
Token childToken = compensationChain.get(0);
BookMark bookMark = new BookMark();
bookMark.setToken(childToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.HANDLE_COMPENSATION);
bookMark.setExtraArg(BookMark.COMPENSATION_CODE,
compensationCode);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, sourceToken);
kernelManager.addBookMark(bookMark);
return false;
}
else{
return true;
}
}
public void handleTermination(WorkflowSession session ,Token thisToken, Token sourceToken){
RuntimeContext ctx = ((WorkflowSessionLocalImpl) session)
.getRuntimeContext();
KernelManager kernelManager = ctx.getDefaultEngineModule(KernelManager.class);
boolean hasAliveChildren = false;
List<Token> children = kernelManager.getChildren(thisToken);
if (children!=null && children.size()>0){
for (Token childToken:children){
if (childToken.getState().getValue()<TokenState.DELIMITER.getValue()){
hasAliveChildren = true;
BookMark bookMark = new BookMark();
bookMark.setToken(childToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark.setExecutionEntrance(ExecutionEntrance.HANDLE_TERMINATION);
kernelManager.addBookMark(bookMark);
}
}
}
if (hasAliveChildren){
thisToken.setState(TokenState.ABORTING);
kernelManager.saveOrUpdateToken(thisToken);
WorkflowBehavior behavior = this.getWorkflowBehavior();
behavior.onTokenStateChanged(session, thisToken, this.getWorkflowElement());
}else{
thisToken.setState(TokenState.ABORTED);
kernelManager.saveOrUpdateToken(thisToken);
WorkflowBehavior behavior = this.getWorkflowBehavior();
behavior.onTokenStateChanged(session, thisToken, this.getWorkflowElement());
//触发父节点的forword
Token parentToken = kernelManager.getParentToken(thisToken);
PObject parent = null;
if (parentToken != null) {
parent = kernelManager.getProcessObject(parentToken);
}
BookMark bookMark = new BookMark();
bookMark.setToken(parentToken);
bookMark.setExecutionEntrance(ExecutionEntrance.FORWARD_TOKEN);
kernelManager.addBookMark(bookMark);
}
}
public void handleFault(WorkflowSession session, Token thisToken, Token sourceToken, String faultCode) {
if (!thisToken.getState().equals(TokenState.RUNNING)) {
throw new KernelException(this,
"Illegal token state ,the TokenState.RUNNING is expected,but it is "
+ thisToken.getState().name());
}
//System.out.println("===Inside "+this.getKey().getWorkflowElementId()+": 进入错误处理逻辑");
RuntimeContext ctx = ((WorkflowSessionLocalImpl) session)
.getRuntimeContext();
KernelManager kernelManager = ctx.getDefaultEngineModule(KernelManager.class);
PObject processObject = null;
if (faultCode==null || faultCode.trim().equals("")){
processObject = this.defaultFaultHandler;
String s = "null";
if (processObject!=null){
s = processObject.getKey().getWorkflowElementId();
}
//System.out.println("===Inside "+this.getKey().getWorkflowElementId()+": 采用defaultFaultHandler="+s);
}else{
processObject = this.getFaultHandler(faultCode);
//System.out.println("===Inside "+this.getKey().getWorkflowElementId()+": 根据faultCode获得faultHandler="+processObject);
if (processObject==null){//如果没有找到匹配的错误处理器,则自动采用缺省的错误处理器
processObject = this.defaultFaultHandler;
}
}
if (processObject!=null){
//1、将活动的子节点中止掉
List<Token> children = kernelManager.getChildren(thisToken);
if (children!=null && children.size()>0){
for (Token childToken:children){
if (childToken.getState().getValue()<TokenState.DELIMITER.getValue()){
BookMark bookMark = new BookMark();
bookMark.setToken(childToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark.setExecutionEntrance(ExecutionEntrance.HANDLE_TERMINATION);
kernelManager.addBookMark(bookMark);
}
}
}
//2、进入异常处理子流程
Token newToken = sourceToken==null?(new TokenImpl(thisToken)):(new TokenImpl(sourceToken));
newToken.setElementId(processObject.getKey().getWorkflowElementId());
newToken.setBusinessPermitted(true);
newToken.setCallbackTokenId(thisToken.getId());
newToken.setOperationContextName(OperationContextName.FAULT);
BookMark bookMark = new BookMark();
bookMark.setToken(newToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, sourceToken);
bookMark.setExecutionEntrance(ExecutionEntrance.TAKE_TOKEN);
kernelManager.addBookMark(bookMark);
thisToken.setState(TokenState.FAULTING);
kernelManager.saveOrUpdateToken(thisToken);
WorkflowBehavior behavior = this.getWorkflowBehavior();
behavior.onTokenStateChanged(session, thisToken, this.getWorkflowElement());
}else{
FaultHandler faultHandler = this.getWorkflowBehavior().getFaultHandler(faultCode);
if (faultHandler!=null){
//1、将活动的子节点中止掉
List<Token> children = kernelManager.getChildren(thisToken);
if (children!=null && children.size()>0){
for (Token childToken:children){
if (childToken.getState().getValue()<TokenState.DELIMITER.getValue()){
BookMark bookMark = new BookMark();
bookMark.setToken(childToken);
bookMark.setExtraArg(BookMark.SOURCE_TOKEN, thisToken);
bookMark.setExecutionEntrance(ExecutionEntrance.HANDLE_TERMINATION);
kernelManager.addBookMark(bookMark);
}
}
}
//2、处理异常
faultHandler.handleFault(session, thisToken, this.getWorkflowElement(), faultCode);
thisToken.setState(TokenState.FAULTING);
kernelManager.saveOrUpdateToken(thisToken);
WorkflowBehavior behavior = this.getWorkflowBehavior();
behavior.onTokenStateChanged(session, thisToken, this.getWorkflowElement());
}else{
String parentTokenId = thisToken.getParentTokenId();
Token parentToken = null;
if (parentTokenId!=null){
parentToken = kernelManager.getParentToken(thisToken);
}
// 向上层抛出
if (parentToken != null) {
BookMark bookMark = new BookMark();
bookMark.setToken(parentToken);
bookMark
.setExecutionEntrance(ExecutionEntrance.HANDLE_FAULT);
bookMark.setExtraArg(BookMark.ERROR_CODE, faultCode);
kernelManager.addBookMark(bookMark);
thisToken.setState(TokenState.FAULTED);//如果向上层抛出,则应该记录为Faulted
kernelManager.saveOrUpdateToken(thisToken);
WorkflowBehavior behavior = this.getWorkflowBehavior();
behavior.onTokenStateChanged(session, thisToken, this
.getWorkflowElement());
}
//如果没有父元素,则抛出异常
else{
thisToken.setState(TokenState.FAULTED);//如果向上层抛出,则应该记录为Faulted
kernelManager.saveOrUpdateToken(thisToken);
WorkflowBehavior behavior = this.getWorkflowBehavior();
behavior.onTokenStateChanged(session, thisToken, this
.getWorkflowElement());
//抛出异常
throw new KernelException(this,"No fault handler found for FaultCode="+faultCode);
}
}
}
}
}