Search in sources :

Example 1 with NodeAndBundleInformationPersistor

use of org.knime.core.node.NodeAndBundleInformationPersistor in project knime-core by knime.

the class FileWorkflowPersistor method loadNodeContainer.

/**
 * {@inheritDoc}
 */
@Override
public void loadNodeContainer(final Map<Integer, BufferedDataTable> tblRep, final ExecutionMonitor exec, final LoadResult loadResult) throws CanceledExecutionException, IOException {
    ReferencedFile workflowKNIMEFile = getWorkflowKNIMEFile();
    if (workflowKNIMEFile == null || m_workflowSett == null) {
        setDirtyAfterLoad();
        throw new IllegalStateException("The method preLoadNodeContainer has either not been called or failed");
    }
    /* read nodes */
    NodeSettingsRO nodes;
    try {
        nodes = loadSettingsForNodes(m_workflowSett);
    } catch (InvalidSettingsException e) {
        String error = "Can't load nodes in workflow, config not found: " + e.getMessage();
        getLogger().debug(error, e);
        loadResult.addError(error);
        setDirtyAfterLoad();
        setNeedsResetAfterLoad();
        // stop loading here
        return;
    }
    // ids of nodes that failed to load. Used to suppress superfluous errors when reading the connections
    Set<Integer> failingNodeIDSet = new HashSet<Integer>();
    // ids of nodes whose factory can't be loaded (e.g. node extension not installed)
    Map<Integer, NodeFactoryUnknownException> missingNodeIDMap = new HashMap<Integer, NodeFactoryUnknownException>();
    exec.setMessage("node information");
    final ReferencedFile workflowDirRef = workflowKNIMEFile.getParent();
    /* Load nodes */
    for (String nodeKey : nodes.keySet()) {
        exec.checkCanceled();
        NodeSettingsRO nodeSetting;
        try {
            nodeSetting = nodes.getNodeSettings(nodeKey);
        } catch (InvalidSettingsException e) {
            String error = "Unable to load settings for node with internal " + "id \"" + nodeKey + "\": " + e.getMessage();
            getLogger().debug(error, e);
            setDirtyAfterLoad();
            loadResult.addError(error);
            continue;
        }
        if (shouldSkipThisNode(nodeSetting)) {
            continue;
        }
        int nodeIDSuffix;
        try {
            nodeIDSuffix = loadNodeIDSuffix(nodeSetting);
        } catch (InvalidSettingsException e) {
            nodeIDSuffix = getRandomNodeID();
            String error = "Unable to load node ID (internal id \"" + nodeKey + "\"), trying random number " + nodeIDSuffix + "instead: " + e.getMessage();
            getLogger().debug(error, e);
            setDirtyAfterLoad();
            loadResult.addError(error);
        }
        NodeType nodeType;
        try {
            nodeType = loadNodeType(nodeSetting);
        } catch (InvalidSettingsException e) {
            String error = "Can't retrieve node type for contained node with id suffix " + nodeIDSuffix + ", attempting to read ordinary (native) node: " + e.getMessage();
            getLogger().debug(error, e);
            setDirtyAfterLoad();
            loadResult.addError(error);
            nodeType = NodeType.NativeNode;
        }
        NodeUIInformation nodeUIInfo = null;
        String uiInfoClassName;
        try {
            uiInfoClassName = loadUIInfoClassName(nodeSetting);
        } catch (InvalidSettingsException e) {
            String error = "Unable to load UI information class name " + "to node with ID suffix " + nodeIDSuffix + ", no UI information available: " + e.getMessage();
            getLogger().debug(error, e);
            setDirtyAfterLoad();
            loadResult.addError(error);
            uiInfoClassName = null;
        }
        if (uiInfoClassName != null) {
            try {
                // load node ui info
                nodeUIInfo = loadNodeUIInformation(nodeSetting);
            } catch (InvalidSettingsException e) {
                String error = "Unable to load UI information to " + "node with ID suffix " + nodeIDSuffix + ", no UI information available: " + e.getMessage();
                getLogger().debug(error, e);
                setDirtyAfterLoad();
                loadResult.addError(error);
            }
        }
        ReferencedFile nodeFile;
        try {
            nodeFile = loadNodeFile(nodeSetting, workflowDirRef);
        } catch (InvalidSettingsException e) {
            String error = "Unable to load settings for node " + "with ID suffix " + nodeIDSuffix + ": " + e.getMessage();
            getLogger().debug(error, e);
            setDirtyAfterLoad();
            loadResult.addError(error);
            failingNodeIDSet.add(nodeIDSuffix);
            continue;
        }
        FromFileNodeContainerPersistor persistor;
        switch(nodeType) {
            case MetaNode:
                persistor = createWorkflowPersistorLoad(nodeFile);
                break;
            case NativeNode:
                persistor = createNativeNodeContainerPersistorLoad(nodeFile);
                break;
            case SubNode:
                persistor = createSubNodeContainerPersistorLoad(nodeFile);
                break;
            default:
                throw new IllegalStateException("Unknown node type: " + nodeType);
        }
        try {
            LoadResult childResult = new LoadResult(nodeType.toString() + " with ID suffix " + nodeIDSuffix);
            persistor.preLoadNodeContainer(this, nodeSetting, childResult);
            loadResult.addChildError(childResult);
        } catch (Throwable e) {
            String error = "Unable to load node with ID suffix " + nodeIDSuffix + " into workflow, skipping it: " + e.getMessage();
            String loadErrorString;
            if (e instanceof NodeFactoryUnknownException) {
                loadErrorString = e.getMessage();
            } else {
                loadErrorString = error;
            }
            if (e instanceof InvalidSettingsException || e instanceof IOException || e instanceof NodeFactoryUnknownException) {
                getLogger().debug(error, e);
            } else {
                getLogger().error(error, e);
            }
            loadResult.addError(loadErrorString);
            if (e instanceof NodeFactoryUnknownException) {
                missingNodeIDMap.put(nodeIDSuffix, (NodeFactoryUnknownException) e);
            // don't set dirty
            } else {
                setDirtyAfterLoad();
                failingNodeIDSet.add(nodeIDSuffix);
                // node directory is the parent of the settings.xml
                m_obsoleteNodeDirectories.add(nodeFile.getParent());
                continue;
            }
        }
        NodeContainerMetaPersistor meta = persistor.getMetaPersistor();
        if (m_nodeContainerLoaderMap.containsKey(nodeIDSuffix)) {
            int randomID = getRandomNodeID();
            setDirtyAfterLoad();
            loadResult.addError("Duplicate id encountered in workflow: " + nodeIDSuffix + ", uniquifying to random id " + randomID + ", this possibly screws the connections");
            nodeIDSuffix = randomID;
        }
        meta.setNodeIDSuffix(nodeIDSuffix);
        meta.setUIInfo(nodeUIInfo);
        if (persistor.isDirtyAfterLoad()) {
            setDirtyAfterLoad();
        }
        m_nodeContainerLoaderMap.put(nodeIDSuffix, persistor);
    }
    /* read connections */
    exec.setMessage("connection information");
    NodeSettingsRO connections;
    try {
        connections = loadSettingsForConnections(m_workflowSett);
        if (connections == null) {
            connections = EMPTY_SETTINGS;
        }
    } catch (InvalidSettingsException e) {
        String error = "Can't load workflow connections, config not found: " + e.getMessage();
        getLogger().debug(error, e);
        setDirtyAfterLoad();
        loadResult.addError(error);
        connections = EMPTY_SETTINGS;
    }
    for (String connectionKey : connections.keySet()) {
        exec.checkCanceled();
        ConnectionContainerTemplate c;
        try {
            c = loadConnection(connections.getNodeSettings(connectionKey));
        } catch (InvalidSettingsException e) {
            String error = "Can't load connection with internal ID \"" + connectionKey + "\": " + e.getMessage();
            getLogger().debug(error, e);
            setDirtyAfterLoad();
            loadResult.addError(error);
            continue;
        }
        int sourceIDSuffix = c.getSourceSuffix();
        NodeContainerPersistor sourceNodePersistor = m_nodeContainerLoaderMap.get(sourceIDSuffix);
        if (sourceNodePersistor == null && sourceIDSuffix != -1) {
            setDirtyAfterLoad();
            if (!failingNodeIDSet.contains(sourceIDSuffix)) {
                loadResult.addError("Unable to load node connection " + c + ", source node does not exist");
            }
            continue;
        }
        fixSourcePortIfNecessary(sourceNodePersistor, c);
        int destIDSuffix = c.getDestSuffix();
        NodeContainerPersistor destNodePersistor = m_nodeContainerLoaderMap.get(destIDSuffix);
        if (destNodePersistor == null && destIDSuffix != -1) {
            setDirtyAfterLoad();
            if (!failingNodeIDSet.contains(destIDSuffix)) {
                loadResult.addError("Unable to load node connection " + c + ", destination node does not exist");
            }
            continue;
        }
        fixDestPortIfNecessary(destNodePersistor, c);
        if (!m_connectionSet.add(c)) {
            setDirtyAfterLoad();
            loadResult.addError("Duplicate connection information: " + c);
        }
    }
    for (Map.Entry<Integer, NodeFactoryUnknownException> missingNode : missingNodeIDMap.entrySet()) {
        exec.checkCanceled();
        int missingNodeSuffix = missingNode.getKey();
        NodeAndBundleInformationPersistor nodeInfo = missingNode.getValue().getNodeAndBundleInformation();
        loadResult.addMissingNode(nodeInfo);
        NodeSettingsRO additionalFactorySettings = missingNode.getValue().getAdditionalFactorySettings();
        ArrayList<PersistorWithPortIndex> upstreamNodes = new ArrayList<PersistorWithPortIndex>();
        ArrayList<List<PersistorWithPortIndex>> downstreamNodes = new ArrayList<List<PersistorWithPortIndex>>();
        for (ConnectionContainerTemplate t : m_connectionSet) {
            // check upstream nodes
            int sourceSuffix = t.getSourceSuffix();
            int destSuffix = t.getDestSuffix();
            int sourcePort = t.getSourcePort();
            int destPort = t.getDestPort();
            if (destSuffix == missingNodeSuffix) {
                FromFileNodeContainerPersistor persistor;
                if (sourceSuffix == -1) {
                    // connected to this metanode's input port bar
                    persistor = this;
                } else {
                    persistor = m_nodeContainerLoaderMap.get(sourceSuffix);
                }
                ensureArrayListIndexValid(upstreamNodes, destPort);
                upstreamNodes.set(destPort, new PersistorWithPortIndex(persistor, sourcePort));
            }
            // check downstream nodes
            if (sourceSuffix == missingNodeSuffix) {
                FromFileNodeContainerPersistor persistor;
                if (destSuffix == -1) {
                    // connect to this metanode's output port bar
                    persistor = this;
                } else {
                    persistor = m_nodeContainerLoaderMap.get(destSuffix);
                }
                ensureArrayListIndexValid(downstreamNodes, sourcePort);
                List<PersistorWithPortIndex> downstreamNodesAtPort = downstreamNodes.get(sourcePort);
                if (downstreamNodesAtPort == null) {
                    downstreamNodesAtPort = new ArrayList<PersistorWithPortIndex>();
                    downstreamNodes.set(sourcePort, downstreamNodesAtPort);
                }
                downstreamNodesAtPort.add(new PersistorWithPortIndex(persistor, destPort));
            }
        }
        FromFileNodeContainerPersistor failingNodePersistor = m_nodeContainerLoaderMap.get(missingNodeSuffix);
        failingNodePersistor.guessPortTypesFromConnectedNodes(nodeInfo, additionalFactorySettings, upstreamNodes, downstreamNodes);
    }
    exec.setProgress(1.0);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ReferencedFile(org.knime.core.internal.ReferencedFile) ArrayList(java.util.ArrayList) List(java.util.List) NodeAndBundleInformationPersistor(org.knime.core.node.NodeAndBundleInformationPersistor) HashSet(java.util.HashSet) IOException(java.io.IOException) InvalidSettingsException(org.knime.core.node.InvalidSettingsException) NodeSettingsRO(org.knime.core.node.NodeSettingsRO) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 2 with NodeAndBundleInformationPersistor

use of org.knime.core.node.NodeAndBundleInformationPersistor in project knime-core by knime.

the class FileNativeNodeContainerPersistor method saveNodeFactory.

private static void saveNodeFactory(final NodeSettingsWO settings, final NativeNodeContainer nnc) {
    final Node node = nnc.getNode();
    // node info to missing node is the info to the actual instance, not MissingNodeFactory
    NodeAndBundleInformationPersistor nodeInfo = nnc.getNodeAndBundleInformation();
    nodeInfo.save(settings);
    NodeSettingsWO subSets = settings.addNodeSettings("factory_settings");
    node.getFactory().saveAdditionalFactorySettings(subSets);
}
Also used : NodeSettingsWO(org.knime.core.node.NodeSettingsWO) Node(org.knime.core.node.Node) NodeAndBundleInformationPersistor(org.knime.core.node.NodeAndBundleInformationPersistor)

Example 3 with NodeAndBundleInformationPersistor

use of org.knime.core.node.NodeAndBundleInformationPersistor in project knime-workbench by knime.

the class Nodalizer method parseDeprecatedNodeList.

private static void parseDeprecatedNodeList(final Path factoryListFile, final File directory, final Map<String, ExtensionInfo> extensions, final List<String> bundles, final List<String> previouslyReadFactories) {
    if (factoryListFile == null) {
        return;
    }
    List<String> factories = null;
    try {
        factories = Files.readAllLines(factoryListFile);
    } catch (final Exception e) {
        LOGGER.error("Failed to read additional factories file: " + factoryListFile, e);
        return;
    }
    for (final String factory : factories) {
        if (previouslyReadFactories.stream().anyMatch(f -> f.equals(factory))) {
            LOGGER.info("Skipping previously read factory: " + factory);
            continue;
        }
        try {
            final String[] parts = factory.split("#");
            final NodeFactory<? extends NodeModel> fac = RepositoryManager.loadNodeFactory(parts[0]);
            // Dynamic nodes require additional information to load the factory
            if ((fac instanceof DynamicNodeFactory) && (parts.length > 1)) {
                final String s = parts[1];
                final NodeSettingsRO ns = NodeSettings.loadFromXML(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)));
                fac.loadAdditionalFactorySettings(ns);
            }
            final NodeAndBundleInformationPersistor b = NodeAndBundleInformationPersistor.create(fac);
            final String categoryPath = "/uncategorized";
            final List<String> path = Collections.singletonList("Uncategorized");
            // Some factories must be initialized or name/description throws NPE
            fac.init();
            if (b.getBundleName().isPresent() && b.getBundleVersion().isPresent() && b.getBundleSymbolicName().isPresent()) {
                // always pass true for isDeprecated, even though the factory may not say it is deprecated
                // pass the factory name in the file, not the name of the loaded class - due to factory class
                // mapping these may not match
                parseNodeAndPrint(fac, parts[0], path, categoryPath, fac.getNodeName(), b, true, directory, extensions, bundles);
            } else {
                if (!b.getBundleName().isPresent()) {
                    LOGGER.warn("Bundle name is missing! " + factory);
                }
                if (!b.getBundleVersion().isPresent()) {
                    LOGGER.warn("Bundle version is missing! " + factory);
                }
                if (!b.getBundleSymbolicName().isPresent()) {
                    LOGGER.warn("Bundle symbolic name is missing! " + factory);
                }
                throw new IllegalArgumentException("Bundle information is missing!");
            }
        } catch (final Throwable e) {
            LOGGER.warn("Failed to read factory from list: " + factory + ". ", e);
        }
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) NodeSettingsRO(org.knime.core.node.NodeSettingsRO) NodeAndBundleInformationPersistor(org.knime.core.node.NodeAndBundleInformationPersistor) FileNotFoundException(java.io.FileNotFoundException) NoSuchElementException(java.util.NoSuchElementException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) DynamicNodeFactory(org.knime.core.node.DynamicNodeFactory)

