Search in sources :

Example 1 with VirtualSubNodeOutputNodeModel

use of org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel in project knime-core by knime.

the class SubNodeContainer method performLoadContent.

/**
 * {@inheritDoc}
 */
@Override
WorkflowCopyContent performLoadContent(final SingleNodeContainerPersistor nodePersistor, final Map<Integer, BufferedDataTable> tblRep, final FlowObjectStack inStack, final ExecutionMonitor exec, final LoadResult loadResult, final boolean preserveNodeMessage) throws CanceledExecutionException {
    SubNodeContainerPersistor subNodePersistor = (SubNodeContainerPersistor) nodePersistor;
    WorkflowPersistor workflowPersistor = subNodePersistor.getWorkflowPersistor();
    // TODO pass in a filter input stack
    m_wfm.loadContent(workflowPersistor, tblRep, inStack, exec, loadResult, preserveNodeMessage);
    if (workflowPersistor.isDirtyAfterLoad() || m_wfm.isDirty()) {
        setDirty();
    }
    InternalNodeContainerState loadState = nodePersistor.getMetaPersistor().getState();
    if (!m_wfm.getInternalState().equals(loadState)) {
        // can happen for workflows that were exported without data;
        // the same check is done by the caller (WorkflowManager#postLoad) and handled appropriately
        setInternalState(m_wfm.getInternalState(), false);
    }
    NodeSettingsRO modelSettings = subNodePersistor.getSNCSettings().getModelSettings();
    if (modelSettings != null) {
        try {
            loadModelSettingsIntoDialogNodes(modelSettings, false);
        } catch (InvalidSettingsException e) {
            final String msg = "Could not load Wrapped Metanode configuration into dialog-nodes: " + e.getMessage();
            LOGGER.error(msg, e);
            loadResult.addError(msg);
            setDirty();
        }
    }
    checkInOutNodesAfterLoad(subNodePersistor, loadResult);
    // put data input output node if it was executed;
    final NativeNodeContainer virtualOutNode = getVirtualOutNode();
    LoadVersion l = nodePersistor instanceof FileSingleNodeContainerPersistor ? ((FileSingleNodeContainerPersistor) nodePersistor).getLoadVersion() : LoadVersion.V3010;
    if (l.isOlderThan(LoadVersion.V3010) && virtualOutNode.getInternalState().isExecuted()) {
        VirtualSubNodeOutputNodeModel outNodeModel = getVirtualOutNodeModel();
        PortObject[] outputData = new PortObject[virtualOutNode.getNrInPorts()];
        m_wfm.assembleInputData(getVirtualOutNodeID(), outputData);
        outNodeModel.postLoadExecute(ArrayUtils.removeAll(outputData, 0));
        // allow node to receive the internal held objects so that the next save operation also persists the
        // array of internal held objects - otherwise we get strange errors with nodes saved in 2.x, then loaded
        // and saved in 3.1+ (and converted ... although unmodified)
        getVirtualOutNode().getNode().assignInternalHeldObjects(outputData, null, getVirtualOutNode().createExecutionContext(), new PortObject[0]);
    }
    setVirtualOutputIntoOutport(m_wfm.getInternalState());
    m_wfmStateChangeListener = createAndAddStateListener();
    getInPort(0).setPortName("Variable Inport");
    getOutPort(0).setPortName("Variable Outport");
    getVirtualInNode().addNodeStateChangeListener(new RefreshPortNamesListener());
    getVirtualOutNode().addNodeStateChangeListener(new RefreshPortNamesListener());
    refreshPortNames();
    return null;
}
Also used : InvalidSettingsException(org.knime.core.node.InvalidSettingsException) NodeSettingsRO(org.knime.core.node.NodeSettingsRO) LoadVersion(org.knime.core.node.workflow.FileWorkflowPersistor.LoadVersion) VirtualSubNodeOutputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel) FlowVariablePortObject(org.knime.core.node.port.flowvariable.FlowVariablePortObject) InactiveBranchPortObject(org.knime.core.node.port.inactive.InactiveBranchPortObject) PortObject(org.knime.core.node.port.PortObject)

