public static void linkIntermediateLinks()

in jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java [264:335]


    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,
                                    org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE, catchNode,
                                    org.jbpm.workflow.core.Node.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());
        }

    }