protected boolean isReachable(
      PvmActivity srcActivity, PvmActivity targetActivity, Set<PvmActivity> visitedActivities) {

    // if source has no outputs, it is the end of the process, and its parent process should be
    // checked.
    if (srcActivity.getOutgoingTransitions().isEmpty()) {
      visitedActivities.add(srcActivity);
      if (!(srcActivity.getParent() instanceof PvmActivity)) {
        return false;
      }
      srcActivity = (PvmActivity) srcActivity.getParent();
    }

    if (srcActivity.equals(targetActivity)) {
      return true;
    }

    // To avoid infinite looping, we must capture every node we visit
    // and check before going further in the graph if we have already visitied
    // the node.
    visitedActivities.add(srcActivity);

    List<PvmTransition> transitionList = srcActivity.getOutgoingTransitions();
    if (transitionList != null && !transitionList.isEmpty()) {
      for (PvmTransition pvmTransition : transitionList) {
        PvmActivity destinationActivity = pvmTransition.getDestination();
        if (destinationActivity != null && !visitedActivities.contains(destinationActivity)) {
          boolean reachable = isReachable(destinationActivity, targetActivity, visitedActivities);

          // If false, we should investigate other paths, and not yet return the
          // result
          if (reachable) {
            return true;
          }
        }
      }
    }
    return false;
  }
  public boolean activeConcurrentExecutionsExist(ActivityExecution execution) {
    PvmActivity activity = execution.getActivity();
    if (execution.isConcurrent()) {
      for (ActivityExecution concurrentExecution : getLeaveExecutions(execution.getParent())) {
        if (concurrentExecution.isActive()
            && concurrentExecution.getId().equals(execution.getId()) == false) {
          // TODO: when is transitionBeingTaken cleared? Should we clear it?
          boolean reachable = false;
          PvmTransition pvmTransition =
              ((ExecutionEntity) concurrentExecution).getTransitionBeingTaken();
          if (pvmTransition != null) {
            reachable =
                isReachable(pvmTransition.getDestination(), activity, new HashSet<PvmActivity>());
          } else {
            reachable =
                isReachable(
                    concurrentExecution.getActivity(), activity, new HashSet<PvmActivity>());
          }

          if (reachable) {
            if (log.isDebugEnabled()) {
              log.debug(
                  "an active concurrent execution found: '{}'", concurrentExecution.getActivity());
            }
            return true;
          }
        }
      }
    } else if (execution.isActive()) { // is this ever true?
      if (log.isDebugEnabled()) {
        log.debug("an active concurrent execution found: '{}'", execution.getActivity());
      }
      return true;
    }

    return false;
  }