Example 2 with VirtualSubNodeOutputNodeModel

use of org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel in project knime-core by knime.

the class SubNodeContainer method setVirtualOutputIntoOutport.

/**
 * Copies data from virtual output node into m_outputs, notifies state listeners if not
 * processing call from parent.
 * @param newState State of the internal WFM to decide whether to publish ports and/or specs.
 */
@SuppressWarnings("null")
private boolean setVirtualOutputIntoOutport(final InternalNodeContainerState newState) {
    // retrieve results and copy to outports
    final VirtualSubNodeOutputNodeModel virtualOutNodeModel = getVirtualOutNodeModel();
    final boolean isInactive = getVirtualOutNode().isInactive();
    final VirtualSubNodeExchange outputExchange = virtualOutNodeModel.getOutputExchange();
    // put objects into output if state of WFM is executed
    boolean publishObjects = newState.isExecuted();
    // publishObjects implies that output node has data or is inactive
    assert !publishObjects || (isInactive || (outputExchange != null && outputExchange.getPortObjects() != null)) : String.format("output node must have data or be inactive, status: %s, inactive: %b, exhange is null: %b, " + "exchange content is null: %s", newState, isInactive, outputExchange == null, outputExchange == null ? "<invalid>" : String.valueOf(outputExchange.getPortObjects() == null));
    boolean publishSpecs = (isInactive || outputExchange != null) && (newState.isConfigured() || newState.isExecuted() || newState.isExecutionInProgress());
    boolean changed = false;
    for (int i = 1; i < m_outputs.length; i++) {
        // not publish spec:     null output
        // inactive output node: inactive branch port object
        // otherwise:            use data from output node
        final PortObjectSpec spec = publishSpecs ? (isInactive ? InactiveBranchPortObjectSpec.INSTANCE : outputExchange.getPortSpecs()[i - 1]) : null;
        changed = m_outputs[i].setSpec(spec) || changed;
        final PortObject object = publishObjects ? (isInactive ? InactiveBranchPortObject.INSTANCE : outputExchange.getPortObjects()[i - 1]) : null;
        changed = m_outputs[i].setObject(object) || changed;
    }
    final PortObjectSpec spec = publishSpecs ? (isInactive ? InactiveBranchPortObjectSpec.INSTANCE : FlowVariablePortObjectSpec.INSTANCE) : null;
    changed = m_outputs[0].setSpec(spec) || changed;
    final PortObject object = publishObjects ? (isInactive ? InactiveBranchPortObject.INSTANCE : FlowVariablePortObject.INSTANCE) : null;
    changed = m_outputs[0].setObject(object) || changed;
    final FlowObjectStack outgoingFlowObjectStack = getOutgoingFlowObjectStack();
    // TODO API to remove variables from stack, then remove variables no longer in output node and update "changed"
    if (publishObjects && !isInactive) {
        for (FlowVariable f : outputExchange.getFlowVariables()) {
            outgoingFlowObjectStack.push(f.cloneAndUnsetOwner());
        }
    } else {
        // outgoing stack may be null if reset is called twice in a row (or once but no configure was called)
        if (outgoingFlowObjectStack != null) {
            while (!outgoingFlowObjectStack.isEmpty()) {
                outgoingFlowObjectStack.pop(FlowObject.class);
            }
        }
    }
    if (changed && !m_isPerformingActionCalledFromParent) {
        // updates port views
        notifyStateChangeListeners(new NodeStateEvent(this));
    }
    return changed;
}
Also used : VirtualSubNodeExchange(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeExchange) PortObjectSpec(org.knime.core.node.port.PortObjectSpec) FlowVariablePortObjectSpec(org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) VirtualSubNodeOutputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel) FlowVariablePortObject(org.knime.core.node.port.flowvariable.FlowVariablePortObject) InactiveBranchPortObject(org.knime.core.node.port.inactive.InactiveBranchPortObject) PortObject(org.knime.core.node.port.PortObject)

