/*
   * (non-Javadoc)
   *
   * @see com.aof.service.business.rule.FlowManager#executePurchaseFlow(com.aof.model.business.Purchasable)
   */
  public List executePurchaseFlow(Purchasable target)
      throws ExecuteFlowEmptyResultException, NoAvailableFlowToExecuteException {
    if (target == null) {
      throw new RuntimeException("Cannot execute flow on null target");
    }

    EngineFlow ef = workspace.getFlow(target.getPurchaseFlowName());
    if (ef == null) throw new NoAvailableFlowToExecuteException();
    List l = ef.execute(target);
    int s = l.size();
    if (s == 0) {
      throw new ExecuteFlowEmptyResultException();
    }
    List results = new ArrayList();
    Set users = new HashSet();
    for (Iterator itor = l.iterator(); itor.hasNext(); ) {
      RuleConsequence rc = (RuleConsequence) itor.next();
      User purchaser = rc.getUser();
      if (!users.contains(purchaser)) {
        BasePurchaser bp = target.createNewPurchaserObj();
        bp.setPurchaser(purchaser);
        results.add(bp);
        users.add(purchaser);
      }
    }
    return results;
  }
  public void executeNotifyFlow(Notifiable target) {
    if (target == null) {
      throw new RuntimeException("Cannot execute flow on null target");
    }

    EngineFlow ef = workspace.getFlow(target.getNotifyFlowName());
    if (ef == null) {
      return;
    }
    Set users = new HashSet();
    for (Iterator itor = ef.execute(target).iterator(); itor.hasNext(); ) {
      RuleConsequence rc = (RuleConsequence) itor.next();
      User notifier = rc.getUser();
      if (!users.contains(notifier)) {
        /*
         * 重新load User, 个人信息可能已经修改
         */
        notifier = userManager.getUser(notifier.getId());
        if (EnabledDisabled.ENABLED.equals(notifier.getEnabled())) {
          Map context = target.getNotifyEmailContext();
          context.put("user", notifier);
          context.put("role", EmailManager.EMAIL_ROLE_NOTIFIER);
          emailManager.insertEmail(
              target.getLogSite(),
              notifier.getEmail(),
              target.getNotifyEmailTemplateName(),
              context);
        }

        users.add(notifier);
      }
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see com.aof.service.business.rule.FlowManager#executeApproveFlow(com.aof.model.business.Approvable)
   */
  public List executeApproveFlow(Approvable target)
      throws ExecuteFlowEmptyResultException, NoAvailableFlowToExecuteException {
    if (target == null) {
      throw new RuntimeException("Cannot execute flow on null target");
    }

    EngineFlow ef = workspace.getFlow(target.getApproveFlowName());
    if (ef == null) {
      throw new NoAvailableFlowToExecuteException();
    }
    List l = ef.execute(target);
    int s = l.size();
    if (s == 0) {
      throw new ExecuteFlowEmptyResultException();
    }
    List results = new ArrayList();
    Set users = new HashSet();
    User requestor = target.getRequestor();
    /*
     * 重复的approver保留后一个
     */
    /*
    for (int i = s; i > 0; i--) {
        RuleConsequence rc = (RuleConsequence) l.get(i - 1);
        User approver = rc.getUser();
        User superior = rc.getSuperior();
        if (superior != null && approver.equals(requestor)) {
            approver = superior;
        }
        if (!users.contains(approver)) {
            BaseApproveRequest bar = target.createNewApproveRequestObj();
            bar.setApprover(approver);
            bar.setCanModify(rc.getCanModify());
            results.add(0, bar);
            users.add(approver);
        }
    }
    */
    /*
     * 重复的approver保留前一个
     */
    for (int i = 0; i < s; i++) {
      RuleConsequence rc = (RuleConsequence) l.get(i);
      User approver = rc.getUser();
      User superior = rc.getSuperior();
      if (superior != null && approver.equals(requestor)) {
        approver = superior;
      }
      if (!users.contains(approver)) {
        BaseApproveRequest bar = target.createNewApproveRequestObj();
        bar.setApprover(approver);
        bar.setCanModify(rc.getCanModify());
        results.add(bar);
        users.add(approver);
      }
    }

    s = results.size();
    for (int i = 0; i < s; i++) {
      BaseApproveRequest bar = (BaseApproveRequest) results.get(i);
      if (i == 0) {
        bar.setStatus(ApproveStatus.WAITING_FOR_APPROVE);
        bar.setYourTurnDate(new Date());
      } else {
        bar.setStatus(ApproveStatus.NOT_YOUR_TURN);
      }
      bar.setSeq(i + 1);
    }
    return results;
  }