Пример #3
0
  public void validateExclusiveGateway(ActivityImpl activity, ExclusiveGateway exclusiveGateway) {
    if (activity.getOutgoingTransitions().size() == 0) {
      // TODO: double check if this is valid (I think in Activiti yes, since we need start events we
      // will need an end event as well)
      bpmnModel.addProblem(
          "Exclusive Gateway '" + activity.getId() + "' has no outgoing sequence flows.",
          exclusiveGateway);
    } else if (activity.getOutgoingTransitions().size() == 1) {
      PvmTransition flow = activity.getOutgoingTransitions().get(0);
      Condition condition = (Condition) flow.getProperty(BpmnParse.PROPERTYNAME_CONDITION);
      if (condition != null) {
        bpmnModel.addProblem(
            "Exclusive Gateway '"
                + activity.getId()
                + "' has only one outgoing sequence flow ('"
                + flow.getId()
                + "'). This is not allowed to have a condition.",
            exclusiveGateway);
      }
    } else {
      String defaultSequenceFlow = (String) activity.getProperty("default");
      boolean hasDefaultFlow = StringUtils.isNotEmpty(defaultSequenceFlow);

      ArrayList<PvmTransition> flowsWithoutCondition = new ArrayList<PvmTransition>();
      for (PvmTransition flow : activity.getOutgoingTransitions()) {
        Condition condition = (Condition) flow.getProperty(BpmnParse.PROPERTYNAME_CONDITION);
        boolean isDefaultFlow = flow.getId() != null && flow.getId().equals(defaultSequenceFlow);
        boolean hasConditon = condition != null;

        if (!hasConditon && !isDefaultFlow) {
          flowsWithoutCondition.add(flow);
        }
        if (hasConditon && isDefaultFlow) {
          bpmnModel.addProblem(
              "Exclusive Gateway '"
                  + activity.getId()
                  + "' has outgoing sequence flow '"
                  + flow.getId()
                  + "' which is the default flow but has a condition too.",
              exclusiveGateway);
        }
      }
      if (hasDefaultFlow || flowsWithoutCondition.size() > 1) {
        // if we either have a default flow (then no flows without conditions are valid at all) or
        // if we have more than one flow without condition this is an error
        for (PvmTransition flow : flowsWithoutCondition) {
          bpmnModel.addProblem(
              "Exclusive Gateway '"
                  + activity.getId()
                  + "' has outgoing sequence flow '"
                  + flow.getId()
                  + "' without condition which is not the default flow.",
              exclusiveGateway);
        }
      } else if (flowsWithoutCondition.size() == 1) {
        // Havinf no default and exactly one flow without condition this is considered the default
        // one now (to not break backward compatibility)
        PvmTransition flow = flowsWithoutCondition.get(0);
        bpmnModel.addWarning(
            "Exclusive Gateway '"
                + activity.getId()
                + "' has outgoing sequence flow '"
                + flow.getId()
                + "' without condition which is not the default flow. We assume it to be the default flow, but it is bad modeling practice, better set the default flow in your gateway.",
            exclusiveGateway);
      }
    }
  }