Example 4 with NodeAndBundleInformationPersistor

use of org.knime.core.node.NodeAndBundleInformationPersistor in project knime-core by knime.

the class Bug5207_BundleVersionInWorkflow method testBundleVersionOnLoad.

@Test
public void testBundleVersionOnLoad() throws Exception {
    checkState(m_tableCreator1, InternalNodeContainerState.EXECUTED);
    // table creator is executed and must have version as from execution time (which was faked but still...)
    NativeNodeContainer tableCreatorNC = (NativeNodeContainer) getManager().getNodeContainer(m_tableCreator1);
    NodeAndBundleInformationPersistor tableBundleInfo = tableCreatorNC.getNodeAndBundleInformation();
    Bundle tableBundle = FrameworkUtil.getBundle(tableCreatorNC.getNodeModel().getClass());
    assertEquals("1.1.1.20140523", tableBundleInfo.getBundleVersion().get().toString());
    final String tableBundleInfoVersion = tableBundleInfo.getBundleVersion().isPresent() ? tableBundleInfo.getBundleVersion().get().toString() : null;
    // must not be the same
    assertFalse(tableBundle.getVersion().toString().equals(tableBundleInfoVersion));
    assertEquals(tableBundle.getSymbolicName(), tableBundleInfo.getBundleSymbolicName().get());
    // col filter is not executed and has current bundle version as version information
    // (stored in workflow but ignored during load)
    NativeNodeContainer colFilterNC = (NativeNodeContainer) getManager().getNodeContainer(m_columnFilter2);
    NodeAndBundleInformationPersistor colFilterBundleInfo = colFilterNC.getNodeAndBundleInformation();
    Bundle colFilterBundle = FrameworkUtil.getBundle(colFilterNC.getNodeModel().getClass());
    assertEquals(colFilterBundle.getVersion().toString(), colFilterBundleInfo.getBundleVersion().get().toString());
    assertEquals(colFilterBundle.getSymbolicName(), colFilterBundleInfo.getBundleSymbolicName().get());
}
Also used : Bundle(org.osgi.framework.Bundle) NodeAndBundleInformationPersistor(org.knime.core.node.NodeAndBundleInformationPersistor) Test(org.junit.Test)

