Search in sources :

Example 11 with IntermediateLink

use of io.automatiko.engine.workflow.bpmn2.core.IntermediateLink in project kogito-runtimes by kiegroup.

the class ProcessHandler method linkIntermediateLinks.

public static void linkIntermediateLinks(NodeContainer process, List<IntermediateLink> links) {
    if (links == null) {
        return;
    }
    Map<String, IntermediateLink> catchLinks = new HashMap<>();
    Map<String, Collection<IntermediateLink>> throwLinks = new HashMap<>();
    Collection<IntermediateLink> noNameLinks = new ArrayList<>();
    Collection<IntermediateLink> duplicatedTarget = new LinkedHashSet<>();
    Collection<IntermediateLink> unconnectedTarget = new ArrayList<>();
    // collect errors and nodes in first loop
    for (IntermediateLink link : links) {
        if (link.getName() == null || link.getName().isEmpty()) {
            noNameLinks.add(link);
        } else if (link.isThrowLink()) {
            throwLinks.computeIfAbsent(link.getName(), s -> new ArrayList<>()).add(link);
        } else {
            IntermediateLink duplicateLink = catchLinks.putIfAbsent(link.getName(), link);
            if (duplicateLink != null) {
                duplicatedTarget.add(duplicateLink);
                duplicatedTarget.add(link);
            }
        }
    }
    // second loop for connection
    for (IntermediateLink catchLink : catchLinks.values()) {
        Collection<IntermediateLink> associatedLinks = throwLinks.remove(catchLink.getName());
        if (associatedLinks != null) {
            // connect throw to catch
            Node catchNode = findNodeByIdOrUniqueIdInMetadata(process, catchLink.getUniqueId());
            if (catchNode != null) {
                for (IntermediateLink throwLink : associatedLinks) {
                    Node throwNode = findNodeByIdOrUniqueIdInMetadata(process, throwLink.getUniqueId());
                    if (throwNode != null) {
                        Connection result = new ConnectionImpl(throwNode, NodeImpl.CONNECTION_DEFAULT_TYPE, catchNode, NodeImpl.CONNECTION_DEFAULT_TYPE);
                        result.setMetaData("linkNodeHidden", "yes");
                    }
                }
            }
        } else {
            unconnectedTarget.add(catchLink);
        }
    }
    // throw exception if any error (this is done at the end of the process to show the user as much errors as possible)
    StringBuilder errors = new StringBuilder();
    if (!noNameLinks.isEmpty()) {
        formatError(errors, "These nodes do not have a name ", noNameLinks.stream(), process);
    }
    if (!duplicatedTarget.isEmpty()) {
        formatError(errors, "\nThere are multiple catch nodes with the same name ", duplicatedTarget.stream(), process);
    }
    if (!unconnectedTarget.isEmpty()) {
        formatError(errors, "\nThere is not connection from any throw link to these catch links ", unconnectedTarget.stream(), process);
    }
    if (!throwLinks.isEmpty()) {
        formatError(errors, "\nThere is not connection to any catch link from these throw links ", throwLinks.values().stream().flatMap(Collection::stream), process);
    }
    if (errors.length() > 0) {
        throw new ProcessParsingValidationException(errors.toString());
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) HumanTaskNode(org.jbpm.workflow.core.node.HumanTaskNode) BoundaryEventNode(org.jbpm.workflow.core.node.BoundaryEventNode) StartNode(org.jbpm.workflow.core.node.StartNode) CompositeNode(org.jbpm.workflow.core.node.CompositeNode) StateNode(org.jbpm.workflow.core.node.StateNode) RuleSetNode(org.jbpm.workflow.core.node.RuleSetNode) SubProcessNode(org.jbpm.workflow.core.node.SubProcessNode) CompositeContextNode(org.jbpm.workflow.core.node.CompositeContextNode) KogitoNode(org.kie.kogito.internal.process.runtime.KogitoNode) StateBasedNode(org.jbpm.workflow.core.node.StateBasedNode) EventSubProcessNode(org.jbpm.workflow.core.node.EventSubProcessNode) FaultNode(org.jbpm.workflow.core.node.FaultNode) WorkItemNode(org.jbpm.workflow.core.node.WorkItemNode) ActionNode(org.jbpm.workflow.core.node.ActionNode) EndNode(org.jbpm.workflow.core.node.EndNode) EventNode(org.jbpm.workflow.core.node.EventNode) Node(org.kie.api.definition.process.Node) ArrayList(java.util.ArrayList) Connection(org.jbpm.workflow.core.Connection) ConnectionImpl(org.jbpm.workflow.core.impl.ConnectionImpl) IntermediateLink(org.jbpm.bpmn2.core.IntermediateLink) Collection(java.util.Collection)

Example 12 with IntermediateLink

use of io.automatiko.engine.workflow.bpmn2.core.IntermediateLink in project automatiko-engine by automatiko-io.

the class ProcessHandler method linkIntermediateLinks.

public static void linkIntermediateLinks(NodeContainer process, List<IntermediateLink> links) {
    if (null != links) {
        // Search throw links
        ArrayList<IntermediateLink> throwLinks = new ArrayList<IntermediateLink>();
        for (IntermediateLink aLinks : links) {
            if (aLinks.isThrowLink()) {
                throwLinks.add(aLinks);
            }
        }
        // Look for catch links for a throw link
        for (IntermediateLink throwLink : throwLinks) {
            ArrayList<IntermediateLink> linksWithSharedNames = new ArrayList<IntermediateLink>();
            for (IntermediateLink aLink : links) {
                if (throwLink.getName().equals(aLink.getName())) {
                    linksWithSharedNames.add(aLink);
                }
            }
            if (linksWithSharedNames.size() < 2) {
                throw new IllegalArgumentException("There should be at least 2 link events to make a connection");
            }
            linksWithSharedNames.remove(throwLink);
            // Make the connections
            Node t = findNodeByIdOrUniqueIdInMetadata(process, throwLink.getUniqueId());
            // connect throw to catch
            for (IntermediateLink catchLink : linksWithSharedNames) {
                Node c = findNodeByIdOrUniqueIdInMetadata(process, catchLink.getUniqueId());
                if (t != null && c != null) {
                    Connection result = new ConnectionImpl(t, NodeImpl.CONNECTION_DEFAULT_TYPE, c, NodeImpl.CONNECTION_DEFAULT_TYPE);
                    result.setMetaData("linkNodeHidden", "yes");
                }
            }
            // Remove processed links
            links.remove(throwLink);
            links.removeAll(linksWithSharedNames);
        }
        if (links.size() > 0) {
            throw new IllegalArgumentException(links.size() + " links were not processed");
        }
    }
}
Also used : StateBasedNode(io.automatiko.engine.workflow.process.core.node.StateBasedNode) CompositeContextNode(io.automatiko.engine.workflow.process.core.node.CompositeContextNode) ActionNode(io.automatiko.engine.workflow.process.core.node.ActionNode) FaultNode(io.automatiko.engine.workflow.process.core.node.FaultNode) EventSubProcessNode(io.automatiko.engine.workflow.process.core.node.EventSubProcessNode) StateNode(io.automatiko.engine.workflow.process.core.node.StateNode) WorkItemNode(io.automatiko.engine.workflow.process.core.node.WorkItemNode) SubProcessNode(io.automatiko.engine.workflow.process.core.node.SubProcessNode) RuleSetNode(io.automatiko.engine.workflow.process.core.node.RuleSetNode) CompositeNode(io.automatiko.engine.workflow.process.core.node.CompositeNode) Node(io.automatiko.engine.api.definition.process.Node) HumanTaskNode(io.automatiko.engine.workflow.process.core.node.HumanTaskNode) BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) StartNode(io.automatiko.engine.workflow.process.core.node.StartNode) EndNode(io.automatiko.engine.workflow.process.core.node.EndNode) EventNode(io.automatiko.engine.workflow.process.core.node.EventNode) ArrayList(java.util.ArrayList) Connection(io.automatiko.engine.workflow.process.core.Connection) ConnectionImpl(io.automatiko.engine.workflow.process.core.impl.ConnectionImpl) IntermediateLink(io.automatiko.engine.workflow.bpmn2.core.IntermediateLink)

