Package com.founder.fix.fixflow.core.impl.runtime

Source Code of com.founder.fix.fixflow.core.impl.runtime.TokenEntity

/**
* Copyright 1996-2013 Founder International Co.,Ltd.
*
* 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 com.founder.fix.fixflow.core.impl.runtime;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.bpmn2.Activity;
import org.eclipse.bpmn2.FlowNode;
import org.eclipse.bpmn2.LoopCharacteristics;
import org.eclipse.bpmn2.MultiInstanceLoopCharacteristics;

import com.founder.fix.fixflow.core.exception.FixFlowException;
import com.founder.fix.fixflow.core.factory.ProcessObjectFactory;
import com.founder.fix.fixflow.core.impl.Context;
import com.founder.fix.fixflow.core.impl.bpmn.behavior.ProcessDefinitionBehavior;
import com.founder.fix.fixflow.core.impl.db.AbstractPersistentObject;
import com.founder.fix.fixflow.core.impl.identity.Authentication;
import com.founder.fix.fixflow.core.impl.task.TaskInstanceEntity;
import com.founder.fix.fixflow.core.impl.util.GuidUtil;
import com.founder.fix.fixflow.core.impl.util.StringUtil;
import com.founder.fix.fixflow.core.runtime.ExecutionContext;
import com.founder.fix.fixflow.core.runtime.Token;
import com.founder.fix.fixflow.core.task.TaskMgmtInstance;

public class TokenEntity extends AbstractPersistentObject<TokenEntity> implements Token {

  private static final long serialVersionUID = 1L;
  public static final String RULE_GET_TOKEN_PERSISTENT_STATE = "getTokenPersistentState";
  public static final String RULE_GET_TOKEN_PERSISTENT_DBMAP = "getTokenPersistentDbMap";
  public static final String RULE_GET_TOKEN_CLONE = "tokenClone";

  // 持久化字段
  protected String id;
  protected String name;
  protected String processInstanceId;
  protected String nodeId;
  protected String parentTokenId;
  protected String parentFreeTokenId;
  protected Date startTime;
  protected Date endTime;
  protected Date nodeEnterTime;
  protected Date archiveTime;
  protected boolean isLocked = false;
  protected boolean isSuspended = false;
  protected boolean isSubProcessRootToken = false;
  protected boolean isAbleToReactivateParent = true;
  protected boolean freeToken;

  // 构造函数 //////////////////////

  // 构造函数
  public TokenEntity() {

  }

  /**
   * 创建令牌
   *
   * @param fixflowInstance
   *            流程实例
   * @throws Exception
   */
  public TokenEntity(ProcessInstanceEntity processInstance) {
    // 给令牌编号赋值(guid)
    this.id = GuidUtil.CreateGuid();
    // 设置令牌的创建时间
    this.startTime = new Date();
    // 设置令牌的流程实例
    setProcessInstance(processInstance);
    // 将新生成的令牌放入流程实例令牌列表中
    processInstance.addTokenList(this);

  }

  /**
   * 创建一个子令牌
   *
   * @param parent
   *            父令牌
   * @param name
   *            令牌名称
   */
  public TokenEntity(TokenEntity parent, String name) {
    this(parent, name, false);
  }

  /**
   * 创建一个子令牌
   *
   * @param parent
   *            父令牌
   * @param name
   *            令牌名称
   */
  public TokenEntity(TokenEntity parent, String name, boolean freeToken) {
    // 设置令牌的编号
    this.id = GuidUtil.CreateGuid();
    // 设置令牌的开始时间
    this.startTime = new Date();
    // 设置令牌的流程实例对象
    setProcessInstance(parent.getProcessInstance());
    // 设置令牌的名称
    this.name = name;
    // 设置令牌所在的节点
    this.flowNode = parent.getFlowNode();
    // 把这个新生成的令牌放到他爸爸的儿子集合里~
    if (freeToken) {
      this.freeToken = true;
      this.parentFreeTokenId = parent.getId();
      this.parentFreeToken = parent;
    } else {
      // 设置令牌的爸爸囧~
      setParent(parent);
      parent.addChild(this);
    }
    // 将生成的新节点放入流程实例令牌列表中
    this.getProcessInstance().addTokenList(this);
  }

  // /定义对象
  /**
   * 令牌所在流程实例
   */
  protected ProcessInstanceEntity processInstance;

  /**
   * 令牌所在的节点
   */
  protected FlowNode flowNode;

  /**
   * 父令牌
   */
  protected TokenEntity parent;

  /**
   * 父令牌(如果有则这个令牌为自由令牌)
   */
  protected TokenEntity parentFreeToken;

  /**
   * 子令牌集合
   */
  protected Map<String, TokenEntity> children;

 

  // //get和set方法

 
  public void setId(String id) {
    this.id = id;
  }

  public String getId() {
    return id;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void setProcessInstanceId(String processInstanceId) {
    this.processInstanceId = processInstanceId;
  }

  public String getProcessInstanceId() {
    return this.processInstanceId;
  }

  public void setNodeId(String nodeId) {
    this.nodeId = nodeId;
  }

  public String getNodeId() {
    return this.nodeId;
  }

  public void setParentTokenId(String parentTokenId) {
    this.parentTokenId = parentTokenId;
  }

  public String getParentTokenId() {
    return this.parentTokenId;
  }

  public void setParentFreeTokenId(String parentFreeTokenId) {
    this.parentFreeTokenId = parentFreeTokenId;
  }

  public String getParentFreeTokenId() {
    return parentFreeTokenId;
  }

  public void setStartTime(Date startTime) {
    this.startTime = startTime;
  }

  public void setStartTimeWithoutCascade(Date startTime) {
    this.startTime = startTime;
  }

  public Date getStartTime() {
    return startTime;
  }

  public void setEndTime(Date endTime) {
    this.endTime = endTime;
  }

  public void setEndTimeWithoutCascade(Date endTime) {
    this.endTime = endTime;
  }

  public Date getEndTime() {
    return endTime;
  }

  public void setNodeEnterTime(Date date) {
    this.nodeEnterTime = date;
  }

  public Date getNodeEnterTime() {
    return nodeEnterTime;
  }

  public void setArchiveTime(Date archiveTime) {
    this.archiveTime = archiveTime;
  }

  public Date getArchiveTime() {
    return archiveTime;
  }

  public void setLocked(boolean isLocked) {
    this.isLocked = isLocked;
  }

  public void setLockedString(String isLocked) {
    if (StringUtil.isNotEmpty(isLocked)) {
      this.isLocked = StringUtil.getBoolean(isLocked);
    }
  }

  public boolean getlock() {
    return this.isLocked;
  }

  public void setSuspended(boolean isSuspended) {
    this.isSuspended = isSuspended;
  }

  public void setSuspendedString(String isSuspended) {
    if (StringUtil.isNotEmpty(isSuspended)) {
      this.isSuspended = StringUtil.getBoolean(isSuspended);
    }
  }

  public boolean isSuspended() {
    return isSuspended;
  }

  public void setSubProcessRootToken(boolean isSubProcessRootToken) {
    this.isSubProcessRootToken = isSubProcessRootToken;
  }

  public void setSubProcessRootTokenString(String isSubProcessRootToken) {
    if (StringUtil.isNotEmpty(isSubProcessRootToken)) {
      this.isSubProcessRootToken = StringUtil.getBoolean(isSubProcessRootToken);
    }
  }

  public boolean isSubProcessRootToken() {
    return isSubProcessRootToken;
  }

  public void setAbleToReactivateParent(boolean isAbleToReactivateParent) {
    this.isAbleToReactivateParent = isAbleToReactivateParent;
  }

  public void setAbleToReactivateParentString(String isAbleToReactivateParent) {
    if (StringUtil.isNotEmpty(isAbleToReactivateParent)) {
      this.isAbleToReactivateParent = StringUtil.getBoolean(isAbleToReactivateParent);
    }
  }

  public boolean isAbleToReactivateParent() {
    return isAbleToReactivateParent;
  }

  public void setFreeToken(boolean freeToken) {
    this.freeToken = freeToken;
  }

  public void setFreeTokenString(String freeToken) {
    if (StringUtil.isNotEmpty(freeToken)) {
      this.freeToken = StringUtil.getBoolean(freeToken);
    }
  }

  public boolean isFreeToken() {
    return freeToken;
  }

  // 对象get set方法
  public void setFlowNode(FlowNode flowNode) {
    this.flowNode = flowNode;
    if (flowNode == null) {
      this.nodeId = null;
    } else {
      this.nodeId = flowNode.getId();
    }
  }

  public FlowNode getFlowNode() {
    if (this.flowNode == null) {

      if (StringUtil.isNotEmpty(this.nodeId)) {
        ProcessInstanceEntity processInstanceEntity = getProcessInstance();
        if (processInstanceEntity == null) {
          return null;
        }
        ProcessDefinitionBehavior processDefinitionBehavior = getProcessInstance().getProcessDefinition();
        if (processDefinitionBehavior == null) {
          return null;
        }
        this.flowNode = (FlowNode) processDefinitionBehavior.getDefinitions().getElement(this.nodeId);
        return this.flowNode;
      }

      return null;

    } else {
      return flowNode;
    }

  }

  public void setProcessInstance(ProcessInstanceEntity processInstance) {
    this.processInstance = processInstance;
    if (processInstance == null) {
      this.processInstanceId = null;
    } else {
      this.processInstanceId = processInstance.getId();
    }
  }

  public ProcessInstanceEntity getProcessInstance() {

    if (this.processInstance == null) {

      if (StringUtil.isNotEmpty(this.processInstanceId)) {

        this.processInstance = Context.getCommandContext().getProcessInstanceManager().findProcessInstanceById(this.processInstanceId);
       
        if(this.processInstance!=null){
         
          if(StringUtil.isNotEmpty(this.parentTokenId)&&!this.freeToken){
            this.processInstance.setRootToken(this);
          }         
          return this.processInstance;
        }
       
       
      }
      return null;

    }

    return this.processInstance;
  }

  public void setParent(TokenEntity parent) {
    this.parent = parent;
    if (parent == null) {
      this.parentTokenId = null;
    } else {
      this.parentTokenId = parent.getId();
    }
  }

  public TokenEntity getParent() {

    if (this.parent == null) {

      if (StringUtil.isNotEmpty(this.parentTokenId)) {

        this.parent = Context.getCommandContext().getTokenManager().findTokenById(this.parentTokenId);
        return this.parent;

      }
      return null;

    }

    return this.parent;
  }

  public void setParentFreeToken(TokenEntity parentFreeToken) {
    this.parentFreeToken = parentFreeToken;
    if (parentFreeToken != null) {
      this.parentFreeTokenId = parentFreeToken.getId();
    }

  }

  public Token getParentFreeToken() {

    if (this.parentFreeToken == null) {

      if (StringUtil.isNotEmpty(this.parentFreeTokenId)) {

        this.parentFreeToken = Context.getCommandContext().getTokenManager().findTokenById(this.parentFreeTokenId);
        return this.parentFreeToken;

      }
      return null;

    }

    return this.parentFreeToken;

  }

 

  // 令牌流转
  // ////////////////////////////////////////////////////////

  public void signal() {
    ExecutionContext executionContext = ProcessObjectFactory.FACTORYINSTANCE.createExecutionContext(this);
    signal(executionContext);
  }

  public void signalKillChildMoveParentToken(FlowNode flowNode, FlowNode timeOutNode) {

    TokenEntity tokenParent = this.getParent();
    if (tokenParent == null) {
      tokenParent = this;
    }
    tokenParent.terminationChildToken();
    ExecutionContext executionContext = ProcessObjectFactory.FACTORYINSTANCE.createExecutionContext(tokenParent);
    if (timeOutNode != null) {
      executionContext.setTimeOutNode(timeOutNode);
    }
    flowNode.leave(executionContext);
  }

  public void signal(ExecutionContext executionContext) {

    if (executionContext == null) {
      throw new FixFlowException("执行内容不能为空!");
    }
    if (isSuspended) {
      throw new FixFlowException("令牌已经停止!");
    }
    if (isLocked) {
      throw new FixFlowException("令牌已经锁定!");
    }

    try {
      FlowNode signalNode = this.getFlowNode();
 
      signalNode.leave(executionContext);

    } finally {

    }
  }
 
  public Map<String, TokenEntity> getChildren() {
   
    if(this.children==null){
      this.children= new HashMap<String, TokenEntity>();
     
     
    }
    return children;
  }



  public void addChild(TokenEntity token) {
   
    if(token!=null){
      getChildren().put(token.getId(), token);
    }
   
   

  }

  public boolean hasParent() {
    return (StringUtil.isNotEmpty(this.parentTokenId));
  }

  public boolean hasChild(String name) {
    return (getChildren() != null ? getChildren().containsKey(name) : false);
  }

  public boolean hasChildRecursive(String tokenId) {
    boolean hasChildRecursive = false;
    if (getChildren() != null) {
      if (!getChildren().containsKey(tokenId)) {
        for (String tokenChildrenKey : getChildren().keySet()) {
          hasChildRecursive = getChildren().get(tokenChildrenKey).hasChildRecursive(tokenId);
          if (hasChildRecursive) {
            return true;
          }
        }
      } else {
        return true;
      }
    }

    return hasChildRecursive;
  }

  public Token getChild(String id) {
   
    return getChildren().get(id);
  }

  public void end() {
    end(true);
  }

  public void end(boolean verifyParentTermination) {
    // 如果令牌已经有结束时间则不执行令牌结束方法
    if (endTime == null) {
      // 结束令牌.使他不能再启动父令牌
      isAbleToReactivateParent = false;
      // 结束日期的标志,表明此令牌已经结束。
      this.endTime = new Date();
      // 结束所有子令牌
      if (getChildren() != null) {
        for (String tokenKey : getChildren().keySet()) {
          TokenEntity child = getChildren().get(tokenKey);
          if (!child.hasEnded()) {
            child.end();
          }
        }
      }
      // 记录日志用
      if (getParent() != null) {
        // 添加日志
        // parent.addLog(new TokenEndLog(this));
      }
      // 移除这个将要结束的令牌上的所有未完成的任务
      TaskMgmtInstance taskMgmtInstance = (TaskMgmtInstance) this.getProcessInstance().getTaskMgmtInstance();
      for (TaskInstanceEntity taskInstance : taskMgmtInstance.getTaskInstanceEntitys(this)) {
        if (!taskInstance.hasEnded()) {
          taskInstance.customEnd(null, null);
        }
      }
      if (verifyParentTermination) {
        // 如果这是根令牌,则需要结束流程实例.
        notifyParentOfTokenEnd();
      }
    }
  }

  public void terminationChildToken() {
    // 如果令牌已经有结束时间则不执行令牌结束方法
    if (endTime == null) {
      // 结束所有子令牌
      if (getChildren() != null) {

        for (String tokenKey : getChildren().keySet()) {
          TokenEntity child = getChildren().get(tokenKey);
          if (!child.hasEnded()) {
            // 结束令牌.使他不能再启动父令牌
            child.setAbleToReactivateParent(false);
            // 移除这个将要结束的令牌上的所有未完成的任务
            removeTaskInstanceSynchronization(child, null, null, null, null, null, null);
            child.terminationChildToken();
            // 设置结束日起
            // 结束日期的标志,表明此令牌已经结束。
            child.setEndTime(new Date());
          }
        }
      }
    }
  }

  public void terminationChildTokenWithTask(String taskommandType, String taskommandName, String taskComment, String assigneeId, String agent,
      String admin) {
    // 如果令牌已经有结束时间则不执行令牌结束方法
    if (endTime == null) {
      // 结束所有子令牌
      if (getChildren() != null) {
        for (String tokenKey : getChildren().keySet()) {
          TokenEntity child = getChildren().get(tokenKey);
          if (!child.hasEnded()) {
            // 结束令牌.使他不能再启动父令牌
            child.setAbleToReactivateParent(false);
            // 移除这个将要结束的令牌上的所有未完成的任务
            removeTaskInstanceSynchronization(child, taskommandType, taskommandName, taskComment, assigneeId, agent, admin);
            child.terminationChildToken();
            // 设置结束日起
            // 结束日期的标志,表明此令牌已经结束。
            child.setEndTime(new Date());
          }
        }
      }
    }
  }

  private TaskMgmtInstance getTaskMgmtInstance(TokenEntity token) {
    return (TaskMgmtInstance) token.getProcessInstance().getTaskMgmtInstance();
  }

  private void removeTaskInstanceSynchronization(TokenEntity token, String taskCommandType, String taskCommandName, String taskComment,
      String assigneeId, String agent, String admin) {
    String assigneeIdObj = assigneeId;
    String agentObj = null;
    String adminObj = null;
    if (agent != null) {
      assigneeIdObj = agent;
      agentObj = Authentication.getAuthenticatedUserId();
    }
    if (admin != null) {
      assigneeIdObj = admin;
      adminObj = admin;
    }
    TaskMgmtInstance tmi = getTaskMgmtInstance(token);
    for (TaskInstanceEntity taskInstance : tmi.getTaskInstanceEntitys(token)) {
      if (!taskInstance.hasEnded()) {
        taskInstance.customEnd(null, null);
        if (assigneeId != null) {
          taskInstance.setAssignee(assigneeIdObj);
        }
        taskInstance.setAgent(agentObj);
        taskInstance.setAdmin(adminObj);
        // taskInstance.setDraft(false);
        taskInstance.setTaskComment(taskComment);// taskComment
      }
    }
  }

  public void removeTaskInstanceSynchronization(String taskCommandType, String taskCommandName, String taskComment, String assigneeId,
      String agent, String admin) {
    removeTaskInstanceSynchronization(this, taskCommandType, taskCommandName, taskComment, assigneeId, agent, admin);
  }

  void notifyParentOfTokenEnd() {
    // 判断是否为根令牌
    if (isRoot()) {
      // 结束流程实例
      for (TokenEntity tokenObj : this.getProcessInstance().getTokenList()) {
        if (tokenObj.isFreeToken() && !tokenObj.hasEnded()) {
          return;
        }
      }
      getProcessInstance().end();
    } else {
      if (getParent() != null) {
        // 下面这句话是用来当存在分支时 一个分支走到结束另一个分支没结束的时候,不能结束他的父令牌
        // 只有当到达结束节点的令牌的同级分支都结束才能结束父令牌
        if (!getParent().hasActiveChildren()) {
          // 推动父令牌向后执行
          if (this.isSubProcessRootToken) {
            if (!getParent().hasEnded()) {
              getParent().signal();
            }
          } else {
            getParent().end();
          }
        } else {
          // 子流程多实例的时候 每个子流程结束的时候去触发验证完成条件
          if (getParent().getFlowNode() instanceof Activity) {
            Activity activity = (Activity) getParent().getFlowNode();
            LoopCharacteristics loopCharacteristics = activity.getLoopCharacteristics();
            if (loopCharacteristics instanceof MultiInstanceLoopCharacteristics) {
              if (this.isSubProcessRootToken) {
                if (!getParent().hasEnded()) {
                  getParent().signal();
                }
              }
            }
          }
        }
      } else {
        if (this.isFreeToken()) {
          boolean rootTokenObj = false;
          for (TokenEntity tokenObj : this.getProcessInstance().getTokenList()) {
            if (tokenObj.isRoot()) {
              rootTokenObj = true;
            }
            if (tokenObj.isFreeToken() && !tokenObj.hasEnded()) {
              return;
            }
          }
          if (!rootTokenObj || this.getProcessInstance().getRootToken().hasEnded()) {
            getProcessInstance().end();
          }
        }
      }
    }
  }

  public boolean hasActiveChildren() {
    boolean foundActiveChildToken = false;
    // 发现至少有一个子令牌,仍然活跃(没有结束.
    if (getChildren() != null) {

      for (String tokenKey : getChildren().keySet()) {
        if (!foundActiveChildToken) {
          TokenEntity child = getChildren().get(tokenKey);
          if (!child.hasEnded()) {
            foundActiveChildToken = true;
          }
        }
      }
    }
    return foundActiveChildToken;
  }

  public void resume() {
    isSuspended = false;
    // resumeTimers();
    // resumeMessages();
    resumeTaskInstances();
    // 恢复子令牌
    if (getChildren() != null) {
      for (String key : getChildren().keySet()) {
        TokenEntity child = getChildren().get(key);
        child.resume();
      }
    }
  }

  public void suspend() {
    isSuspended = true;
    // suspendTimers();
    // suspendMessages();
    suspendTaskInstances();
    // 暂停子令牌
    if (getChildren() != null) {
      for (String key : getChildren().keySet()) {
        TokenEntity child = getChildren().get(key);
        child.suspend();
      }
    }
  }

  void suspendTaskInstances() {
    TaskMgmtInstance taskMgmtInstance = (getProcessInstance() != null ? getProcessInstance().getTaskMgmtInstance() : null);
    if (taskMgmtInstance != null) {
      taskMgmtInstance.suspend(this);
    }
  }

  void resumeTaskInstances() {
    TaskMgmtInstance taskMgmtInstance = (getProcessInstance() != null ? getProcessInstance().getTaskMgmtInstance() : null);
    if (taskMgmtInstance != null) {
      taskMgmtInstance.resume(this);
    }
  }


  public void lock() {
    isLocked = true;
  }

  /**
   * @see #lock()
   */
  public void unlock() {
    isLocked = false;
  }

  public boolean hasEnded() {
    return (endTime != null);
  }

  public String toString() {
    return "Token(" + getFullName() + ")";
  }

  public boolean isRoot() {
    return (getParent() == null && !isFreeToken());
  }

  public String getFullName() {
    if (getParent() == null)
      return "/";
    if (getParent() .getParent() == null)
      return "/" + name;
    return getParent() .getFullName() + "/" + name;
  }

  @Override
  public String getCloneRuleId() {
    return RULE_GET_TOKEN_CLONE;
  }

  @Override
  public String getPersistentDbMapRuleId() {
    return RULE_GET_TOKEN_PERSISTENT_DBMAP;
  }

  @Override
  public String getPersistentStateRuleId() {
    return RULE_GET_TOKEN_PERSISTENT_STATE;
  }

  // 过时方法
  public void setIdWithoutCascade(String id) {
    this.id = id;
  }

  public void setNameWithoutCascade(String name) {
    this.name = name;
  }

  public void setProcessInstanceIdWithoutCascade(String processInstanceId) {
    this.processInstanceId = processInstanceId;
  }

  public void setNodeIdWithoutCascade(String nodeId) {
    this.nodeId = nodeId;
  }

  public void setParentTokenIdWithoutCascade(String parentTokenId) {
    this.parentTokenId = parentTokenId;
  }

  public void setNodeEnterTimeWithoutCascade(Date nodeEnterTime) {
    this.nodeEnterTime = nodeEnterTime;
  }

  public void setlockWithoutCascade(boolean isLocked) {
    this.isLocked = isLocked;
  }

  public void setSuspendedWithoutCascade(boolean isSuspended) {
    this.isSuspended = isSuspended;
  }

  public void setSubProcessRootTokenWithoutCascade(boolean isSubProcessRootToken) {
    this.isSubProcessRootToken = isSubProcessRootToken;
  }

  public void setAbleToReactivateParentWithoutCascade(boolean isAbleToReactivateParent) {
    this.isAbleToReactivateParent = isAbleToReactivateParent;
  }
 
  // 作废方法
 
  /**
   * 自由子令牌集合
   */
  protected Map<String, TokenEntity> freeChildren = new HashMap<String, TokenEntity>();
 
  public Map<String, TokenEntity> getFreeChildren() {

    return freeChildren;
  }

  public void setFreeChildren(Map<String, TokenEntity> freeChildren) {
    this.freeChildren = freeChildren;
  }
 
  public void setChildren(Map<String, TokenEntity> children) {
    this.children = children;
  }

}
TOP

Related Classes of com.founder.fix.fixflow.core.impl.runtime.TokenEntity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.