Example 5 with NodeAndBundleInformationPersistor

use of org.knime.core.node.NodeAndBundleInformationPersistor in project knime-core by knime.

the class Bug5207_BundleVersionInWorkflow method testBundleVersionAfterCopyPaste.

@Test
public void testBundleVersionAfterCopyPaste() throws Exception {
    WorkflowCopyContent.Builder copyContent = WorkflowCopyContent.builder();
    copyContent.setNodeIDs(m_tableCreator1);
    WorkflowCopyContent pasteContent = getManager().copyFromAndPasteHere(getManager(), copyContent.build());
    NodeID pasteID = pasteContent.getNodeIDs()[0];
    // bundle version number is reset after copy & paste
    NativeNodeContainer copiedTableNC = (NativeNodeContainer) getManager().getNodeContainer(pasteID);
    NodeAndBundleInformationPersistor copiedTableBundleInfo = copiedTableNC.getNodeAndBundleInformation();
    Bundle tableBundle = FrameworkUtil.getBundle(copiedTableNC.getNodeModel().getClass());
    assertEquals(tableBundle.getVersion().toString(), copiedTableBundleInfo.getBundleVersion().get().toString());
    assertEquals(tableBundle.getSymbolicName(), copiedTableBundleInfo.getBundleSymbolicName().get());
}
Also used : Bundle(org.osgi.framework.Bundle) NodeAndBundleInformationPersistor(org.knime.core.node.NodeAndBundleInformationPersistor) Test(org.junit.Test)

Aggregations

NodeAndBundleInformationPersistor (org.knime.core.node.NodeAndBundleInformationPersistor)7 Test (org.junit.Test)3 NodeSettingsRO (org.knime.core.node.NodeSettingsRO)3 Bundle (org.osgi.framework.Bundle)3 IOException (java.io.IOException)2 InvalidSettingsException (org.knime.core.node.InvalidSettingsException)2 Node (org.knime.core.node.Node)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 NoSuchElementException (java.util.NoSuchElementException)1 TreeMap (java.util.TreeMap)1 ReferencedFile (org.knime.core.internal.ReferencedFile)1 CanceledExecutionException (org.knime.core.node.CanceledExecutionException)1 DynamicNodeFactory (org.knime.core.node.DynamicNodeFactory)1