Search in sources :

Example 1 with InactiveBranchPortObjectSpec

use of org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec in project knime-core by knime.

the class Node method getDialogPaneWithSettings.

/**
 * @param inSpecs The input specs, which will be forwarded to the dialog's
 *        {@link NodeDialogPane#loadSettingsFrom(NodeSettingsRO,
 *        PortObjectSpec[])}.
 * @param settings The current settings of this node. The settings object
 *        will also contain the settings of the outer SNC.
 * @param isWriteProtected Whether write protected, see
 *        {@link org.knime.core.node.workflow.WorkflowManager#isWriteProtected()}.
 * @return The dialog pane which holds all the settings' components. In
 *         addition this method loads the settings from the model into the
 *         dialog pane.
 * @throws NotConfigurableException if the dialog cannot be opened because
 *             of real invalid settings or if any preconditions are not
 *             fulfilled, e.g. no predecessor node, no nominal column in
 *             input table, etc.
 * @throws IllegalStateException If node has no dialog.
 * @see #hasDialog()
 * @since 2.6
 */
public NodeDialogPane getDialogPaneWithSettings(final PortObjectSpec[] inSpecs, final PortObject[] inData, final NodeSettingsRO settings, final boolean isWriteProtected) throws NotConfigurableException {
    NodeDialogPane dialogPane = getDialogPane();
    PortObjectSpec[] corrInSpecs = new PortObjectSpec[inSpecs.length - 1];
    PortObject[] corrInData = new PortObject[inData.length - 1];
    for (int i = 1; i < inSpecs.length; i++) {
        if (inSpecs[i] instanceof InactiveBranchPortObjectSpec) {
            if (!isInactiveBranchConsumer()) {
                throw new NotConfigurableException("Cannot configure nodes in inactive branches.");
            }
        }
        PortType t = getInputType(i);
        if (!t.acceptsPortObjectSpec(inSpecs[i]) && !(inSpecs[i] instanceof InactiveBranchPortObjectSpec)) {
            // table(!) connection)
            throw new NotConfigurableException("Invalid incoming port object spec \"" + inSpecs[i].getClass().getSimpleName() + "\", expected \"" + t.getPortObjectSpecClass().getSimpleName() + "\"");
        } else if (inSpecs[i] == null && BufferedDataTable.TYPE.equals(t) && !t.isOptional()) {
            corrInSpecs[i - 1] = new DataTableSpec();
        } else {
            corrInSpecs[i - 1] = inSpecs[i];
            corrInData[i - 1] = inData[i];
        }
    }
    // the sub node virtual input node shows in its dialog all flow variables that are available to the rest
    // of the subnode. It's the only case where the flow variables shown in the dialog are not the ones available
    // to the node model class ...
    final FlowObjectStack flowObjectStack = m_model instanceof VirtualSubNodeInputNodeModel ? ((VirtualSubNodeInputNodeModel) m_model).getSubNodeContainerFlowObjectStack() : getFlowObjectStack();
    dialogPane.internalLoadSettingsFrom(settings, corrInSpecs, corrInData, flowObjectStack, getCredentialsProvider(), isWriteProtected);
    if (m_model instanceof ValueControlledNode && dialogPane instanceof ValueControlledDialogPane) {
        NodeSettings currentValue = new NodeSettings("currentValue");
        try {
            ((ValueControlledNode) m_model).saveCurrentValue(currentValue);
            ((ValueControlledDialogPane) dialogPane).loadCurrentValue(currentValue);
        } catch (Exception ise) {
            final String msg = "Could not load current value into dialog: " + ise.getMessage();
            if (ise instanceof InvalidSettingsException) {
                LOGGER.warn(msg, ise);
            } else {
                LOGGER.coding(msg, ise);
            }
        }
    }
    return dialogPane;
}
Also used : DataTableSpec(org.knime.core.data.DataTableSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) FlowObjectStack(org.knime.core.node.workflow.FlowObjectStack) IOException(java.io.IOException) DataContainerException(org.knime.core.data.container.DataContainerException) VirtualSubNodeInputNodeModel(org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeInputNodeModel) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) PortObjectSpec(org.knime.core.node.port.PortObjectSpec) FlowVariablePortObjectSpec(org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec) ValueControlledDialogPane(org.knime.core.node.dialog.ValueControlledDialogPane) ValueControlledNode(org.knime.core.node.dialog.ValueControlledNode) PortObject(org.knime.core.node.port.PortObject) FileStorePortObject(org.knime.core.data.filestore.FileStorePortObject) FlowVariablePortObject(org.knime.core.node.port.flowvariable.FlowVariablePortObject) InactiveBranchPortObject(org.knime.core.node.port.inactive.InactiveBranchPortObject) PortType(org.knime.core.node.port.PortType)

