This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 2c9ccb5ae78e CAMEL-23912: Extract DependencyLoader and fix F3 tab
refresh
2c9ccb5ae78e is described below
commit 2c9ccb5ae78e09b0cfb39b856c0ac0b4c5f17b97
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Jul 6 11:44:16 2026 +0200
CAMEL-23912: Extract DependencyLoader and fix F3 tab refresh
Extract shared DependencyLoader utility from MavenDependenciesTab so
CveAuditTab scans declared Maven dependencies instead of the full JVM
classpath. Fix F3 integration switch not refreshing Classpath and Maven
Dependencies tabs by adding reload in onIntegrationChanged(), and make
resetIntegrationTabState() loop over moreTabs so future tabs are
covered automatically.
Co-Authored-By: Claude <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../dsl/jbang/core/commands/tui/ClasspathTab.java | 5 +
.../dsl/jbang/core/commands/tui/CveAuditTab.java | 78 ++---
.../jbang/core/commands/tui/DependencyLoader.java | 375 ++++++++++++++++++++
.../core/commands/tui/MavenDependenciesTab.java | 376 ++-------------------
.../dsl/jbang/core/commands/tui/OsvClient.java | 16 +-
.../dsl/jbang/core/commands/tui/TabRegistry.java | 20 +-
6 files changed, 441 insertions(+), 429 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
index d83afd0ccea6..265bf3ff2f3e 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
@@ -96,6 +96,11 @@ class ClasspathTab extends AbstractTab {
lastPid = null;
errorMessage = null;
dataLoaded = false;
+ loading.set(false);
+ if (ctx.selectedPid != null) {
+ lastPid = ctx.selectedPid;
+ loadClasspath();
+ }
}
@Override
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
index 2aba0c006de7..278b6f3fe355 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -46,7 +45,6 @@ import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -61,13 +59,12 @@ class CveAuditTab extends AbstractTableTab {
private int detailScroll;
- private List<ClasspathTab.JarEntry> jarEntries = Collections.emptyList();
+ private List<DependencyLoader.DepEntry> depEntries =
Collections.emptyList();
private List<VulnGroup> allGroups = Collections.emptyList();
private String lastPid;
private String errorMessage;
private boolean dataLoaded;
private int scannedCount;
- private int totalCount;
CveAuditTab(MonitorContext ctx) {
super(ctx, "severity", "id", "artifact");
@@ -94,7 +91,7 @@ class CveAuditTab extends AbstractTableTab {
@Override
public void onIntegrationChanged() {
allGroups = Collections.emptyList();
- jarEntries = Collections.emptyList();
+ depEntries = Collections.emptyList();
lastPid = null;
errorMessage = null;
dataLoaded = false;
@@ -157,9 +154,7 @@ class CveAuditTab extends AbstractTableTab {
@Override
protected void renderContent(Frame frame, Rect area, IntegrationInfo info)
{
if (loading.get() && allGroups.isEmpty()) {
- String msg = totalCount > 0
- ? String.format(" Scanning %d dependencies...",
totalCount)
- : " Loading classpath...";
+ String msg = " Scanning dependencies...";
frame.renderWidget(
Paragraph.builder()
.text(Text.from(Line.from(Span.styled(msg,
Style.EMPTY.dim()))))
@@ -361,7 +356,7 @@ class CveAuditTab extends AbstractTableTab {
if (loading.get()) {
return;
}
- osvClient.clearCache(jarEntries);
+ osvClient.clearCache(depEntries);
allGroups = Collections.emptyList();
dataLoaded = false;
errorMessage = null;
@@ -369,64 +364,38 @@ class CveAuditTab extends AbstractTableTab {
}
private void loadAndScan() {
- if (ctx.selectedPid == null || ctx.runner == null) {
+ IntegrationInfo info = ctx.findSelectedIntegration();
+ if (info == null || ctx.runner == null) {
return;
}
if (!loading.compareAndSet(false, true)) {
return;
}
- String pid = ctx.selectedPid;
ctx.runner.scheduler().execute(() -> {
try {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
- JsonObject action = new JsonObject();
- action.put("action", "jvm");
-
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
-
- JsonObject response = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
-
- if (response == null) {
- applyResult(Collections.emptyList(),
Collections.emptyList(), "No response from integration");
+ DependencyLoader.LoadResult loadResult =
DependencyLoader.loadDependencies(info);
+ if (loadResult.error() != null &&
loadResult.entries().isEmpty()) {
+ applyResult(Collections.emptyList(),
Collections.emptyList(), loadResult.error());
return;
}
- List<String> paths = new ArrayList<>();
- Object cp = response.get("classpath");
- if (cp instanceof JsonArray arr) {
- for (Object item : arr) {
- paths.add(String.valueOf(item));
- }
- }
+ List<DependencyLoader.DepEntry> directDeps =
loadResult.entries();
+ List<DependencyLoader.DepEntry> transitiveDeps =
DependencyLoader.resolveTransitives(directDeps);
- if (paths.isEmpty()) {
- applyResult(Collections.emptyList(),
Collections.emptyList(), "No classpath information available");
- return;
+ List<DependencyLoader.DepEntry> allDeps = new
ArrayList<>(directDeps);
+ for (DependencyLoader.DepEntry t : transitiveDeps) {
+ allDeps.add(t);
}
- List<ClasspathTab.JarEntry> jars = new ArrayList<>();
- for (String path : paths) {
- ClasspathTab.JarEntry entry =
ClasspathTab.parseJarEntry(path);
- if (entry.groupId() != null) {
- jars.add(entry);
- }
- }
-
- updateProgress(jars);
-
- Map<String, List<OsvClient.Vulnerability>> vulnMap =
osvClient.queryBatch(jars);
+ Map<String, List<OsvClient.Vulnerability>> vulnMap =
osvClient.queryBatch(allDeps);
List<VulnGroup> groups = buildVulnGroups(vulnMap);
groups.sort(Comparator
.comparingInt((VulnGroup g) ->
severityIndex(g.severity))
.thenComparing(g -> g.canonicalId));
- applyResult(jars, groups, null);
+ applyResult(allDeps, groups, null);
} catch (Exception e) {
applyResult(Collections.emptyList(), Collections.emptyList(),
"Error: " + e.getMessage());
} finally {
@@ -435,25 +404,16 @@ class CveAuditTab extends AbstractTableTab {
});
}
- private void updateProgress(List<ClasspathTab.JarEntry> jars) {
- if (ctx.runner == null) {
- return;
- }
- ctx.runner.runOnRenderThread(() -> {
- totalCount = jars.size();
- });
- }
-
- private void applyResult(List<ClasspathTab.JarEntry> jars, List<VulnGroup>
groups, String error) {
+ private void applyResult(List<DependencyLoader.DepEntry> deps,
List<VulnGroup> groups, String error) {
if (ctx.runner == null) {
return;
}
ctx.runner.runOnRenderThread(() -> {
- jarEntries = jars;
+ depEntries = deps;
allGroups = groups;
errorMessage = error;
dataLoaded = true;
- scannedCount = jars.size();
+ scannedCount = deps.size();
if (!allGroups.isEmpty()) {
tableState.select(0);
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DependencyLoader.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DependencyLoader.java
new file mode 100644
index 000000000000..0ec787f902ec
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DependencyLoader.java
@@ -0,0 +1,375 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.tui;
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.camel.dsl.jbang.core.common.XmlHelper;
+import org.apache.camel.tooling.maven.MavenArtifact;
+import org.apache.camel.tooling.maven.MavenDownloaderImpl;
+import org.apache.camel.tooling.maven.MavenGav;
+
+/**
+ * Shared dependency discovery for the TUI. Reads declared Maven dependencies
from pom.xml (for exported Spring Boot /
+ * Quarkus apps) or from .camel-jbang/camel-jbang-run.properties (for JBang
mode). Filters out internal infrastructure
+ * JARs so only the user's actual dependencies are returned.
+ * <p/>
+ * Used by both {@link MavenDependenciesTab} and {@link CveAuditTab} to avoid
scanning the full JVM classpath which
+ * would include internal bootstrap JARs like camel-kamelet-main, jansi, and
log4j.
+ */
+final class DependencyLoader {
+
+ private DependencyLoader() {
+ }
+
+ record DepEntry(String groupId, String artifactId, String version, boolean
transitive, String parent) {
+
+ DepEntry(String groupId, String artifactId, String version) {
+ this(groupId, artifactId, version, false, null);
+ }
+
+ String display() {
+ if (version != null) {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+ return groupId + ":" + artifactId;
+ }
+
+ boolean isCamel() {
+ return groupId != null && groupId.startsWith("org.apache.camel");
+ }
+ }
+
+ record LoadResult(List<DepEntry> entries, String source, String error) {
+ }
+
+ static LoadResult loadDependencies(IntegrationInfo info) {
+ List<Path> candidates = new ArrayList<>();
+ Path sourceDir = FilesBrowser.resolveSourceDirectory(info);
+ if (sourceDir != null) {
+ candidates.add(sourceDir);
+ }
+ if (info.directory != null && !info.directory.isEmpty()) {
+ Path infoDir = Path.of(info.directory);
+ if (!candidates.contains(infoDir)) {
+ candidates.add(infoDir);
+ }
+ }
+ if (candidates.isEmpty()) {
+ return new LoadResult(Collections.emptyList(), null, "Cannot
determine integration directory");
+ }
+
+ boolean jbangMode = "JBang".equals(info.platform) ||
"Camel".equals(info.platform);
+
+ if (jbangMode) {
+ for (Path dir : candidates) {
+ Path propsFile =
dir.resolve(".camel-jbang").resolve("camel-jbang-run.properties");
+ if (Files.exists(propsFile)) {
+ List<DepEntry> deps = loadFromRunProperties(propsFile);
+ return new LoadResult(deps, "jbang", deps.isEmpty() ? "No
dependencies in run properties" : null);
+ }
+ }
+ }
+
+ for (Path dir : candidates) {
+ Path pomFile = dir.resolve("pom.xml");
+ if (Files.exists(pomFile)) {
+ List<DepEntry> deps = loadFromPomXml(pomFile);
+ return new LoadResult(deps, "pom.xml", deps.isEmpty() ? "No
compile dependencies in pom.xml" : null);
+ }
+ }
+
+ if (!jbangMode) {
+ for (Path dir : candidates) {
+ Path propsFile =
dir.resolve(".camel-jbang").resolve("camel-jbang-run.properties");
+ if (Files.exists(propsFile)) {
+ List<DepEntry> deps = loadFromRunProperties(propsFile);
+ return new LoadResult(deps, "jbang", deps.isEmpty() ? "No
dependencies in run properties" : null);
+ }
+ }
+ }
+
+ return new LoadResult(Collections.emptyList(), null, "No dependency
information found");
+ }
+
+ static List<DepEntry> resolveTransitives(List<DepEntry> directDeps) {
+ if (directDeps.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ try (MavenDownloaderImpl downloader = new MavenDownloaderImpl()) {
+ downloader.build();
+
+ Set<String> directKeys = new HashSet<>();
+ for (DepEntry d : directDeps) {
+ directKeys.add(d.groupId() + ":" + d.artifactId());
+ }
+
+ boolean hasSnapshot = directDeps.stream()
+ .anyMatch(d -> d.version() != null &&
d.version().contains("SNAPSHOT"));
+
+ Map<String, DepEntry> transitiveMap = new HashMap<>();
+ for (DepEntry direct : directDeps) {
+ if (direct.version() == null) {
+ continue;
+ }
+ String gav = direct.groupId() + ":" + direct.artifactId() +
":" + direct.version();
+ String parentKey = direct.groupId() + ":" +
direct.artifactId();
+ try {
+ List<MavenArtifact> resolved = downloader.resolveArtifacts(
+ List.of(gav), Set.of(), true, hasSnapshot);
+ for (MavenArtifact ma : resolved) {
+ MavenGav g = ma.getGav();
+ if (skipArtifact(g.getGroupId(), g.getArtifactId())) {
+ continue;
+ }
+ String key = g.getGroupId() + ":" + g.getArtifactId();
+ if (!directKeys.contains(key) &&
!transitiveMap.containsKey(key)) {
+ transitiveMap.put(key, new DepEntry(
+ g.getGroupId(), g.getArtifactId(),
g.getVersion(), true, parentKey));
+ }
+ }
+ } catch (Exception e) {
+ // skip this dependency
+ }
+ }
+
+ List<DepEntry> entries = new ArrayList<>(transitiveMap.values());
+ entries.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
+ return entries;
+ } catch (Exception e) {
+ return Collections.emptyList();
+ }
+ }
+
+ static List<DepEntry> loadFromPomXml(Path pomFile) {
+ try {
+ DocumentBuilderFactory dbf =
XmlHelper.createDocumentBuilderFactory();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document dom;
+ try (InputStream is = Files.newInputStream(pomFile)) {
+ dom = db.parse(is);
+ }
+
+ Map<String, String> properties = new HashMap<>();
+ NodeList propsList = dom.getElementsByTagName("properties");
+ if (propsList.getLength() > 0) {
+ Element propsEl = (Element) propsList.item(0);
+ for (int i = 0; i < propsEl.getChildNodes().getLength(); i++) {
+ if (propsEl.getChildNodes().item(i) instanceof Element
prop) {
+ properties.put(prop.getTagName(),
prop.getTextContent().trim());
+ }
+ }
+ }
+
+ String camelVersion = null;
+ String springBootVersion = null;
+ String quarkusVersion = null;
+
+ NodeList parentList = dom.getElementsByTagName("parent");
+ if (parentList.getLength() > 0) {
+ Element parentEl = (Element) parentList.item(0);
+ String pg = textContent(parentEl, "groupId");
+ String pa = textContent(parentEl, "artifactId");
+ String pv = textContent(parentEl, "version");
+ pv = resolveProperty(pv, properties);
+ if ("org.springframework.boot".equals(pg)
+ && ("spring-boot-starter-parent".equals(pa) ||
"spring-boot-dependencies".equals(pa))) {
+ springBootVersion = pv;
+ }
+ if ("org.apache.camel.springboot".equals(pg) &&
"camel-spring-boot-bom".equals(pa)) {
+ camelVersion = pv;
+ }
+ }
+
+ NodeList nl = dom.getElementsByTagName("dependency");
+ List<DepEntry> deps = new ArrayList<>();
+
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element node = (Element) nl.item(i);
+
+ String p = node.getParentNode().getNodeName();
+ String p2 = node.getParentNode().getParentNode().getNodeName();
+ boolean accept = ("dependencyManagement".equals(p2) ||
"project".equals(p2))
+ && "dependencies".equals(p);
+ if (!accept) {
+ continue;
+ }
+
+ String g =
node.getElementsByTagName("groupId").item(0).getTextContent();
+ String a =
node.getElementsByTagName("artifactId").item(0).getTextContent();
+ String v = null;
+ NodeList vl = node.getElementsByTagName("version");
+ if (vl.getLength() > 0) {
+ v = vl.item(0).getTextContent();
+ }
+
+ v = resolveProperty(v, properties);
+
+ if ("org.apache.camel".equals(g) && "camel-bom".equals(a)) {
+ camelVersion = v;
+ continue;
+ }
+ if ("org.apache.camel.springboot".equals(g) &&
"camel-spring-boot-bom".equals(a)) {
+ camelVersion = v;
+ continue;
+ }
+ if ("org.springframework.boot".equals(g) &&
"spring-boot-dependencies".equals(a)) {
+ springBootVersion = v;
+ continue;
+ }
+ if (("${quarkus.platform.group-id}".equals(g) ||
"io.quarkus.platform".equals(g))
+ && ("${quarkus.platform.artifact-id}".equals(a) ||
"quarkus-bom".equals(a))) {
+ if ("${quarkus.platform.version}".equals(v)) {
+ NodeList qvl =
dom.getElementsByTagName("quarkus.platform.version");
+ if (qvl.getLength() > 0) {
+ quarkusVersion = qvl.item(0).getTextContent();
+ }
+ } else {
+ quarkusVersion = v;
+ }
+ continue;
+ }
+
+ String scope = null;
+ NodeList sl = node.getElementsByTagName("scope");
+ if (sl.getLength() > 0) {
+ scope = sl.item(0).getTextContent();
+ }
+ if ("test".equals(scope) || "import".equals(scope)) {
+ continue;
+ }
+
+ if (v == null && "org.apache.camel".equals(g)) {
+ v = camelVersion;
+ }
+ if (v == null && "org.apache.camel.springboot".equals(g)) {
+ v = camelVersion;
+ }
+ if (v == null && "org.springframework.boot".equals(g)) {
+ v = springBootVersion;
+ }
+ if (v == null && ("io.quarkus".equals(g) ||
"org.apache.camel.quarkus".equals(g))) {
+ v = quarkusVersion;
+ }
+
+ g = resolveProperty(g, properties);
+ a = resolveProperty(a, properties);
+ v = resolveProperty(v, properties);
+
+ if (skipArtifact(g, a)) {
+ continue;
+ }
+
+ deps.add(new DepEntry(g, a, v));
+ }
+
+ deps.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
+ return deps;
+ } catch (Exception e) {
+ return Collections.emptyList();
+ }
+ }
+
+ static List<DepEntry> loadFromRunProperties(Path propsFile) {
+ try {
+ List<String> lines = Files.readAllLines(propsFile);
+ List<DepEntry> deps = new ArrayList<>();
+
+ for (String line : lines) {
+ line = line.trim();
+ if (!line.startsWith("dependency=")) {
+ continue;
+ }
+ String value = line.substring("dependency=".length()).trim();
+ value = value.replace("\\:", ":");
+
+ if (value.startsWith("mvn:") || value.startsWith("mvn\\:")) {
+ String gav = value.startsWith("mvn:") ? value.substring(4)
: value.substring(5);
+ MavenGav parsed = MavenGav.parseGav(gav);
+ if (parsed.getGroupId() != null && parsed.getArtifactId()
!= null) {
+ if (!skipArtifact(parsed.getGroupId(),
parsed.getArtifactId())) {
+ deps.add(new DepEntry(parsed.getGroupId(),
parsed.getArtifactId(), parsed.getVersion()));
+ }
+ }
+ }
+ }
+
+ deps.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
+ return deps;
+ } catch (Exception e) {
+ return Collections.emptyList();
+ }
+ }
+
+ static boolean skipArtifact(String groupId, String artifactId) {
+ if ("org.fusesource.jansi".equals(groupId)) {
+ return true;
+ }
+ if ("org.apache.logging.log4j".equals(groupId)) {
+ return true;
+ }
+ if ("org.apache.camel".equals(groupId) &&
"camel-kamelet-main".equals(artifactId)) {
+ return true;
+ }
+ if ("org.apache.camel".equals(groupId) &&
"camel-cli-connector".equals(artifactId)) {
+ return true;
+ }
+ return false;
+ }
+
+ static String shortArtifact(String ga) {
+ if (ga == null) {
+ return "";
+ }
+ int colon = ga.indexOf(':');
+ return colon >= 0 ? ga.substring(colon + 1) : ga;
+ }
+
+ static String resolveProperty(String value, Map<String, String>
properties) {
+ if (value != null && value.startsWith("${") && value.endsWith("}")) {
+ String key = value.substring(2, value.length() - 1);
+ String resolved = properties.get(key);
+ if (resolved != null) {
+ return resolved;
+ }
+ }
+ return value;
+ }
+
+ static String textContent(Element parent, String tag) {
+ NodeList nl = parent.getElementsByTagName(tag);
+ return nl.getLength() > 0 ? nl.item(0).getTextContent().trim() : null;
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
index 0ebf416a42b3..87806f9a9a42 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
@@ -16,26 +16,14 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
import dev.tamboui.layout.Constraint;
import dev.tamboui.layout.Rect;
import dev.tamboui.style.Color;
@@ -54,10 +42,6 @@ import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
-import org.apache.camel.dsl.jbang.core.common.XmlHelper;
-import org.apache.camel.tooling.maven.MavenArtifact;
-import org.apache.camel.tooling.maven.MavenDownloaderImpl;
-import org.apache.camel.tooling.maven.MavenGav;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -78,8 +62,8 @@ class MavenDependenciesTab extends AbstractTableTab {
private TextInputState filterInputState = new TextInputState("");
private String filterTerm;
private int scopeIndex;
- private List<DepEntry> allEntries = Collections.emptyList();
- private List<DepEntry> filteredEntries = Collections.emptyList();
+ private List<DependencyLoader.DepEntry> allEntries =
Collections.emptyList();
+ private List<DependencyLoader.DepEntry> filteredEntries =
Collections.emptyList();
private String lastPid;
private String errorMessage;
private boolean dataLoaded;
@@ -87,7 +71,7 @@ class MavenDependenciesTab extends AbstractTableTab {
private boolean transitiveMode;
private boolean transitiveLoading;
private boolean transitiveLoaded;
- private List<DepEntry> transitiveEntries = Collections.emptyList();
+ private List<DependencyLoader.DepEntry> transitiveEntries =
Collections.emptyList();
MavenDependenciesTab(MonitorContext ctx) {
super(ctx, "artifact", "version", "via");
@@ -121,6 +105,11 @@ class MavenDependenciesTab extends AbstractTableTab {
transitiveLoading = false;
transitiveLoaded = false;
transitiveEntries = Collections.emptyList();
+ loading.set(false);
+ if (ctx.selectedPid != null) {
+ lastPid = ctx.selectedPid;
+ loadDependencies();
+ }
}
@Override
@@ -226,16 +215,16 @@ class MavenDependenciesTab extends AbstractTableTab {
@Override
protected void renderContent(Frame frame, Rect area, IntegrationInfo info)
{
- List<DepEntry> sorted = new ArrayList<>(filteredEntries);
+ List<DependencyLoader.DepEntry> sorted = new
ArrayList<>(filteredEntries);
sorted.sort(this::sortDep);
List<Row> rows = new ArrayList<>();
- for (DepEntry entry : sorted) {
+ for (DependencyLoader.DepEntry entry : sorted) {
String artifact = entry.groupId() + ":" + entry.artifactId();
String ver = entry.version() != null ? entry.version() : "";
Style style = entry.transitive() ? Style.EMPTY.dim() : Style.EMPTY;
if (transitiveMode) {
- String via = entry.parent() != null ?
shortArtifact(entry.parent()) : "";
+ String via = entry.parent() != null ?
DependencyLoader.shortArtifact(entry.parent()) : "";
rows.add(Row.from(
Cell.from(Span.styled(" " + artifact, style)),
Cell.from(Span.styled(ver, style)),
@@ -335,7 +324,7 @@ class MavenDependenciesTab extends AbstractTableTab {
hintLast(spans, TuiIcons.HINT_SCROLL, "navigate");
}
- private int sortDep(DepEntry a, DepEntry b) {
+ private int sortDep(DependencyLoader.DepEntry a, DependencyLoader.DepEntry
b) {
int result = switch (sort) {
case "version" -> {
String va = a.version() != null ? a.version() : "";
@@ -343,8 +332,8 @@ class MavenDependenciesTab extends AbstractTableTab {
yield va.compareToIgnoreCase(vb);
}
case "via" -> {
- String pa = a.parent() != null ? shortArtifact(a.parent()) :
"";
- String pb = b.parent() != null ? shortArtifact(b.parent()) :
"";
+ String pa = a.parent() != null ?
DependencyLoader.shortArtifact(a.parent()) : "";
+ String pb = b.parent() != null ?
DependencyLoader.shortArtifact(b.parent()) : "";
yield pa.compareToIgnoreCase(pb);
}
default -> { // "artifact"
@@ -365,56 +354,8 @@ class MavenDependenciesTab extends AbstractTableTab {
ctx.runner.scheduler().execute(() -> {
try {
- List<Path> candidates = new ArrayList<>();
- Path sourceDir = FilesBrowser.resolveSourceDirectory(info);
- if (sourceDir != null) {
- candidates.add(sourceDir);
- }
- if (info.directory != null && !info.directory.isEmpty()) {
- Path infoDir = Path.of(info.directory);
- if (!candidates.contains(infoDir)) {
- candidates.add(infoDir);
- }
- }
- if (candidates.isEmpty()) {
- applyResult(Collections.emptyList(), null, "Cannot
determine integration directory");
- return;
- }
-
- boolean jbangMode = "JBang".equals(info.platform) ||
"Camel".equals(info.platform);
-
- if (jbangMode) {
- for (Path dir : candidates) {
- Path propsFile =
dir.resolve(".camel-jbang").resolve("camel-jbang-run.properties");
- if (Files.exists(propsFile)) {
- List<DepEntry> deps =
loadFromRunProperties(propsFile);
- applyResult(deps, "jbang", deps.isEmpty() ? "No
dependencies in run properties" : null);
- return;
- }
- }
- }
-
- for (Path dir : candidates) {
- Path pomFile = dir.resolve("pom.xml");
- if (Files.exists(pomFile)) {
- List<DepEntry> deps = loadFromPomXml(pomFile);
- applyResult(deps, "pom.xml", deps.isEmpty() ? "No
compile dependencies in pom.xml" : null);
- return;
- }
- }
-
- if (!jbangMode) {
- for (Path dir : candidates) {
- Path propsFile =
dir.resolve(".camel-jbang").resolve("camel-jbang-run.properties");
- if (Files.exists(propsFile)) {
- List<DepEntry> deps =
loadFromRunProperties(propsFile);
- applyResult(deps, "jbang", deps.isEmpty() ? "No
dependencies in run properties" : null);
- return;
- }
- }
- }
-
- applyResult(Collections.emptyList(), null, "No dependency
information found");
+ DependencyLoader.LoadResult result =
DependencyLoader.loadDependencies(info);
+ applyResult(result.entries(), result.source(), result.error());
} catch (Exception e) {
applyResult(Collections.emptyList(), null, "Error: " +
e.getMessage());
} finally {
@@ -429,45 +370,8 @@ class MavenDependenciesTab extends AbstractTableTab {
}
transitiveLoading = true;
ctx.runner.scheduler().execute(() -> {
- try (MavenDownloaderImpl downloader = new MavenDownloaderImpl()) {
- downloader.build();
-
- Set<String> directKeys = new HashSet<>();
- for (DepEntry d : allEntries) {
- directKeys.add(d.groupId() + ":" + d.artifactId());
- }
-
- boolean hasSnapshot = allEntries.stream()
- .anyMatch(d -> d.version() != null &&
d.version().contains("SNAPSHOT"));
-
- Map<String, DepEntry> transitiveMap = new HashMap<>();
- for (DepEntry direct : allEntries) {
- if (direct.version() == null) {
- continue;
- }
- String gav = direct.groupId() + ":" + direct.artifactId()
+ ":" + direct.version();
- String parentKey = direct.groupId() + ":" +
direct.artifactId();
- try {
- List<MavenArtifact> resolved =
downloader.resolveArtifacts(
- List.of(gav), Set.of(), true, hasSnapshot);
- for (MavenArtifact ma : resolved) {
- MavenGav g = ma.getGav();
- if (skipArtifact(g.getGroupId(),
g.getArtifactId())) {
- continue;
- }
- String key = g.getGroupId() + ":" +
g.getArtifactId();
- if (!directKeys.contains(key) &&
!transitiveMap.containsKey(key)) {
- transitiveMap.put(key, new DepEntry(
- g.getGroupId(), g.getArtifactId(),
g.getVersion(), true, parentKey));
- }
- }
- } catch (Exception e) {
- // skip this dependency
- }
- }
-
- List<DepEntry> entries = new
ArrayList<>(transitiveMap.values());
- entries.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
+ try {
+ List<DependencyLoader.DepEntry> entries =
DependencyLoader.resolveTransitives(allEntries);
applyTransitiveResult(entries);
} catch (Exception e) {
applyTransitiveResult(Collections.emptyList());
@@ -475,7 +379,7 @@ class MavenDependenciesTab extends AbstractTableTab {
});
}
- private void applyTransitiveResult(List<DepEntry> entries) {
+ private void applyTransitiveResult(List<DependencyLoader.DepEntry>
entries) {
if (ctx.runner == null) {
return;
}
@@ -488,207 +392,7 @@ class MavenDependenciesTab extends AbstractTableTab {
});
}
- private List<DepEntry> loadFromPomXml(Path pomFile) {
- try {
- DocumentBuilderFactory dbf =
XmlHelper.createDocumentBuilderFactory();
- DocumentBuilder db = dbf.newDocumentBuilder();
- Document dom;
- try (InputStream is = Files.newInputStream(pomFile)) {
- dom = db.parse(is);
- }
-
- Map<String, String> properties = new HashMap<>();
- NodeList propsList = dom.getElementsByTagName("properties");
- if (propsList.getLength() > 0) {
- Element propsEl = (Element) propsList.item(0);
- for (int i = 0; i < propsEl.getChildNodes().getLength(); i++) {
- if (propsEl.getChildNodes().item(i) instanceof Element
prop) {
- properties.put(prop.getTagName(),
prop.getTextContent().trim());
- }
- }
- }
-
- String camelVersion = null;
- String springBootVersion = null;
- String quarkusVersion = null;
-
- NodeList parentList = dom.getElementsByTagName("parent");
- if (parentList.getLength() > 0) {
- Element parentEl = (Element) parentList.item(0);
- String pg = textContent(parentEl, "groupId");
- String pa = textContent(parentEl, "artifactId");
- String pv = textContent(parentEl, "version");
- pv = resolveProperty(pv, properties);
- if ("org.springframework.boot".equals(pg)
- && ("spring-boot-starter-parent".equals(pa) ||
"spring-boot-dependencies".equals(pa))) {
- springBootVersion = pv;
- }
- if ("org.apache.camel.springboot".equals(pg) &&
"camel-spring-boot-bom".equals(pa)) {
- camelVersion = pv;
- }
- }
-
- NodeList nl = dom.getElementsByTagName("dependency");
- List<DepEntry> deps = new ArrayList<>();
-
- for (int i = 0; i < nl.getLength(); i++) {
- Element node = (Element) nl.item(i);
-
- String p = node.getParentNode().getNodeName();
- String p2 = node.getParentNode().getParentNode().getNodeName();
- boolean accept = ("dependencyManagement".equals(p2) ||
"project".equals(p2))
- && "dependencies".equals(p);
- if (!accept) {
- continue;
- }
-
- String g =
node.getElementsByTagName("groupId").item(0).getTextContent();
- String a =
node.getElementsByTagName("artifactId").item(0).getTextContent();
- String v = null;
- NodeList vl = node.getElementsByTagName("version");
- if (vl.getLength() > 0) {
- v = vl.item(0).getTextContent();
- }
-
- v = resolveProperty(v, properties);
-
- if ("org.apache.camel".equals(g) && "camel-bom".equals(a)) {
- camelVersion = v;
- continue;
- }
- if ("org.apache.camel.springboot".equals(g) &&
"camel-spring-boot-bom".equals(a)) {
- camelVersion = v;
- continue;
- }
- if ("org.springframework.boot".equals(g) &&
"spring-boot-dependencies".equals(a)) {
- springBootVersion = v;
- continue;
- }
- if (("${quarkus.platform.group-id}".equals(g) ||
"io.quarkus.platform".equals(g))
- && ("${quarkus.platform.artifact-id}".equals(a) ||
"quarkus-bom".equals(a))) {
- if ("${quarkus.platform.version}".equals(v)) {
- NodeList qvl =
dom.getElementsByTagName("quarkus.platform.version");
- if (qvl.getLength() > 0) {
- quarkusVersion = qvl.item(0).getTextContent();
- }
- } else {
- quarkusVersion = v;
- }
- continue;
- }
-
- String scope = null;
- NodeList sl = node.getElementsByTagName("scope");
- if (sl.getLength() > 0) {
- scope = sl.item(0).getTextContent();
- }
- if ("test".equals(scope) || "import".equals(scope)) {
- continue;
- }
-
- if (v == null && "org.apache.camel".equals(g)) {
- v = camelVersion;
- }
- if (v == null && "org.apache.camel.springboot".equals(g)) {
- v = camelVersion;
- }
- if (v == null && "org.springframework.boot".equals(g)) {
- v = springBootVersion;
- }
- if (v == null && ("io.quarkus".equals(g) ||
"org.apache.camel.quarkus".equals(g))) {
- v = quarkusVersion;
- }
-
- g = resolveProperty(g, properties);
- a = resolveProperty(a, properties);
- v = resolveProperty(v, properties);
-
- if (skipArtifact(g, a)) {
- continue;
- }
-
- deps.add(new DepEntry(g, a, v));
- }
-
- deps.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
- return deps;
- } catch (Exception e) {
- return Collections.emptyList();
- }
- }
-
- private List<DepEntry> loadFromRunProperties(Path propsFile) {
- try {
- List<String> lines = Files.readAllLines(propsFile);
- List<DepEntry> deps = new ArrayList<>();
-
- for (String line : lines) {
- line = line.trim();
- if (!line.startsWith("dependency=")) {
- continue;
- }
- String value = line.substring("dependency=".length()).trim();
- value = value.replace("\\:", ":");
-
- if (value.startsWith("mvn:") || value.startsWith("mvn\\:")) {
- String gav = value.startsWith("mvn:") ? value.substring(4)
: value.substring(5);
- MavenGav parsed = MavenGav.parseGav(gav);
- if (parsed.getGroupId() != null && parsed.getArtifactId()
!= null) {
- if (!skipArtifact(parsed.getGroupId(),
parsed.getArtifactId())) {
- deps.add(new DepEntry(parsed.getGroupId(),
parsed.getArtifactId(), parsed.getVersion()));
- }
- }
- }
- }
-
- deps.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
- return deps;
- } catch (Exception e) {
- return Collections.emptyList();
- }
- }
-
- private static String textContent(Element parent, String tag) {
- NodeList nl = parent.getElementsByTagName(tag);
- return nl.getLength() > 0 ? nl.item(0).getTextContent().trim() : null;
- }
-
- private static String resolveProperty(String value, Map<String, String>
properties) {
- if (value != null && value.startsWith("${") && value.endsWith("}")) {
- String key = value.substring(2, value.length() - 1);
- String resolved = properties.get(key);
- if (resolved != null) {
- return resolved;
- }
- }
- return value;
- }
-
- private static String shortArtifact(String ga) {
- if (ga == null) {
- return "";
- }
- int colon = ga.indexOf(':');
- return colon >= 0 ? ga.substring(colon + 1) : ga;
- }
-
- private static boolean skipArtifact(String groupId, String artifactId) {
- if ("org.fusesource.jansi".equals(groupId)) {
- return true;
- }
- if ("org.apache.logging.log4j".equals(groupId)) {
- return true;
- }
- if ("org.apache.camel".equals(groupId) &&
"camel-kamelet-main".equals(artifactId)) {
- return true;
- }
- if ("org.apache.camel".equals(groupId) &&
"camel-cli-connector".equals(artifactId)) {
- return true;
- }
- return false;
- }
-
- private void applyResult(List<DepEntry> parsed, String source, String
error) {
+ private void applyResult(List<DependencyLoader.DepEntry> parsed, String
source, String error) {
if (ctx.runner == null) {
return;
}
@@ -702,13 +406,13 @@ class MavenDependenciesTab extends AbstractTableTab {
}
private void refilter() {
- List<DepEntry> source = transitiveMode
+ List<DependencyLoader.DepEntry> source = transitiveMode
? combinedEntries()
: allEntries;
- List<DepEntry> result = new ArrayList<>();
+ List<DependencyLoader.DepEntry> result = new ArrayList<>();
String ft = filterTerm != null ? filterTerm.toLowerCase() : null;
String scope = SCOPES[scopeIndex];
- for (DepEntry entry : source) {
+ for (DependencyLoader.DepEntry entry : source) {
if ("camel".equals(scope) && !entry.isCamel()) {
continue;
}
@@ -726,18 +430,18 @@ class MavenDependenciesTab extends AbstractTableTab {
}
}
- private List<DepEntry> combinedEntries() {
+ private List<DependencyLoader.DepEntry> combinedEntries() {
Set<String> directKeys = new HashSet<>();
- for (DepEntry d : allEntries) {
+ for (DependencyLoader.DepEntry d : allEntries) {
directKeys.add(d.groupId() + ":" + d.artifactId());
}
- List<DepEntry> combined = new ArrayList<>(allEntries);
- for (DepEntry t : transitiveEntries) {
+ List<DependencyLoader.DepEntry> combined = new ArrayList<>(allEntries);
+ for (DependencyLoader.DepEntry t : transitiveEntries) {
if (!directKeys.contains(t.groupId() + ":" + t.artifactId())) {
combined.add(t);
}
}
- combined.sort(Comparator.comparing(DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
+ combined.sort(Comparator.comparing(DependencyLoader.DepEntry::display,
String.CASE_INSENSITIVE_ORDER));
return combined;
}
@@ -761,29 +465,11 @@ class MavenDependenciesTab extends AbstractTableTab {
if (filteredEntries.isEmpty()) {
return null;
}
- List<String> items =
filteredEntries.stream().map(DepEntry::display).toList();
+ List<String> items =
filteredEntries.stream().map(DependencyLoader.DepEntry::display).toList();
Integer sel = tableState.selected();
return new SelectionContext("table", items, sel != null ? sel : -1,
items.size(), "Maven Dependencies");
}
- record DepEntry(String groupId, String artifactId, String version, boolean
transitive, String parent) {
-
- DepEntry(String groupId, String artifactId, String version) {
- this(groupId, artifactId, version, false, null);
- }
-
- String display() {
- if (version != null) {
- return groupId + ":" + artifactId + ":" + version;
- }
- return groupId + ":" + artifactId;
- }
-
- boolean isCamel() {
- return groupId != null && groupId.startsWith("org.apache.camel");
- }
- }
-
@Override
public String description() {
return "Maven dependency entries with filtering";
@@ -878,14 +564,14 @@ class MavenDependenciesTab extends AbstractTableTab {
@Override
public JsonObject getTableDataAsJson() {
- List<DepEntry> entries = filteredEntries;
+ List<DependencyLoader.DepEntry> entries = filteredEntries;
if (entries.isEmpty()) {
return null;
}
JsonObject result = new JsonObject();
result.put("tab", "Maven Dependencies");
JsonArray rows = new JsonArray();
- for (DepEntry d : entries) {
+ for (DependencyLoader.DepEntry d : entries) {
JsonObject row = new JsonObject();
row.put("groupId", d.groupId());
row.put("artifactId", d.artifactId());
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OsvClient.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OsvClient.java
index f140d00bc4fd..0d346b94f33b 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OsvClient.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OsvClient.java
@@ -54,11 +54,11 @@ class OsvClient {
*
* @return map from GAV string (groupId:artifactId:version) to list of
vulnerabilities
*/
- Map<String, List<Vulnerability>> queryBatch(List<ClasspathTab.JarEntry>
entries) {
+ Map<String, List<Vulnerability>>
queryBatch(List<DependencyLoader.DepEntry> entries) {
Map<String, List<Vulnerability>> result = new HashMap<>();
- List<ClasspathTab.JarEntry> uncached = new ArrayList<>();
+ List<DependencyLoader.DepEntry> uncached = new ArrayList<>();
- for (ClasspathTab.JarEntry entry : entries) {
+ for (DependencyLoader.DepEntry entry : entries) {
if (entry.groupId() == null) {
continue;
}
@@ -76,7 +76,7 @@ class OsvClient {
}
JsonArray queries = new JsonArray();
- for (ClasspathTab.JarEntry entry : uncached) {
+ for (DependencyLoader.DepEntry entry : uncached) {
JsonObject pkg = new JsonObject();
pkg.put("name", entry.groupId() + ":" + entry.artifactId());
pkg.put("ecosystem", "Maven");
@@ -110,7 +110,7 @@ class OsvClient {
// collect vuln IDs per GAV, then fetch full details
Map<String, List<String>> gavToVulnIds = new HashMap<>();
for (int i = 0; i < results.size() && i < uncached.size();
i++) {
- ClasspathTab.JarEntry entry = uncached.get(i);
+ DependencyLoader.DepEntry entry = uncached.get(i);
String gav = entry.display();
JsonObject queryResult = (JsonObject) results.get(i);
JsonArray vulns = (JsonArray) queryResult.get("vulns");
@@ -152,7 +152,7 @@ class OsvClient {
}
// cache empty results for uncached entries that got no response
- for (ClasspathTab.JarEntry entry : uncached) {
+ for (DependencyLoader.DepEntry entry : uncached) {
String gav = entry.display();
result.putIfAbsent(gav, Collections.emptyList());
CACHE.putIfAbsent(gav, Collections.emptyList());
@@ -198,8 +198,8 @@ class OsvClient {
VULN_DETAIL_CACHE.clear();
}
- void clearCache(List<ClasspathTab.JarEntry> entries) {
- for (ClasspathTab.JarEntry entry : entries) {
+ void clearCache(List<DependencyLoader.DepEntry> entries) {
+ for (DependencyLoader.DepEntry entry : entries) {
if (entry.groupId() != null) {
CACHE.remove(entry.display());
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TabRegistry.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TabRegistry.java
index fbcd5724e4ec..588f6d965c3e 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TabRegistry.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TabRegistry.java
@@ -256,23 +256,9 @@ class TabRegistry {
httpTab.onIntegrationChanged();
logTab.onIntegrationChanged();
historyTab.onIntegrationChanged();
- beansTab.onIntegrationChanged();
- browseTab.onIntegrationChanged();
- threadsTab.onIntegrationChanged();
- startupTab.onIntegrationChanged();
- configurationTab.onIntegrationChanged();
- consumersTab.onIntegrationChanged();
- cveAuditTab.onIntegrationChanged();
- dataSourceTab.onIntegrationChanged();
- heapHistogramTab.onIntegrationChanged();
- mavenDependenciesTab.onIntegrationChanged();
- memoryLeakTab.onIntegrationChanged();
- sqlQueryTab.onIntegrationChanged();
- sqlTraceTab.onIntegrationChanged();
- circuitBreakerTab.onIntegrationChanged();
- inflightTab.onIntegrationChanged();
- spansTab.onIntegrationChanged();
- processTab.onIntegrationChanged();
+ for (MoreTab mt : moreTabs) {
+ mt.tab().onIntegrationChanged();
+ }
dataService.otelSpans().set(List.of());
filesBrowser.reset();