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#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 constructEngineFlow(Integer siteId, RuleType rt) {
    String flowName = siteId + rt.getPrefixUrl();
    Collection flowRules = null;
    if (ConsequenceType.NOTIFIER.equals(rt.getConsequenceType())) {
      flowRules = new ArrayList();
      List ruleList = ruleManager.getEnabledRuleListForRuleType(siteId, rt);
      int i = 2;
      for (Iterator itorRule = ruleList.iterator(); itorRule.hasNext(); i++) {
        Rule r = (Rule) itorRule.next();
        FlowRule fr = new FlowRule();
        fr.setRule(r);
        if (itorRule.hasNext()) {
          fr.setNextSeqWhenFail(i);
          fr.setNextSeqWhenPass(i);
        } else {
          fr.setNextSeqWhenFail(0);
          fr.setNextSeqWhenPass(0);
        }
        flowRules.add(fr);
      }
    } else {
      Flow f = getSiteEnabledFlow(siteId, rt);
      if (f != null) {
        flowRules = dao.getRulesForFlow(f.getId());
      }
    }

    if (flowRules == null || flowRules.isEmpty()) {
      workspace.removeFlow(flowName);
      return;
    }
    EngineFlow ef = workspace.getFlow(flowName);
    if (ef == null) {
      ef = workspace.createFlow(flowName);
    }
    ef.lockForUpdate();
    try {
      ef.clearRules();
      for (Iterator itor = flowRules.iterator(); itor.hasNext(); ) {
        ef.addRule(createEngineRuleForFlowRule((FlowRule) itor.next()));
      }
    } finally {
      ef.releaseLock();
    }
  }
 /*
  * (non-Javadoc)
  *
  * @see com.aof.service.business.rule.FlowManager#removeFlow(java.lang.Integer)
  */
 public void removeFlow(Integer id) {
   Flow f = getFlow(id, true);
   for (Iterator itor = f.getRules().iterator(); itor.hasNext(); ) {
     dao.removeFlowRule((FlowRule) itor.next());
   }
   dao.removeFlow(id);
   if (EnabledDisabled.ENABLED.equals(f.getEnabled())) {
     Site s = f.getSite();
     RuleType rt = f.getType();
     workspace.removeFlow(s.getId() + rt.getPrefixUrl());
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see com.aof.service.business.rule.FlowManager#executeControlFlow(com.aof.model.business.Controllable)
   */
  public boolean executeControlFlow(Controllable target) throws NoAvailableFlowToExecuteException {
    if (target == null) {
      throw new RuntimeException("Cannot execute flow on null target");
    }

    EngineFlow ef = workspace.getFlow(target.getControlFlowName());
    if (ef == null) {
      throw new NoAvailableFlowToExecuteException();
    }
    List l = ef.execute(target);
    int s = l.size();
    if (s == 0) {
      throw new RuntimeException(
          "Execute control flow return empty result list, this is a coding error.");
    }
    return ((Boolean) l.get(s - 1)).booleanValue();
  }
  /*
   * (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;
  }