Example 2 with InactiveBranchPortObjectSpec

use of org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec in project knime-core by knime.

the class Node method configure.

/**
 * Allows passing an object that may modify the specs created by the
 * {@link NodeModel}, for example in case the node is wrapped and the
 * output is modified.
 *
 * @param rawInSpecs table specs from the predecessors
 * @param configureHelper object called after node model calculated output
 *            specs
 * @return true if configure finished successfully.
 * @noreference This method is not intended to be referenced by clients.
 */
public boolean configure(final PortObjectSpec[] rawInSpecs, final NodeConfigureHelper configureHelper) {
    boolean success = false;
    LOGGER.assertLog(NodeContext.getContext() != null, "No node context available, please check call hierarchy and fix it");
    synchronized (m_configureLock) {
        // reset message object
        clearNodeMessageAndNotify();
        // copy input port object specs, ignoring the 0-variable port:
        PortObjectSpec[] inSpecs = Arrays.copyOfRange(rawInSpecs, 1, rawInSpecs.length);
        // clean output spec
        for (int p = 0; p < m_outputs.length; p++) {
            // update data table spec
            m_outputs[p].spec = null;
        }
        PortObjectSpec[] newOutSpec = new PortObjectSpec[getNrOutPorts() - 1];
        try {
            // check the inspecs against null
            for (int i = 0; i < inSpecs.length; i++) {
                if (inSpecs[i] == null) {
                    if (m_inputs[i + 1].getType().isOptional()) {
                    // ignore, unconnected optional input
                    } else {
                        return false;
                    }
                // TODO: did we really need a warning here??
                // throw new InvalidSettingsException(
                // "Node is not executable until all predecessors "
                // + "are configured and/or executed.");
                }
            }
            // check if the node is part of a skipped branch and return
            // appropriate specs without actually configuring the node.
            // Note that we must also check the incoming variable port!
            boolean isInactive = false;
            if (!isInactiveBranchConsumer()) {
                for (int i = 0; i < rawInSpecs.length; i++) {
                    if (rawInSpecs[i] instanceof InactiveBranchPortObjectSpec) {
                        isInactive = true;
                        break;
                    }
                }
            } else {
                FlowLoopContext flc = getFlowObjectStack().peek(FlowLoopContext.class);
                if (flc != null && flc.isInactiveScope()) {
                    isInactive = true;
                }
            }
            if (isInactive) {
                for (int j = 0; j < m_outputs.length; j++) {
                    m_outputs[j].spec = InactiveBranchPortObjectSpec.INSTANCE;
                }
                if (success) {
                    LOGGER.debug("Configure skipped. (" + getName() + " in inactive branch.)");
                }
                return true;
            }
            if (configureHelper != null) {
                configureHelper.preConfigure();
            }
            // call configure model to create output table specs
            // guaranteed to return non-null, correct-length array
            newOutSpec = invokeNodeModelConfigure(inSpecs);
            if (configureHelper != null) {
                newOutSpec = configureHelper.postConfigure(inSpecs, newOutSpec);
            }
            // find out if we are in the middle of executing a loop and this is a LoopEnd node
            boolean isIntermediateRunningLoop = false;
            if (isModelCompatibleTo(LoopEndNode.class)) {
                if ((getLoopContext() != null) && !getPauseLoopExecution()) {
                    FlowLoopContext flc = m_model.getFlowObjectStack().peek(FlowLoopContext.class);
                    if ((flc != null) && (flc.getIterationIndex() > 0)) {
                        // don't treat first iteration as "in the middle":
                        isIntermediateRunningLoop = true;
                    }
                }
            }
            if (!isIntermediateRunningLoop) {
                // update data table specs
                for (int p = 0; p < newOutSpec.length; p++) {
                    m_outputs[p + 1].spec = newOutSpec[p];
                }
            } else {
                // on the loop end node (avoids costly configure calls on remainder of workflow).
                for (int p = 0; p < newOutSpec.length; p++) {
                    if (newOutSpec[p] instanceof DataTableSpec) {
                        // remove domain before assigning spec to outputs
                        DataTableSpecCreator dtsCreator = new DataTableSpecCreator((DataTableSpec) newOutSpec[p]);
                        dtsCreator.dropAllDomains();
                        m_outputs[p + 1].spec = dtsCreator.createSpec();
                    } else {
                        // no domain to clean in PortObjectSpecs
                        m_outputs[p + 1].spec = newOutSpec[p];
                    }
                }
            }
            m_outputs[0].spec = FlowVariablePortObjectSpec.INSTANCE;
            success = true;
        } catch (InvalidSettingsException ise) {
            Throwable cause = ise.getCause();
            if (cause == null) {
                createWarningMessageAndNotify(ise.getMessage());
            } else {
                createWarningMessageAndNotify(ise.getMessage(), ise);
            }
        } catch (Throwable t) {
            String error = "Configure failed (" + t.getClass().getSimpleName() + "): " + t.getMessage();
            createErrorMessageAndNotify(error, t);
        }
    }
    if (success) {
        LOGGER.debug("Configure succeeded. (" + this.getName() + ")");
    }
    return success;
}
Also used : DataTableSpec(org.knime.core.data.DataTableSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) DataTableSpecCreator(org.knime.core.data.DataTableSpecCreator) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) PortObjectSpec(org.knime.core.node.port.PortObjectSpec) FlowVariablePortObjectSpec(org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec) FlowLoopContext(org.knime.core.node.workflow.FlowLoopContext)

