use of org.knime.core.util.workflowalizer.NodeAndBundleInformation in project knime-workbench by knime.
the class Nodalizer method parseNodesInRoot.
// -- Parse nodes --
private void parseNodesInRoot(final IRepositoryObject object, final List<String> path, final File directory, final Map<String, ExtensionInfo> extensions, final List<String> bundles, final List<String> readFactories) {
if (object instanceof NodeTemplate) {
try {
final NodeTemplate template = (NodeTemplate) object;
final NodeFactory<? extends NodeModel> fac = template.createFactoryInstance();
final NodeAndBundleInformation nodeAndBundleInfo = NodeAndBundleInformationPersistor.create(fac);
parseNodeAndPrint(fac, fac.getClass().getName(), path, template.getCategoryPath(), template.getName(), nodeAndBundleInfo, template.isDeprecated(), directory, extensions, bundles);
readFactories.add(fac.getClass().toString());
} catch (final Throwable e) {
LOGGER.error("Failed to read node: " + object.getName() + ".", e);
}
} else if (object instanceof Root) {
for (final IRepositoryObject child : ((Root) object).getChildren()) {
parseNodesInRoot(child, new ArrayList<>(), directory, extensions, bundles, readFactories);
}
} else if (object instanceof Category) {
for (final IRepositoryObject child : ((Category) object).getChildren()) {
final Category c = (Category) object;
final List<String> p = new ArrayList<>(path);
p.add(c.getName());
parseNodesInRoot(child, p, directory, extensions, bundles, readFactories);
}
} else {
return;
}
}
use of org.knime.core.util.workflowalizer.NodeAndBundleInformation in project knime-workbench by knime.
the class Nodalizer method parseNodeAndPrint.
private static void parseNodeAndPrint(final NodeFactory<?> fac, final String factoryString, final List<String> path, final String categoryPath, final String name, final NodeAndBundleInformation nodeAndBundleInfo, final boolean isDeprecated, final File directory, final Map<String, ExtensionInfo> extensions, final List<String> bundles) throws Exception {
// Read update site info
// Do this early to prevent instantiating unnecessary nodes.
String extensionId = null;
SiteInfo updateSite = null;
String owner = null;
NodeAndBundleInformation nabi = nodeAndBundleInfo;
if (extensions != null && bundles != null) {
// TODO: Check symbolic name and version once we support reading multiple extension versions
String cleanedSymbolicName = NodalizerUtil.cleanSymbolicName(nabi.getFeatureSymbolicName().orElse(null));
if (extensions.containsKey(cleanedSymbolicName)) {
// HACK: See https://knime-com.atlassian.net/browse/AP-13547 for details
ExtensionInfo e;
if (cleanedSymbolicName.equals("org.knime.features.testing.core") && extensions.containsKey("org.knime.features.testing.application")) {
e = extensions.get("org.knime.features.testing.application");
} else {
e = extensions.get(cleanedSymbolicName);
}
e.setHasNodes(true);
updateSite = e.getUpdateSite();
extensionId = e.getId();
owner = e.getOwner();
nabi = new NodeAndBundleInformation(nodeAndBundleInfo.getFactoryClass(), nodeAndBundleInfo.getBundleSymbolicName(), nodeAndBundleInfo.getBundleName(), nodeAndBundleInfo.getBundleVendor(), nodeAndBundleInfo.getNodeName(), nodeAndBundleInfo.getBundleVersion(), Optional.of(e.getSymbolicName()), Optional.ofNullable(e.getName()), Optional.ofNullable(e.getVendor()), Optional.ofNullable(e.getVersion()));
} else if (!nabi.getFeatureSymbolicName().isPresent() && bundles.contains(nabi.getBundleSymbolicName().orElse(null))) {
LOGGER.warn(fac.getClass() + " does not contain extension information, skipping ...");
return;
} else {
// to the update site being read.
return;
}
}
@SuppressWarnings("unchecked") final org.knime.core.node.Node kcn = new org.knime.core.node.Node((NodeFactory<NodeModel>) fac);
final NodeInfo nInfo = new NodeInfo();
nInfo.setAdditionalSiteInformation(updateSite);
nInfo.setBundleInformation(nabi, extensionId);
nInfo.setOwner(owner);
// Read from node
final NodeSettings settings = new NodeSettings("");
fac.saveAdditionalFactorySettings(settings);
final String factoryName = factoryString + ConfigUtils.contentBasedHashString(settings);
nInfo.setFactoryName(factoryName);
nInfo.setTitle(name.trim());
nInfo.setNodeType(kcn.getType().toString());
nInfo.setPath(path);
nInfo.setDeprecated(isDeprecated);
nInfo.setStreamable(NodeUtil.isStreamable(kcn));
nInfo.setTags(new ArrayList<>());
nInfo.getTags().addAll(nInfo.getPath());
if (NodeUtil.isStreamable(kcn)) {
nInfo.getTags().add("Streamable");
}
// Read icon
URL imageURL = fac.getIcon();
if (imageURL == null) {
imageURL = NodeFactory.class.getResource("defaulticon.png");
}
final String mimeType = URLConnection.guessContentTypeFromName(imageURL.getFile());
byte[] imageBytes = null;
try (InputStream s = imageURL.openStream()) {
imageBytes = IOUtils.toByteArray(s);
}
final String iconBase64 = "data:" + mimeType + ";base64," + Base64.getEncoder().encodeToString(imageBytes);
nInfo.setIcon(iconBase64);
// Parse HTML, and read fields
final Element nodeXML = fac.getXMLDescription();
Document nodeHTML = null;
if (nodeXML == null) {
LOGGER.warn("Node factory XML not found for " + fac.getClass() + ". Skipping ...");
return;
}
final String s = NodeFactoryHTMLCreator.instance.readFullDescription(nodeXML);
nodeHTML = Jsoup.parse(s);
String descriptHTML = "";
org.jsoup.nodes.Node n = nodeHTML.getElementsByTag("p").first();
while (n != null) {
if (n instanceof org.jsoup.nodes.Element) {
final org.jsoup.nodes.Element e = (org.jsoup.nodes.Element) n;
if (e.tagName().equalsIgnoreCase("h2")) {
n = null;
} else if (e.hasText()) {
descriptHTML += e.outerHtml();
n = n.nextSibling();
} else if (e.tagName().equalsIgnoreCase("br")) {
descriptHTML += e.outerHtml();
n = n.nextSibling();
} else {
n = n.nextSibling();
}
} else if (n instanceof TextNode) {
final TextNode tn = (TextNode) n;
descriptHTML += tn.getWholeText();
n = n.nextSibling();
} else {
n = n.nextSibling();
}
}
nInfo.setDescription(descriptHTML);
parseHTML(nodeHTML, nInfo, kcn.getInteractiveViewName());
// Read PortInfo
final PortInfo[] inports = new PortInfo[kcn.getNrInPorts() - 1];
final PortInfo[] outports = new PortInfo[kcn.getNrOutPorts() - 1];
for (int i = 1; i < kcn.getNrInPorts(); i++) {
String portDescriptHTML = fac.getInportDescription(i - 1);
if (!nodeHTML.getElementsMatchingOwnText("Input Ports").isEmpty()) {
final org.jsoup.nodes.Element sibling = nodeHTML.getElementsMatchingOwnText("Input Ports").first().nextElementSibling();
if (sibling != null) {
final Elements matches = sibling.getElementsByAttributeValue("class", "dt");
for (final org.jsoup.nodes.Element match : matches) {
if (match.ownText().equals("" + (i - 1))) {
portDescriptHTML = NodalizerUtil.cleanHTML(match.nextElementSibling());
break;
}
}
}
}
final PortInfo port = new PortInfo(kcn.getInportName(i), portDescriptHTML, kcn.getInputType(i).isOptional(), kcn.getInputType(i).getName(), NodalizerUtil.getColorAsHex(kcn.getInputType(i).getColor()), kcn.getInputType(i).getPortObjectClass().getCanonicalName());
inports[i - 1] = port;
}
for (int i = 1; i < kcn.getNrOutPorts(); i++) {
String portDescriptHTML = fac.getOutportDescription(i - 1);
if (!nodeHTML.getElementsMatchingOwnText("Output Ports").isEmpty()) {
final org.jsoup.nodes.Element sibling = nodeHTML.getElementsMatchingOwnText("Output Ports").first().nextElementSibling();
if (sibling != null) {
final Elements matches = sibling.getElementsByAttributeValue("class", "dt");
for (final org.jsoup.nodes.Element match : matches) {
if (match.ownText().equals("" + (i - 1))) {
portDescriptHTML = NodalizerUtil.cleanHTML(match.nextElementSibling());
break;
}
}
}
}
final PortInfo port = new PortInfo(kcn.getOutportName(i), portDescriptHTML, kcn.getOutputType(i).isOptional(), kcn.getOutputType(i).getName(), NodalizerUtil.getColorAsHex(kcn.getOutputType(i).getColor()), kcn.getOutputType(i).getPortObjectClass().getCanonicalName());
outports[i - 1] = port;
}
nInfo.setInPorts(inports);
nInfo.setOutPorts(outports);
if (kcn.getCopyOfCreationConfig().isPresent() && kcn.getCopyOfCreationConfig().get().getPortConfig().isPresent() && fac instanceof ConfigurableNodeFactory) {
final ModifiablePortsConfiguration portConfigs = kcn.getCopyOfCreationConfig().get().getPortConfig().get();
final List<DynamicPortGroup> dynInports = parseDynamicPorts(nodeXML, "dynInPort", nodeHTML, "Dynamic Input Ports", portConfigs, fac.getClass().getCanonicalName());
final List<DynamicPortGroup> dynOutports = parseDynamicPorts(nodeXML, "dynOutPort", nodeHTML, "Dynamic Output Ports", portConfigs, fac.getClass().getCanonicalName());
nInfo.setDynInPorts(dynInports);
nInfo.setDynOutPorts(dynOutports);
}
// Write to file
NodalizerUtil.writeFile(directory, categoryPath + "/" + name + "_" + nInfo.getId().substring(1), nInfo);
}
Aggregations