Example 3 with VirtualSubNodeOutputNodeModel

use of org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel in project knime-core by knime.

the class SubNodeContainer method checkInOutNodesAfterLoad.

/**
 * Fixes in- and output nodes after loading (in case they don't exist or have errors).
 */
private void checkInOutNodesAfterLoad(final SubNodeContainerPersistor subNodePersistor, final LoadResult loadResult) {
    /* Fix output node */
    NodeID virtualOutID = getVirtualOutNodeID();
    // non null in case not is not present of of wrong type
    String error = null;
    // settings of previous node if present or null
    NodeSettings outputSettings = null;
    // assigned with node insertion, used for node placement
    Pair<int[], int[]> minMaxCoordinates;
    if (m_wfm.containsNodeContainer(virtualOutID)) {
        NodeContainer virtualOutNC = m_wfm.getNodeContainer(virtualOutID);
        if (virtualOutNC instanceof NativeNodeContainer) {
            NodeModel virtualOutModel = ((NativeNodeContainer) virtualOutNC).getNodeModel();
            if (!(virtualOutModel instanceof VirtualSubNodeOutputNodeModel)) {
                // this is very likely a missing node (placeholder)
                error = String.format("Virtual output node is not of expected type (expected %s, actual %s)", VirtualSubNodeOutputNodeModel.class.getName(), virtualOutModel.getClass().getName());
                try {
                    NodeSettings temp = new NodeSettings("temp");
                    m_wfm.saveNodeSettings(virtualOutID, temp);
                    outputSettings = temp;
                } catch (InvalidSettingsException ise) {
                // silently ignore; this is minor given that the node is not there.
                }
            }
        } else {
            error = String.format("Virtual output node with ID %s is not a native node", virtualOutID);
        }
    } else {
        error = String.format("Virtual output node with ID %s does not exist", virtualOutID);
    }
    if (error != null) {
        minMaxCoordinates = getMinMaxCoordinates();
        m_virtualOutNodeIDSuffix = addVirtualOutNode(Output.getPortTypesNoFlowVariablePort(m_outputs), minMaxCoordinates).getIndex();
        error = error.concat(String.format(" - creating new instance (ID %s)", m_virtualOutNodeIDSuffix));
        loadResult.addError(error);
        if (outputSettings != null) {
            try {
                m_wfm.loadNodeSettings(getVirtualOutNodeID(), outputSettings);
            } catch (InvalidSettingsException e) {
            // again, ignore as the node was missing, which is much more critical
            }
        }
    }
    /* Fix input node */
    NodeID virtualInID = getVirtualInNodeID();
    // non null in case not is not present of of wrong type
    error = null;
    // settings of previous node if present or null
    NodeSettings inputSettings = null;
    if (m_wfm.containsNodeContainer(virtualInID)) {
        NodeContainer virtualInNC = m_wfm.getNodeContainer(virtualInID);
        if (virtualInNC instanceof NativeNodeContainer) {
            NodeModel virtualInModel = ((NativeNodeContainer) virtualInNC).getNodeModel();
            if (!(virtualInModel instanceof VirtualSubNodeInputNodeModel)) {
                // this is very likely a missing node (placeholder)
                error = String.format("Virtual input node is not of expected type (expected %s, actual %s)", VirtualSubNodeInputNodeModel.class.getName(), virtualInModel.getClass().getName());
                try {
                    NodeSettings temp = new NodeSettings("temp");
                    m_wfm.saveNodeSettings(virtualInID, temp);
                    inputSettings = temp;
                } catch (InvalidSettingsException ise) {
                // silently ignore; this is minor given that the node is not there.
                }
            }
        } else {
            error = String.format("Virtual input node with ID %s is not a native node", virtualInID);
        }
    } else {
        error = String.format("Virtual input node with ID %s does not exist", virtualInID);
    }
    if (error != null) {
        minMaxCoordinates = getMinMaxCoordinates();
        // skip flow var port
        PortType[] inportTypes = new PortType[getNrInPorts() - 1];
        for (int i = 1; i < getNrInPorts(); i++) {
            inportTypes[i - 1] = getInPort(i).getPortType();
        }
        m_virtualInNodeIDSuffix = addVirtualInNode(inportTypes, minMaxCoordinates).getIndex();
        error = error.concat(String.format(" - creating new instance (ID %s)", m_virtualInNodeIDSuffix));
        loadResult.addError(error);
        if (inputSettings != null) {
            try {
                m_wfm.loadNodeSettings(getVirtualInNodeID(), inputSettings);
            } catch (InvalidSettingsException e) {
            // again, ignore as the node was missing, which is much more critical
            }
        }
    }
}
Also used : NodeSettings(org.knime.core.node.NodeSettings) VirtualSubNodeOutputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel) VirtualSubNodeInputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeInputNodeModel) NodeModel(org.knime.core.node.NodeModel) InvalidSettingsException(org.knime.core.node.InvalidSettingsException) VirtualSubNodeInputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeInputNodeModel) VirtualSubNodeOutputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel) PortType(org.knime.core.node.port.PortType)