Example 3 with InactiveBranchPortObjectSpec

use of org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec in project knime-core by knime.

the class FileNodePersistor method loadPort.

void loadPort(final Node node, final ReferencedFile portDir, final NodeSettingsRO settings, final ExecutionMonitor exec, final int portIdx, final Map<Integer, BufferedDataTable> loadTblRep, final WorkflowDataRepository dataRepository) throws IOException, InvalidSettingsException, CanceledExecutionException {
    final String specClass = settings.getString("port_spec_class");
    final String objectClass = loadPortObjectClassName(settings);
    PortType designatedType = node.getOutputType(portIdx);
    PortObjectSpec spec = null;
    PortObject object = null;
    // this cannot be simplified as BDT must be loaded as BDT even if
    // the port type is not BDT (but general PortObject)
    boolean isBDT = (BufferedDataTable.TYPE.getPortObjectClass().getName().equals(objectClass) && BufferedDataTable.TYPE.getPortObjectSpecClass().getName().equals(specClass)) || designatedType.equals(BufferedDataTable.TYPE);
    // an InactiveBranchPortObjectSpec can be put into any port!
    boolean isInactive = InactiveBranchPortObjectSpec.class.getName().equals(specClass);
    if (isBDT && !isInactive) {
        if (specClass != null && !specClass.equals(BufferedDataTable.TYPE.getPortObjectSpecClass().getName())) {
            throw new IOException("Actual spec class \"" + specClass + "\", expected \"" + BufferedDataTable.TYPE.getPortObjectSpecClass().getName() + "\"");
        }
        if (objectClass != null && !objectClass.equals(BufferedDataTable.TYPE.getPortObjectClass().getName())) {
            throw new IOException("Actual object class \"" + objectClass + "\", expected \"" + BufferedDataTable.TYPE.getPortObjectClass().getName() + "\"");
        }
        if (objectClass != null) {
            object = loadBufferedDataTable(portDir, exec, loadTblRep, dataRepository);
            ((BufferedDataTable) object).setOwnerRecursively(node);
            spec = ((BufferedDataTable) object).getDataTableSpec();
        } else if (specClass != null) {
            spec = BufferedDataTable.loadSpec(portDir);
        }
    } else {
        object = loadPortObject(portDir, settings, exec, dataRepository).orElse(null);
        spec = object != null ? object.getSpec() : null;
    }
    if (spec != null) {
        if (!designatedType.getPortObjectSpecClass().isInstance(spec) && !isInactive) {
            throw new IOException("Actual port spec type (\"" + spec.getClass().getSimpleName() + "\") does not match designated one (\"" + designatedType.getPortObjectSpecClass().getSimpleName() + "\")");
        }
    }
    String summary = null;
    if (object != null) {
        if (!designatedType.getPortObjectClass().isInstance(object) && !isInactive) {
            throw new IOException("Actual port object type (\"" + object.getClass().getSimpleName() + "\") does not match designated one (\"" + designatedType.getPortObjectClass().getSimpleName() + "\")");
        }
        summary = settings.getString("port_object_summary", null);
        if (summary == null) {
            summary = object.getSummary();
        }
    }
    setPortObjectSpec(portIdx, spec);
    setPortObject(portIdx, object);
    setPortObjectSummary(portIdx, summary);
}
Also used : InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) PortObjectSpec(org.knime.core.node.port.PortObjectSpec) FlowVariablePortObjectSpec(org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec) IOException(java.io.IOException) PortObject(org.knime.core.node.port.PortObject) FileStorePortObject(org.knime.core.data.filestore.FileStorePortObject) FlowVariablePortObject(org.knime.core.node.port.flowvariable.FlowVariablePortObject) PMMLPortObject(org.knime.core.node.port.pmml.PMMLPortObject) InactiveBranchPortObject(org.knime.core.node.port.inactive.InactiveBranchPortObject) PortType(org.knime.core.node.port.PortType)

