Beispiel #1
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);
      }
    }
  }
  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());
      }
    }
  }