예제 #1
0
  // TODO - change the return type and the factory parameter to be Definitions and ObjectFactory,
  // and move to bpmn-schema
  public BpmnDefinitions correctFlowNodeRefs(
      final BpmnDefinitions definitions, final BpmnObjectFactory factory)
      throws JAXBException, TransformerException {

    JAXBContext context =
        JAXBContext.newInstance(
            factory.getClass(),
            com.processconfiguration.ObjectFactory.class,
            org.omg.spec.bpmn._20100524.di.ObjectFactory.class,
            org.omg.spec.bpmn._20100524.model.ObjectFactory.class,
            org.omg.spec.dd._20100524.dc.ObjectFactory.class,
            org.omg.spec.dd._20100524.di.ObjectFactory.class,
            com.signavio.ObjectFactory.class);

    // Marshal the BPMN into a DOM tree
    DOMResult intermediateResult = new DOMResult();
    Marshaller marshaller = context.createMarshaller();
    marshaller.marshal(factory.createDefinitions(definitions), intermediateResult);

    // Apply the XSLT transformation, generating a new DOM tree
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer =
        transformerFactory.newTransformer(
            new StreamSource(
                getClass().getClassLoader().getResourceAsStream("xsd/fix-flowNodeRef.xsl")));
    DOMSource finalSource = new DOMSource(intermediateResult.getNode());
    DOMResult finalResult = new DOMResult();
    transformer.transform(finalSource, finalResult);

    // Unmarshal back to JAXB
    Object def2 = context.createUnmarshaller().unmarshal(finalResult.getNode());
    return ((JAXBElement<BpmnDefinitions>) def2).getValue();
  }
예제 #2
0
  private void rewriteFlowElements(List<JAXBElement<? extends TFlowElement>> jfel)
      throws CanoniserException {
    for (JAXBElement<? extends TFlowElement> flowElement :
        new ArrayList<JAXBElement<? extends TFlowElement>>(jfel)) {
      if (flowElement.getValue() instanceof TFlowNode
          && !(flowElement.getValue() instanceof TGateway)) {
        TFlowNode flowNode = (TFlowNode) flowElement.getValue();

        if (flowNode.getIncoming().size() > 1) {

          // Create a converging XOR gateway
          BpmnObjectFactory factory = new BpmnObjectFactory();
          TExclusiveGateway xor = factory.createTExclusiveGateway();
          xor.setId(flowNode.getId() + "_implicit_join");
          xor.setGatewayDirection(TGatewayDirection.CONVERGING);
          jfel.add(factory.createExclusiveGateway(xor));

          // Retarget the incoming flows to the XOR gateway
          for (QName incoming : flowNode.getIncoming()) {
            BpmnSequenceFlow incomingFlow = (BpmnSequenceFlow) findElement(incoming);
            incomingFlow.setTargetRef(xor);
          }

          xor.getIncoming().addAll(flowNode.getIncoming());
          flowNode.getIncoming().clear();

          // Create a flow from the XOR gateway to the flow node
          BpmnSequenceFlow flow = factory.createTSequenceFlow();
          flow.setId(
              flowNode.getId()
                  + "_implicit_join_edge"); // TODO - should use IdFactory to ward against clashes
          flow.setSourceRef(xor);
          flow.setTargetRef(flowNode);
          jfel.add(factory.createSequenceFlow(flow));

          QName flowQName = new QName(targetNamespace, flow.getId());
          flowNode.getIncoming().add(flowQName);
          xor.getOutgoing().add(flowQName);
        }

        if (flowNode.getOutgoing().size() > 1) {

          // Create a diverging AND gateway
          BpmnObjectFactory factory = new BpmnObjectFactory();
          TParallelGateway and = factory.createTParallelGateway();
          and.setId(flowNode.getId() + "_implicit_split");
          and.setGatewayDirection(TGatewayDirection.DIVERGING);
          jfel.add(factory.createParallelGateway(and));

          // Change the source of the outgoing flows to be from the AND gateway
          for (QName outgoing : flowNode.getOutgoing()) {
            BpmnSequenceFlow outgoingFlow = (BpmnSequenceFlow) findElement(outgoing);
            outgoingFlow.setSourceRef(and);
          }

          and.getOutgoing().addAll(flowNode.getOutgoing());
          flowNode.getOutgoing().clear();

          // Create a flow to the AND gateway from the flow node
          BpmnSequenceFlow flow = factory.createTSequenceFlow();
          flow.setId(
              flowNode.getId()
                  + "_implicit_split_edge"); // TODO - should use IdFactory to ward against clashes
          flow.setSourceRef(flowNode);
          flow.setTargetRef(and);
          jfel.add(factory.createSequenceFlow(flow));

          QName flowQName = new QName(targetNamespace, flow.getId());
          flowNode.getOutgoing().add(flowQName);
          and.getIncoming().add(flowQName);
        }

        // Recursively rewrite any subprocesses
        if (flowNode instanceof TSubProcess) {
          rewriteFlowElements(((TSubProcess) flowNode).getFlowElement());
        }
      }

      // Rewrite mixed gateways
      if (flowElement.getValue() instanceof TGateway) {
        TGateway gateway = (TGateway) flowElement.getValue();

        if (gateway.getIncoming().size() > 1 && gateway.getOutgoing().size() > 1) {

          // Create a diverging XOR gateway
          BpmnObjectFactory factory = new BpmnObjectFactory();
          TGateway newGateway;
          if (gateway instanceof TComplexGateway) {
            newGateway = factory.createTComplexGateway();
            jfel.add(factory.createComplexGateway((TComplexGateway) newGateway));
          } else if (gateway instanceof TEventBasedGateway) {
            newGateway = factory.createTEventBasedGateway();
            jfel.add(factory.createEventBasedGateway((TEventBasedGateway) newGateway));
          } else if (gateway instanceof TExclusiveGateway) {
            newGateway = factory.createTExclusiveGateway();
            jfel.add(factory.createExclusiveGateway((TExclusiveGateway) newGateway));
          } else if (gateway instanceof TInclusiveGateway) {
            newGateway = factory.createTInclusiveGateway();
            jfel.add(factory.createInclusiveGateway((TInclusiveGateway) newGateway));
          } else if (gateway instanceof TParallelGateway) {
            newGateway = factory.createTParallelGateway();
            jfel.add(factory.createParallelGateway((TParallelGateway) newGateway));
          } else {
            throw new CanoniserException(
                "Mixed gateway "
                    + gateway.getId()
                    + " of type "
                    + gateway.getClass()
                    + " unsupported");
          }
          assert newGateway != null;
          newGateway.setId(gateway.getId() + "_mixed_split");
          newGateway.setGatewayDirection(TGatewayDirection.DIVERGING);

          // Re-source the outgoing flows from the diverging gateway
          for (QName outgoing : gateway.getOutgoing()) {
            BpmnSequenceFlow outgoingFlow = (BpmnSequenceFlow) findElement(outgoing);
            outgoingFlow.setSourceRef(newGateway);
          }
          gateway.setGatewayDirection(TGatewayDirection.CONVERGING);
          gateway.getOutgoing().clear();

          // Create a flow from the original (now converging) gateway to the new diverging gateway
          BpmnSequenceFlow flow = factory.createTSequenceFlow();
          flow.setId(gateway.getId() + "_mixed_edge");
          flow.setSourceRef(gateway);
          flow.setTargetRef(newGateway);
          jfel.add(factory.createSequenceFlow(flow));

          QName flowQName = new QName(targetNamespace, flow.getId());
          newGateway.getIncoming().add(flowQName);
          gateway.getOutgoing().add(flowQName);
        }
      }
    }
  }