Example 13 with IntermediateLink

use of io.automatiko.engine.workflow.bpmn2.core.IntermediateLink in project automatiko-engine by automatiko-io.

the class IntermediateThrowEventHandler method handleLinkNode.

protected void handleLinkNode(Element element, Node node, org.w3c.dom.Node xmlLinkNode, ExtensibleXmlParser parser) {
    node.setName(element.getAttribute("name"));
    NamedNodeMap linkAttr = xmlLinkNode.getAttributes();
    String name = linkAttr.getNamedItem("name").getNodeValue();
    String id = element.getAttribute("id");
    node.setMetaData("UniqueId", id);
    node.setMetaData(LINK_NAME, name);
    org.w3c.dom.Node xmlNode = xmlLinkNode.getFirstChild();
    NodeContainer nodeContainer = (NodeContainer) parser.getParent();
    IntermediateLink aLink = new IntermediateLink();
    aLink.setName(name);
    aLink.setUniqueId(id);
    while (null != xmlNode) {
        String nodeName = xmlNode.getNodeName();
        if (LINK_TARGET.equals(nodeName)) {
            String target = xmlNode.getTextContent();
            node.setMetaData(LINK_TARGET, target);
        }
        if (LINK_SOURCE.equals(nodeName)) {
            String source = xmlNode.getTextContent();
            ArrayList<String> sources = (ArrayList<String>) node.getMetaData().get(LINK_SOURCE);
            // if there is no list, create one
            if (null == sources) {
                sources = new ArrayList<String>();
            }
            // to connect nodes.
            aLink.addSource(source);
            // to do the xml dump
            sources.add(source);
            node.setMetaData(LINK_SOURCE, sources);
        }
        xmlNode = xmlNode.getNextSibling();
    }
    aLink.configureThrow();
    if (nodeContainer instanceof ExecutableProcess) {
        ExecutableProcess process = (ExecutableProcess) nodeContainer;
        List<IntermediateLink> links = (List<IntermediateLink>) process.getMetaData().get(ProcessHandler.LINKS);
        if (null == links) {
            links = new ArrayList<IntermediateLink>();
        }
        links.add(aLink);
        process.setMetaData(ProcessHandler.LINKS, links);
    } else if (nodeContainer instanceof CompositeNode) {
        CompositeNode subprocess = (CompositeNode) nodeContainer;
        List<IntermediateLink> links = (List<IntermediateLink>) subprocess.getMetaData().get(ProcessHandler.LINKS);
        if (null == links) {
            links = new ArrayList<IntermediateLink>();
        }
        links.add(aLink);
        subprocess.setMetaData(ProcessHandler.LINKS, links);
    }
}
Also used : NamedNodeMap(org.w3c.dom.NamedNodeMap) ArrayList(java.util.ArrayList) NodeContainer(io.automatiko.engine.workflow.process.core.NodeContainer) IntermediateLink(io.automatiko.engine.workflow.bpmn2.core.IntermediateLink) CompositeNode(io.automatiko.engine.workflow.process.core.node.CompositeNode) ExecutableProcess(io.automatiko.engine.workflow.process.executable.core.ExecutableProcess) ArrayList(java.util.ArrayList) NodeList(org.w3c.dom.NodeList) List(java.util.List)