Example 4 with VirtualSubNodeOutputNodeModel

use of org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel in project knime-core by knime.

the class SubNodeContainer method getXMLDescription.

/* -------------------- NodeContainer info properties -------------- */
@SuppressWarnings("rawtypes")
/**
 * {@inheritDoc}
 */
@Override
public Element getXMLDescription() {
    VirtualSubNodeInputNodeModel inNode = getVirtualInNodeModel();
    VirtualSubNodeOutputNodeModel outNode = getVirtualOutNodeModel();
    String description = inNode.getSubNodeDescription();
    String sDescription;
    if (StringUtils.isEmpty(description)) {
        sDescription = "";
    } else {
        sDescription = StringUtils.split(description, ".\n")[0];
        sDescription = StringUtils.abbreviate(sDescription, 200);
    }
    String[] inPortNames = inNode.getPortNames();
    String[] inPortDescriptions = inNode.getPortDescriptions();
    String[] outPortNames = outNode.getPortNames();
    String[] outPortDescriptions = outNode.getPortDescriptions();
    Map<NodeID, DialogNode> nodes = m_wfm.findNodes(DialogNode.class, false);
    List<String> optionNames = new ArrayList<String>();
    List<String> optionDescriptions = new ArrayList<String>();
    for (DialogNode dialogNode : nodes.values()) {
        DialogNodeRepresentation representation = dialogNode.getDialogRepresentation();
        if (representation instanceof QuickFormRepresentation) {
            optionNames.add(((QuickFormRepresentation) representation).getLabel());
            optionDescriptions.add(((QuickFormRepresentation) representation).getDescription());
        }
    }
    try {
        // Document
        Document doc = NodeDescription.getDocumentBuilderFactory().newDocumentBuilder().getDOMImplementation().createDocument("http://knime.org/node2012", "knimeNode", null);
        // knimeNode
        Element knimeNode = doc.getDocumentElement();
        knimeNode.setAttribute("type", "Unknown");
        knimeNode.setAttribute("icon", "subnode.png");
        // name
        Element name = doc.createElement("name");
        knimeNode.appendChild(name);
        name.appendChild(doc.createTextNode(getName()));
        // shortDescription
        Element shortDescription = doc.createElement("shortDescription");
        knimeNode.appendChild(shortDescription);
        addText(shortDescription, sDescription, NO_DESCRIPTION_SET);
        // fullDescription
        Element fullDescription = doc.createElement("fullDescription");
        knimeNode.appendChild(fullDescription);
        // intro
        Element intro = doc.createElement("intro");
        fullDescription.appendChild(intro);
        addText(intro, description, NO_DESCRIPTION_SET + "\nIn order to set a description browse the input node " + "contained in the Wrapped Metanode and change its configuration.");
        // option
        for (int i = 0; i < optionNames.size(); i++) {
            Element option = doc.createElement("option");
            fullDescription.appendChild(option);
            option.setAttribute("name", optionNames.get(i));
            addText(option, optionDescriptions.get(i), "");
        }
        // ports
        Element ports = doc.createElement("ports");
        knimeNode.appendChild(ports);
        // inPort
        for (int i = 0; i < inPortNames.length; i++) {
            Element inPort = doc.createElement("inPort");
            ports.appendChild(inPort);
            inPort.setAttribute("index", "" + i);
            inPort.setAttribute("name", inPortNames[i]);
            String defaultText = NO_DESCRIPTION_SET;
            if (i == 0) {
                defaultText += "\nChange this label by browsing the input node contained in the Wrapped Metanode " + "and changing its configuration.";
            }
            addText(inPort, inPortDescriptions[i], defaultText);
        }
        // outPort
        for (int i = 0; i < outPortNames.length; i++) {
            Element outPort = doc.createElement("outPort");
            ports.appendChild(outPort);
            outPort.setAttribute("index", "" + i);
            outPort.setAttribute("name", outPortNames[i]);
            String defaultText = NO_DESCRIPTION_SET;
            if (i == 0) {
                defaultText += "\nChange this label by browsing the output node contained in the Wrapped Metanode " + "and changing its configuration.";
            }
            addText(outPort, outPortDescriptions[i], defaultText);
        }
        return new NodeDescription27Proxy(doc).getXMLDescription();
    } catch (ParserConfigurationException | DOMException | XmlException e) {
        LOGGER.warn("Could not generate Wrapped Metanode description", e);
    }
    return null;
}
Also used : Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) DialogNode(org.knime.core.node.dialog.DialogNode) MetaNodeDialogNode(org.knime.core.node.dialog.MetaNodeDialogNode) DialogNodeRepresentation(org.knime.core.node.dialog.DialogNodeRepresentation) Document(org.w3c.dom.Document) DOMException(org.w3c.dom.DOMException) QuickFormRepresentation(org.knime.core.quickform.QuickFormRepresentation) NodeDescription27Proxy(org.knime.core.node.NodeDescription27Proxy) VirtualSubNodeInputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeInputNodeModel) XmlException(org.apache.xmlbeans.XmlException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) VirtualSubNodeOutputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel)