Example 4 with InactiveBranchPortObjectSpec

use of org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec in project knime-core by knime.

the class NodeModel method configureModel.

/**
 * This function is called when something changes that could affect the
 * output <code>DataTableSpec</code> elements. E.g. after a reset,
 * execute, (dis-)connect, and object creation (model instantiation).
 * <p>
 * The function calls <code>#configure()</code> to receive the updated
 * output DataTableSpecs, if the model is not executed yet. After execution
 * the DataTableSpecs are simply taken from the output DataTables.
 *
 * @param inSpecs An array of input <code>DataTableSpec</code> elements,
 *            either the array or each of its elements can be
 *            <code>null</code>.
 * @return An array where each element indicates if the outport has changed.
 * @throws InvalidSettingsException if the current settings don't go along
 *             with the table specs
 */
final PortObjectSpec[] configureModel(final PortObjectSpec[] inSpecs) throws InvalidSettingsException {
    assert inSpecs.length == getNrInPorts();
    setWarningMessage(null);
    PortObjectSpec[] copyInSpecs = new PortObjectSpec[getNrInPorts()];
    PortObjectSpec[] newOutSpecs;
    System.arraycopy(inSpecs, 0, copyInSpecs, 0, inSpecs.length);
    // Rather empty ones than null
    for (int i = 0; i < copyInSpecs.length; i++) {
        if (copyInSpecs[i] == null && BufferedDataTable.TYPE.equals(m_inPortTypes[i]) && !m_inPortTypes[i].isOptional()) {
            // only mimic empty table for real table connections
            copyInSpecs[i] = new DataTableSpec();
        }
        // only weak port compatibility check during connect
        // (model reader can be connected to any model port)
        // complain if actual types are incompatible.
        Class<? extends PortObjectSpec> expected = m_inPortTypes[i].getPortObjectSpecClass();
        if (// i.e. skip only "optional and not connected"
        copyInSpecs[i] != null && !expected.isAssignableFrom(copyInSpecs[i].getClass()) && !(copyInSpecs[i] instanceof InactiveBranchPortObjectSpec)) {
            StringBuilder b = new StringBuilder("Incompatible port spec");
            if (copyInSpecs.length > 1) {
                b.append(" at port ").append(i);
            }
            b.append(", expected: ").append(expected.getSimpleName());
            b.append(", actual: ").append(copyInSpecs[i].getClass().getSimpleName());
            throw new InvalidSettingsException(b.toString());
        }
    }
    // CALL CONFIGURE
    newOutSpecs = configure(copyInSpecs);
    if (newOutSpecs == null) {
        newOutSpecs = new PortObjectSpec[getNrOutPorts()];
    }
    // check output object spec length
    if (newOutSpecs.length != getNrOutPorts()) {
        m_logger.error("Output spec-array length invalid: " + newOutSpecs.length + " <> " + getNrOutPorts());
        newOutSpecs = new PortObjectSpec[getNrOutPorts()];
    }
    return newOutSpecs;
}
Also used : DataTableSpec(org.knime.core.data.DataTableSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) PortObjectSpec(org.knime.core.node.port.PortObjectSpec)

Example 5 with InactiveBranchPortObjectSpec

use of org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec in project knime-core by knime.

the class FileNodePersistor method loadPort.

