Search in sources :

Example 1 with WorkflowSegment

use of org.knime.core.node.workflow.capture.WorkflowSegment in project knime-core by knime.

the class WorkflowCaptureOperation method capture.

/**
 * Carries out the actual capture-operation and returns the captured sub-workflow as a {@link WorkflowSegment}.
 *
 * @return the captured sub-workflow
 */
public WorkflowSegment capture() {
    WorkflowManager tempParent = null;
    try (WorkflowLock lock = m_wfm.lock()) {
        NodeID endNodeID = m_endNode.getID();
        WorkflowCreationHelper workflowCreationHelper = new WorkflowCreationHelper();
        Optional.ofNullable(NodeContext.getContext()).map(NodeContext::getWorkflowManager).map(WorkflowManager::getContext).ifPresent(workflowCreationHelper::setWorkflowContext);
        tempParent = WorkflowManager.EXTRACTED_WORKFLOW_ROOT.createAndAddProject("Capture-" + endNodeID, workflowCreationHelper);
        // "scope body" -- will copy those nodes later
        List<NodeContainer> nodesInScope = m_wfm.getWorkflow().getNodesInScope(m_endNode);
        // "scope body" and port object ref readers -- will determine bounding box and move them to the top left
        List<NodeContainer> nodesToDetermineBoundingBox = new ArrayList<>(nodesInScope);
        // copy nodes in scope body
        WorkflowCopyContent.Builder copyContent = WorkflowCopyContent.builder();
        NodeID[] allIDs = nodesInScope.stream().map(NodeContainer::getID).toArray(NodeID[]::new);
        HashSet<NodeID> allIDsHashed = new HashSet<>(Arrays.asList(allIDs));
        // port object reader nodes grouped by the original node
        Map<NodeID, List<NodeID>> portObjectReaderGroups = new HashMap<>();
        Set<NodeIDSuffix> addedPortObjectReaderNodes = new HashSet<>();
        NodeID[] allButScopeIDs = ArrayUtils.removeElements(allIDs, endNodeID, m_startNode.getID());
        copyContent.setNodeIDs(allButScopeIDs);
        copyContent.setIncludeInOutConnections(false);
        final int[] boundingBox = NodeUIInformation.getBoundingBoxOf(nodesToDetermineBoundingBox);
        final int[] moveUIDist = new int[] { -boundingBox[0] + 50, -boundingBox[1] + 50 };
        copyContent.setPositionOffset(moveUIDist);
        tempParent.copyFromAndPasteHere(m_wfm, copyContent.build());
        // collect nodes outside the scope body but connected to the scope body (only incoming)
        // maps to 'pasted' node id
        Map<Pair<NodeID, Integer>, NodeID> visitedSrcPorts = new HashMap<>();
        FlowVirtualScopeContext virtualScopeContext = getVirtualScopeContext(m_startNode);
        for (int i = 0; i < allButScopeIDs.length; i++) {
            NodeContainer oldNode = m_wfm.getNodeContainer(allButScopeIDs[i]);
            for (int p = 0; p < oldNode.getNrInPorts(); p++) {
                ConnectionContainer c = m_wfm.getIncomingConnectionFor(allButScopeIDs[i], p);
                if (c == null) {
                // ignore: no incoming connection
                } else if (allIDsHashed.contains(c.getSource())) {
                // ignore: connection already retained by paste persistor
                } else {
                    Pair<NodeID, Integer> currentSrcPort = Pair.create(c.getSource(), c.getSourcePort());
                    if (!visitedSrcPorts.containsKey(currentSrcPort)) {
                        // only add portObjectReader if not inserted already in previous loop iteration
                        // add port object reader
                        NodeID pastedID = addPortObjectReferenceReader(m_wfm, tempParent, c, virtualScopeContext);
                        NodeIDSuffix pastedIDSuffix = NodeIDSuffix.create(tempParent.getID(), pastedID);
                        // position
                        NodeID sourceID = c.getSource();
                        NodeUIInformation sourceUIInformation = getSourceNodeAndUIInformation(sourceID, c.getDest(), nodesToDetermineBoundingBox);
                        tempParent.getNodeContainer(pastedID).setUIInformation(sourceUIInformation);
                        // keeping track
                        visitedSrcPorts.put(Pair.create(c.getSource(), c.getSourcePort()), pastedID);
                        addedPortObjectReaderNodes.add(pastedIDSuffix);
                        portObjectReaderGroups.computeIfAbsent(currentSrcPort.getFirst(), id -> new ArrayList<>()).add(pastedID);
                    }
                    // connect all new port object readers to the in-scope-nodes
                    NodeIDSuffix destID = NodeIDSuffix.create(m_wfm.getID(), c.getDest());
                    tempParent.addConnection(visitedSrcPorts.get(currentSrcPort), 1, destID.prependParent(tempParent.getID()), c.getDestPort());
                }
            }
        }
        groupAndPositionPortObjectReaders(tempParent, portObjectReaderGroups, addedPortObjectReaderNodes, moveUIDist);
        // transfer editor settings, too
        tempParent.setEditorUIInformation(m_wfm.getEditorUIInformation());
        List<Input> workflowFragmentInputs = getInputs();
        List<Output> workflowFragmentOutputs = getOutputs();
        return new WorkflowSegment(tempParent, workflowFragmentInputs, workflowFragmentOutputs, addedPortObjectReaderNodes);
    } catch (Exception e) {
        if (tempParent != null) {
            WorkflowManager.EXTRACTED_WORKFLOW_ROOT.removeNode(tempParent.getID());
            tempParent = null;
        }
        throw e;
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Input(org.knime.core.node.workflow.capture.WorkflowSegment.Input) Output(org.knime.core.node.workflow.capture.WorkflowSegment.Output) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) Pair(org.knime.core.util.Pair) CanceledExecutionException(org.knime.core.node.CanceledExecutionException) IOException(java.io.IOException) FlowVirtualScopeContext(org.knime.core.node.workflow.virtual.parchunk.FlowVirtualScopeContext) WorkflowSegment(org.knime.core.node.workflow.capture.WorkflowSegment) NodeIDSuffix(org.knime.core.node.workflow.NodeID.NodeIDSuffix)

Example 2 with WorkflowSegment

use of org.knime.core.node.workflow.capture.WorkflowSegment in project knime-core by knime.

the class WorkflowCaptureOperation method getInputs.

/**
 * Returns the input of the (to be) captured sub-workflow, i.e. the same ports {@link #capture()} with a
 * subsequent {@link WorkflowSegment#getConnectedInputs()} would return.
 *
 * @return the inputs of the (to be) captured workflow fragment
 */
public List<Input> getInputs() {
    List<Input> res = new ArrayList<>();
    for (int i = 0; i < m_startNode.getNrOutPorts(); i++) {
        Set<PortID> connections = m_wfm.getOutgoingConnectionsFor(m_startNode.getID(), i).stream().map(cc -> {
            return new PortID(NodeIDSuffix.create(m_wfm.getID(), cc.getDest()), cc.getDestPort());
        }).collect(Collectors.toSet());
        NodeOutPort outPort = m_startNode.getOutPort(i);
        res.add(new Input(outPort.getPortType(), castToDTSpecOrNull(outPort.getPortObjectSpec()), connections));
    }
    return res;
}
Also used : WorkflowSegment(org.knime.core.node.workflow.capture.WorkflowSegment) Arrays(java.util.Arrays) DataTableSpec(org.knime.core.data.DataTableSpec) CanceledExecutionException(org.knime.core.node.CanceledExecutionException) HashMap(java.util.HashMap) ArrayUtils(org.apache.commons.lang3.ArrayUtils) NodeIDSuffix(org.knime.core.node.workflow.NodeID.NodeIDSuffix) ConnectionType(org.knime.core.node.workflow.ConnectionContainer.ConnectionType) ArrayList(java.util.ArrayList) Pair(org.knime.core.util.Pair) HashSet(java.util.HashSet) PortID(org.knime.core.node.workflow.capture.WorkflowSegment.PortID) NodeLogger(org.knime.core.node.NodeLogger) Map(java.util.Map) PortObjectInNodeModel(org.knime.core.node.exec.dataexchange.in.PortObjectInNodeModel) PortType(org.knime.core.node.port.PortType) Output(org.knime.core.node.workflow.capture.WorkflowSegment.Output) Input(org.knime.core.node.workflow.capture.WorkflowSegment.Input) Set(java.util.Set) PortObjectSpec(org.knime.core.node.port.PortObjectSpec) IOException(java.io.IOException) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) PortObjectRepository(org.knime.core.node.exec.dataexchange.PortObjectRepository) List(java.util.List) Optional(java.util.Optional) CollapseIntoMetaNodeResult(org.knime.core.node.workflow.action.CollapseIntoMetaNodeResult) CheckUtils(org.knime.core.node.util.CheckUtils) PortObject(org.knime.core.node.port.PortObject) FlowVirtualScopeContext(org.knime.core.node.workflow.virtual.parchunk.FlowVirtualScopeContext) Input(org.knime.core.node.workflow.capture.WorkflowSegment.Input) ArrayList(java.util.ArrayList) PortID(org.knime.core.node.workflow.capture.WorkflowSegment.PortID)

Aggregations

IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 List (java.util.List)2 CanceledExecutionException (org.knime.core.node.CanceledExecutionException)2 NodeIDSuffix (org.knime.core.node.workflow.NodeID.NodeIDSuffix)2 WorkflowSegment (org.knime.core.node.workflow.capture.WorkflowSegment)2 Input (org.knime.core.node.workflow.capture.WorkflowSegment.Input)2 Output (org.knime.core.node.workflow.capture.WorkflowSegment.Output)2 FlowVirtualScopeContext (org.knime.core.node.workflow.virtual.parchunk.FlowVirtualScopeContext)2 Pair (org.knime.core.util.Pair)2 Arrays (java.util.Arrays)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Set (java.util.Set)1 UUID (java.util.UUID)1 Collectors (java.util.stream.Collectors)1 ArrayUtils (org.apache.commons.lang3.ArrayUtils)1 DataTableSpec (org.knime.core.data.DataTableSpec)1