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());
}
}
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");
}
}
}
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);
}
}
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." ); } } }
*/
}
Aggregations