void loadPort(final Node node, final ReferencedFile portDir, final NodeSettingsRO settings, final ExecutionMonitor exec, final int portIdx, final Map<Integer, BufferedDataTable> loadTblRep, final HashMap<Integer, ContainerTable> tblRep, final FileStoreHandlerRepository fileStoreHandlerRepository) throws IOException, InvalidSettingsException, CanceledExecutionException {
    final String specClass = settings.getString("port_spec_class");
    final String objectClass = loadPortObjectClassName(settings);
    PortType designatedType = node.getOutputType(portIdx);
    PortObjectSpec spec = null;
    PortObject object = null;
    // this cannot be simplified as BDT must be loaded as BDT even if
    // the port type is not BDT (but general PortObject)
    boolean isBDT = (BufferedDataTable.TYPE.getPortObjectClass().getName().equals(objectClass) && BufferedDataTable.TYPE.getPortObjectSpecClass().getName().equals(specClass)) || designatedType.equals(BufferedDataTable.TYPE);
    // an InactiveBranchPortObjectSpec can be put into any port!
    boolean isInactive = InactiveBranchPortObjectSpec.class.getName().equals(specClass);
    if (isBDT && !isInactive) {
        if (specClass != null && !specClass.equals(BufferedDataTable.TYPE.getPortObjectSpecClass().getName())) {
            throw new IOException("Actual spec class \"" + specClass + "\", expected \"" + BufferedDataTable.TYPE.getPortObjectSpecClass().getName() + "\"");
        }
        if (objectClass != null && !objectClass.equals(BufferedDataTable.TYPE.getPortObjectClass().getName())) {
            throw new IOException("Actual object class \"" + objectClass + "\", expected \"" + BufferedDataTable.TYPE.getPortObjectClass().getName() + "\"");
        }
        if (objectClass != null) {
            object = loadBufferedDataTable(portDir, exec, loadTblRep, tblRep, fileStoreHandlerRepository);
            ((BufferedDataTable) object).setOwnerRecursively(node);
            spec = ((BufferedDataTable) object).getDataTableSpec();
        } else if (specClass != null) {
            spec = BufferedDataTable.loadSpec(portDir);
        }
    } else {
        object = loadPortObject(portDir, settings, exec, fileStoreHandlerRepository).orElse(null);
        spec = object != null ? object.getSpec() : null;
    }
    if (spec != null) {
        if (!designatedType.getPortObjectSpecClass().isInstance(spec) && !isInactive) {
            throw new IOException("Actual port spec type (\"" + spec.getClass().getSimpleName() + "\") does not match designated one (\"" + designatedType.getPortObjectSpecClass().getSimpleName() + "\")");
        }
    }
    String summary = null;
    if (object != null) {
        if (!designatedType.getPortObjectClass().isInstance(object) && !isInactive) {
            throw new IOException("Actual port object type (\"" + object.getClass().getSimpleName() + "\") does not match designated one (\"" + designatedType.getPortObjectClass().getSimpleName() + "\")");
        }
        summary = settings.getString("port_object_summary", null);
        if (summary == null) {
            summary = object.getSummary();
        }
    }
    setPortObjectSpec(portIdx, spec);
    setPortObject(portIdx, object);
    setPortObjectSummary(portIdx, summary);
}
Also used : InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) InactiveBranchPortObjectSpec(org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec) PortObjectSpec(org.knime.core.node.port.PortObjectSpec) FlowVariablePortObjectSpec(org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec) IOException(java.io.IOException) PortObject(org.knime.core.node.port.PortObject) FileStorePortObject(org.knime.core.data.filestore.FileStorePortObject) FlowVariablePortObject(org.knime.core.node.port.flowvariable.FlowVariablePortObject) PMMLPortObject(org.knime.core.node.port.pmml.PMMLPortObject) InactiveBranchPortObject(org.knime.core.node.port.inactive.InactiveBranchPortObject) PortType(org.knime.core.node.port.PortType)

Aggregations

PortObjectSpec (org.knime.core.node.port.PortObjectSpec)9 InactiveBranchPortObjectSpec (org.knime.core.node.port.inactive.InactiveBranchPortObjectSpec)9 FlowVariablePortObjectSpec (org.knime.core.node.port.flowvariable.FlowVariablePortObjectSpec)6 DataTableSpec (org.knime.core.data.DataTableSpec)5 FileStorePortObject (org.knime.core.data.filestore.FileStorePortObject)5 PortObject (org.knime.core.node.port.PortObject)5 FlowVariablePortObject (org.knime.core.node.port.flowvariable.FlowVariablePortObject)5 InactiveBranchPortObject (org.knime.core.node.port.inactive.InactiveBranchPortObject)5 IOException (java.io.IOException)4 PortType (org.knime.core.node.port.PortType)4 PMMLPortObject (org.knime.core.node.port.pmml.PMMLPortObject)3 DataContainerException (org.knime.core.data.container.DataContainerException)2 InvalidSettingsException (org.knime.core.node.InvalidSettingsException)2 ValueControlledDialogPane (org.knime.core.node.dialog.ValueControlledDialogPane)2 ValueControlledNode (org.knime.core.node.dialog.ValueControlledNode)2 FlowObjectStack (org.knime.core.node.workflow.FlowObjectStack)2 VirtualSubNodeInputNodeModel (org.knime.core.node.workflow.virtual.subnode.VirtualSubNodeInputNodeModel)2 DataTableSpecCreator (org.knime.core.data.DataTableSpecCreator)1 InactiveBranchConsumer (org.knime.core.node.port.inactive.InactiveBranchConsumer)1 FlowLoopContext (org.knime.core.node.workflow.FlowLoopContext)1