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);
}
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);
}
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);
}
}
}
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());
}
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());
}
Aggregations