Пример #4
0
  /**
   * 打开任务 传入的request必须有以下参数 taskId:task的Id taskPage:处理task的页面路径 model:业务表类名 formId:业务表id
   * formProperties:控制表单的名称
   *
   * @return
   * @throws Exception
   */
  public String open_task() throws Exception {
    log.debug("open_task()");
    List<String> nextTaskList = new ArrayList<String>();
    String taskId = getpara("taskId");
    String taskPage = getpara("taskPage");
    String modelStr = getpara("model");
    // add by hb for only query user task
    String readonly = getpara("readonly");
    // end
    String formId = (String) infActiviti.getVariableByTaskId(taskId, "formId");
    if (formId == null || formId.equals("") || modelStr == null || "".equals(modelStr)) {
      rhs.put("model", null);
    } else {
      BaseModel model = (BaseModel) baseDao.loadById(modelStr, Long.parseLong(formId));
      rhs.put("model", model);
    }

    /* add by chenzhijian 20130419 -s */
    // 获取 formProperties 配置文件
    String formProperties = getpara("formProperties");
    HashMap<String, String> formPro = new HashMap<String, String>();
    Properties p = new Properties();
    try {
      // String filepath = System.getProperty("webroot", "./src/main/webapp/");
      String filepath = getWebroot();
      // eg: app/manager/wo/wo.properties
      filepath +=
          "/app/manager/" + modelStr.toLowerCase() + "/" + modelStr.toLowerCase() + ".properties";
      FileInputStream in = new FileInputStream(filepath);
      p.load(in);
      in.close();
      Set<String> set = p.stringPropertyNames();
      for (String s : set) {
        if (s.startsWith("default")) {
          formPro.put(s.replace("default.", ""), p.getProperty(s));
        }
      }
      for (String s : set) {
        if (s.startsWith(formProperties)) {
          formPro.put(s.replace(formProperties + ".", ""), p.getProperty(s));
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    rhs.put("formPro", formPro);
    /* add by chenzhijian 20130419 -e */

    Task task = infActiviti.getTaskById(taskId);
    /*add by hb for get next task 20140128 start*/
    String nextTask = "";
    String initiator = (String) infActiviti.getVariableByTaskId(task.getId(), "initiator");
    // 当前任务获取当前流程的流程定义,然后根据流程定义获得所有的节点
    ProcessDefinitionEntity def =
        (ProcessDefinitionEntity)
            ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(task.getProcessDefinitionId());
    List<ActivityImpl> activitiList = def.getActivities();
    // 根据任务获取当前流程执行ID,执行实例以及当前流程节点的ID
    String excId = task.getExecutionId();
    ExecutionEntity execution =
        (ExecutionEntity) runtimeService.createExecutionQuery().executionId(excId).singleResult();
    String activitiId = execution.getActivityId();
    // 循环activitiList 并判断出当前流程所处节点,然后得到当前节点实例,
    // 根据节点实例获取所有从当前节点出发的路径,然后根据路径获得下一个节点实例
    for (ActivityImpl activityImpl : activitiList) {
      String id = activityImpl.getId();
      if (activitiId.equals(id)) {
        log.debug("当前任务:" + activityImpl.getProperty("name"));
        List<PvmTransition> outTransitions =
            activityImpl.getOutgoingTransitions(); // 获取从某个节点出来的所有线路
        for (PvmTransition tr : outTransitions) {
          PvmActivity ac = tr.getDestination(); // 获取线路的终点节点,在这里应该还要加个判断,如果是并行或者相容关口,则需要继续往下找下一个任务。
          if (ac.getProperty("type").equals("parallelGateway")
              || ac.getProperty("type")
                  .equals(
                      "inclusiveGateway")) { // 不能包括互斥关口
                                             // ac.getProperty("type").equals("exclusiveGateway")
            List<PvmTransition> outTransitions2 = ac.getOutgoingTransitions(); // 因为是关口,所以继续往下找任务
            for (PvmTransition pvmTransition : outTransitions2) {
              PvmActivity ac2 = pvmTransition.getDestination();
              nextTask = (String) ac2.getId();
              log.debug("下一个任务----->:" + nextTask);
              nextTaskList.add(nextTask);
            }
          } else {
            nextTask = (String) ac.getId();
            log.debug("下一个任务++++>:" + nextTask);
            nextTaskList.add(nextTask);
          }
        }
        break;
      }
    }

    /*end*/
    rhs.put("task", task);
    rhs.put("initiator", initiator);
    rhs.put("nextTaskList", nextTaskList);
    rhs.put("taskPage", taskPage);
    rhs.put("readonly", readonly);
    getAllUserAndGroupInfo();

    return "success";
  }
Пример #5
0
  public FirstTaskForm execute(CommandContext commandContext) {
    ProcessDefinitionEntity processDefinitionEntity =
        Context.getProcessEngineConfiguration()
            .getDeploymentManager()
            .findDeployedProcessDefinitionById(processDefinitionId);

    if (processDefinitionEntity == null) {
      throw new IllegalArgumentException("cannot find processDefinition : " + processDefinitionId);
    }

    if (processDefinitionEntity.hasStartFormKey()) {
      return this.findStartEventForm(processDefinitionEntity);
    }

    ActivityImpl startActivity = processDefinitionEntity.getInitial();

    if (startActivity.getOutgoingTransitions().size() != 1) {
      throw new IllegalStateException(
          "start activity outgoing transitions cannot more than 1, now is : "
              + startActivity.getOutgoingTransitions().size());
    }

    PvmTransition pvmTransition = startActivity.getOutgoingTransitions().get(0);
    PvmActivity targetActivity = pvmTransition.getDestination();

    if (!"userTask".equals(targetActivity.getProperty("type"))) {
      logger.info("first activity is not userTask, just skip");

      return new FirstTaskForm();
    }

    FirstTaskForm firstTaskForm = new FirstTaskForm();
    firstTaskForm.setProcessDefinitionId(processDefinitionId);
    firstTaskForm.setExists(true);
    firstTaskForm.setTaskForm(true);

    String taskDefinitionKey = targetActivity.getId();
    logger.debug("activityId : {}", targetActivity.getId());
    firstTaskForm.setActivityId(taskDefinitionKey);

    TaskDefinition taskDefinition =
        processDefinitionEntity.getTaskDefinitions().get(taskDefinitionKey);

    Expression expression = taskDefinition.getAssigneeExpression();

    if (expression != null) {
      String expressionText = expression.getExpressionText();
      logger.debug("{}", expressionText);
      logger.debug("{}", startActivity.getProperties());
      logger.debug("{}", processDefinitionEntity.getProperties());
      firstTaskForm.setAssignee(expressionText);
    } else {
      logger.info("cannot find expression : {}, {}", processDefinitionId, taskDefinitionKey);
    }

    String initiatorVariableName =
        (String)
            processDefinitionEntity.getProperty(BpmnParse.PROPERTYNAME_INITIATOR_VARIABLE_NAME);
    firstTaskForm.setInitiatorName(initiatorVariableName);

    DefaultFormHandler formHandler = (DefaultFormHandler) taskDefinition.getTaskFormHandler();

    if (formHandler.getFormKey() != null) {
      String formKey = formHandler.getFormKey().getExpressionText();
      firstTaskForm.setFormKey(formKey);
    } else {
      logger.info("cannot formKey : {}, {}", processDefinitionId, taskDefinitionKey);
    }

    return firstTaskForm;
  }
  public void execute(ActivityExecution execution) throws Exception {

    execution.inactivate();
    lockConcurrentRoot(execution);

    PvmActivity activity = execution.getActivity();
    if (!activeConcurrentExecutionsExist(execution)) {

      if (log.isDebugEnabled()) {
        log.debug("inclusive gateway '{}' activates", activity.getId());
      }

      List<ActivityExecution> joinedExecutions =
          execution.findInactiveConcurrentExecutions(activity);
      String defaultSequenceFlow = (String) execution.getActivity().getProperty("default");
      List<PvmTransition> transitionsToTake = new ArrayList<PvmTransition>();

      for (PvmTransition outgoingTransition : execution.getActivity().getOutgoingTransitions()) {

        Expression skipExpression = outgoingTransition.getSkipExpression();
        if (!SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression)) {
          if (defaultSequenceFlow == null
              || !outgoingTransition.getId().equals(defaultSequenceFlow)) {
            Condition condition =
                (Condition) outgoingTransition.getProperty(BpmnParse.PROPERTYNAME_CONDITION);
            if (condition == null || condition.evaluate(execution)) {
              transitionsToTake.add(outgoingTransition);
            }
          }
        } else if (SkipExpressionUtil.shouldSkipFlowElement(execution, skipExpression)) {
          transitionsToTake.add(outgoingTransition);
        }
      }

      if (!transitionsToTake.isEmpty()) {
        execution.takeAll(transitionsToTake, joinedExecutions);

      } else {

        if (defaultSequenceFlow != null) {
          PvmTransition defaultTransition =
              execution.getActivity().findOutgoingTransition(defaultSequenceFlow);
          if (defaultTransition != null) {
            execution.take(defaultTransition);
          } else {
            throw new ActivitiException(
                "Default sequence flow '" + defaultSequenceFlow + "' could not be not found");
          }
        } else {
          // No sequence flow could be found, not even a default one
          throw new ActivitiException(
              "No outgoing sequence flow of the inclusive gateway '"
                  + execution.getActivity().getId()
                  + "' could be selected for continuing the process");
        }
      }

    } else {
      if (log.isDebugEnabled()) {
        log.debug("Inclusive gateway '{}' does not activate", activity.getId());
      }
    }
  }