use of org.knime.core.node.workflow.virtual.parchunk.FlowVirtualScopeContext in project knime-core by knime.
the class NativeNodeContainer method initVirtualScopeFileStoreHandler.
/**
* Inits file store handler for nodes that are part of a {@link FlowVirtualScopeContext}.
*
* @return the file store handler or <code>null</code> if not a virtual scope
*/
private IWriteFileStoreHandler initVirtualScopeFileStoreHandler() {
FlowVirtualScopeContext virtualScope = getFlowScopeContextFromHierarchy(FlowVirtualScopeContext.class, getFlowObjectStack());
NativeNodeContainer hostNode = virtualScope != null ? virtualScope.getHostNode().orElse(null) : null;
if (hostNode != null) {
IFileStoreHandler fsh = hostNode.getNode().getFileStoreHandler();
if (fsh instanceof IWriteFileStoreHandler) {
return initWriteFileStoreHandlerReference((IWriteFileStoreHandler) fsh);
} else if (fsh == null) {
// can happen if the node associated with the virtual scope is reset
throw new IllegalStateException("No file store handler given. Try to re-execute '" + hostNode.getNameWithID() + "'");
} else {
throw new IllegalStateException("No file store handler given. Most likely an implementation error");
}
} else {
return null;
}
}
use of org.knime.core.node.workflow.virtual.parchunk.FlowVirtualScopeContext 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;
}
}
Aggregations