/* (non-Javadoc)
   * @see org.fireflow.engine.IProcessInstance#run()
   */
  public void run() throws EngineException, KernelException {
    if (this.getState().intValue() != IProcessInstance.INITIALIZED) {
      throw new EngineException(
          this.getId(),
          this.getWorkflowProcess(),
          this.getProcessId(),
          "The state of the process instance is " + this.getState() + ",can not run it ");
    }

    INetInstance netInstance =
        rtCtx.getKernelManager().getNetInstance(this.getProcessId(), this.getVersion());
    if (netInstance == null) {
      throw new EngineException(
          this.getId(),
          this.getWorkflowProcess(),
          this.getProcessId(),
          "The net instance for the  workflow process [Id="
              + this.getProcessId()
              + "] is Not found");
    }
    // 触发事件
    ProcessInstanceEvent event = new ProcessInstanceEvent();
    event.setEventType(ProcessInstanceEvent.BEFORE_PROCESS_INSTANCE_RUN);
    event.setSource(this);
    this.fireProcessInstanceEvent(event);

    this.setState(IProcessInstance.RUNNING);
    this.setStartedTime(rtCtx.getCalendarService().getSysDate());
    rtCtx.getPersistenceService().saveOrUpdateProcessInstance(this);
    netInstance.run(this); // 运行工作流网实例,从startnode开始
  }
  /**
   * 正常结束工作流 1、首先检查有无活动的token,如果有则直接返回,如果没有则结束当前流程 2、执行结束流程的操作,将state的值设置为结束状态
   * 3、然后检查parentTaskInstanceId是否为null,如果不为null则,调用父taskinstance的complete操作。
   */
  public void complete() throws EngineException, KernelException {
    List<IToken> tokens =
        rtCtx.getPersistenceService().findTokensForProcessInstance(this.getId(), null);
    boolean canBeCompleted = true;
    for (int i = 0; tokens != null && i < tokens.size(); i++) {
      IToken token = tokens.get(i);
      if (token.isAlive()) {
        canBeCompleted = false;
        break;
      }
    }
    if (!canBeCompleted) {
      return;
    }

    this.setState(IProcessInstance.COMPLETED);
    // 记录结束时间
    this.setEndTime(rtCtx.getCalendarService().getSysDate());
    rtCtx.getPersistenceService().saveOrUpdateProcessInstance(this);

    // 删除所有的token
    for (int i = 0; tokens != null && i < tokens.size(); i++) {
      IToken token = tokens.get(i);
      rtCtx.getPersistenceService().deleteToken(token);
    }

    // 触发事件
    ProcessInstanceEvent event = new ProcessInstanceEvent();
    event.setEventType(ProcessInstanceEvent.AFTER_PROCESS_INSTANCE_COMPLETE);
    event.setSource(this);
    this.fireProcessInstanceEvent(event);
    if (this.getParentTaskInstanceId() != null
        && !this.getParentTaskInstanceId().trim().equals("")) {
      ITaskInstance taskInstance =
          rtCtx.getPersistenceService().findAliveTaskInstanceById(this.getParentTaskInstanceId());
      ((IRuntimeContextAware) taskInstance).setRuntimeContext(rtCtx);
      ((IWorkflowSessionAware) taskInstance).setCurrentWorkflowSession(workflowSession);
      ((TaskInstance) taskInstance).complete(null);
    }
  }