Aggregations

VirtualSubNodeOutputNodeModel (org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeOutputNodeModel)4 InvalidSettingsException (org.knime.core.node.InvalidSettingsException)2 PortObject (org.knime.core.node.port.PortObject)2 FlowVariablePortObject (org.knime.core.node.port.flowvariable.FlowVariablePortObject)2 InactiveBranchPortObject (org.knime.core.node.port.inactive.InactiveBranchPortObject)2 VirtualSubNodeInputNodeModel (org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeInputNodeModel)2 ArrayList (java.util.ArrayList)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 XmlException (org.apache.xmlbeans.XmlException)1 NodeDescription27Proxy (org.knime.core.node.NodeDescription27Proxy)1 NodeModel (org.knime.core.node.NodeModel)1 NodeSettings (org.knime.core.node.NodeSettings)1 NodeSettingsRO (org.knime.core.node.NodeSettingsRO)1 DialogNode (org.knime.core.node.dialog.DialogNode)1 DialogNodeRepresentation (org.knime.core.node.dialog.DialogNodeRepresentation)1 MetaNodeDialogNode (org.knime.core.node.dialog.MetaNodeDialogNode)1 PortObjectSpec (org.knime.core.node.port.PortObjectSpec)1 PortType (org.knime.core.node.port.PortType)1 FlowVariablePortObjectSpec (org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec)1 InactiveBranchPortObjectSpec (org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec)1