Example 14 with IntermediateLink

use of io.automatiko.engine.workflow.bpmn2.core.IntermediateLink in project automatiko-engine by automatiko-io.

the class SubProcessHandler method handleCompositeContextNode.

@SuppressWarnings("unchecked")
protected void handleCompositeContextNode(final Node node, final Element element, final String uri, final String localName, final ExtensibleXmlParser parser) throws SAXException {
    super.handleNode(node, element, uri, localName, parser);
    CompositeContextNode compositeNode = (CompositeContextNode) node;
    List<SequenceFlow> connections = (List<SequenceFlow>) compositeNode.getMetaData(ProcessHandler.CONNECTIONS);
    handleScript(compositeNode, element, "onEntry");
    handleScript(compositeNode, element, "onExit");
    List<IntermediateLink> throwLinks = (List<IntermediateLink>) compositeNode.getMetaData(ProcessHandler.LINKS);
    ProcessHandler.linkIntermediateLinks(compositeNode, throwLinks);
    ProcessHandler processHandler = new ProcessHandler();
    processHandler.linkConnections(compositeNode, connections);
    processHandler.linkBoundaryEvents(compositeNode);
    // This must be done *after* linkConnections(process, connections)
    // because it adds hidden connections for compensations
    List<Association> associations = (List<Association>) compositeNode.getMetaData(ProcessHandler.ASSOCIATIONS);
    ProcessHandler.linkAssociations((Definitions) compositeNode.getMetaData("Definitions"), compositeNode, associations);
// TODO: do we fully support interruping ESP's?
/**
 * for( org.kie.api.definition.process.Node subNode : compositeNode.getNodes() )
 * { if( subNode instanceof StartNode ) { if( ! ((StartNode)
 * subNode).isInterrupting() ) { throw new
 * IllegalArgumentException("Non-interrupting event subprocesses are not yet
 * fully supported." ); } } }
 */
}
Also used : Association(io.automatiko.engine.workflow.bpmn2.core.Association) CompositeContextNode(io.automatiko.engine.workflow.process.core.node.CompositeContextNode) SequenceFlow(io.automatiko.engine.workflow.bpmn2.core.SequenceFlow) List(java.util.List) IntermediateLink(io.automatiko.engine.workflow.bpmn2.core.IntermediateLink)

Aggregations

ArrayList (java.util.ArrayList)12 List (java.util.List)11 IntermediateLink (org.jbpm.bpmn2.core.IntermediateLink)9 RuleFlowProcess (org.jbpm.ruleflow.core.RuleFlowProcess)6 CompositeNode (org.jbpm.workflow.core.node.CompositeNode)6 NamedNodeMap (org.w3c.dom.NamedNodeMap)6 IntermediateLink (io.automatiko.engine.workflow.bpmn2.core.IntermediateLink)5 CompositeNode (io.automatiko.engine.workflow.process.core.node.CompositeNode)3 NodeContainer (org.jbpm.workflow.core.NodeContainer)3 CompositeContextNode (org.jbpm.workflow.core.node.CompositeContextNode)3 Association (io.automatiko.engine.workflow.bpmn2.core.Association)2 SequenceFlow (io.automatiko.engine.workflow.bpmn2.core.SequenceFlow)2 NodeContainer (io.automatiko.engine.workflow.process.core.NodeContainer)2 CompositeContextNode (io.automatiko.engine.workflow.process.core.node.CompositeContextNode)2 ExecutableProcess (io.automatiko.engine.workflow.process.executable.core.ExecutableProcess)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 Association (org.jbpm.bpmn2.core.Association)2 SequenceFlow (org.jbpm.bpmn2.core.SequenceFlow)2