This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch fix/camel-tui-tamboui-improvements in repository https://gitbox.apache.org/repos/asf/camel.git
commit 575f2f212a2351f0a6403957a885757ec14b3db7 Author: Claus Ibsen <[email protected]> AuthorDate: Fri May 15 17:37:17 2026 +0200 CAMEL-23514: Extract addExchangeInfoLines, addKvLines, addBodyLines, and renderDetailPanel shared helpers Eliminate duplicate exchange-info header rendering, key-value section rendering, body rendering, and detail-panel scroll/paragraph/scrollbar logic that was copy-pasted between renderTraceStepDetail and renderHistoryDetail. --- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 345 ++++++--------------- 1 file changed, 97 insertions(+), 248 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java index ad4725829726..5caed2dfb0e8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java @@ -2249,157 +2249,24 @@ public class CamelMonitor extends CamelCommand { TraceEntry entry = steps.get(sel); List<Line> lines = new ArrayList<>(); - // Exchange info - lines.add(Line.from( - Span.styled(" Exchange: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.exchangeId != null ? entry.exchangeId : ""))); - lines.add(Line.from( - Span.styled(" Route: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.routeId != null ? entry.routeId : ""), - Span.styled(" Node: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.nodeId != null ? entry.nodeId : ""), - Span.raw(entry.nodeLabel != null ? " (" + entry.nodeLabel + ")" : ""))); - lines.add(Line.from( - Span.styled(" Location: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.location != null ? entry.location : ""))); - lines.add(Line.from( - Span.styled(" Elapsed: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.elapsed >= 0 ? entry.elapsed + "ms" : ""), - Span.styled(" Thread: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.threadName != null ? entry.threadName : ""))); - if (entry.failed) { - lines.add(Line.from( - Span.styled(" Status: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.styled("Failed", Style.EMPTY.fg(Color.RED).bold()))); + addExchangeInfoLines(lines, entry.exchangeId, entry.routeId, entry.nodeId, entry.nodeLabel, + entry.location, entry.elapsed, entry.threadName, entry.failed); + if (showTraceProperties) { + addKvLines(lines, " Exchange Properties:", entry.exchangeProperties, entry.exchangePropertyTypes); } - lines.add(Line.from(Span.raw(""))); - - // Exchange Properties - if (showTraceProperties && entry.exchangeProperties != null && !entry.exchangeProperties.isEmpty()) { - lines.add(Line.from(Span.styled(" Exchange Properties:", Style.EMPTY.fg(Color.GREEN).bold()))); - for (Map.Entry<String, Object> p : entry.exchangeProperties.entrySet()) { - String type = entry.exchangePropertyTypes != null ? entry.exchangePropertyTypes.get(p.getKey()) : null; - String typeLabel; - if (type != null) { - String t = "(" + type + ")"; - t = truncate(t, 20); - typeLabel = String.format("%-20s ", t); - } else { - typeLabel = String.format("%-21s", ""); - } - lines.add(Line.from( - Span.styled(" " + typeLabel, Style.EMPTY.dim()), - Span.styled(p.getKey(), Style.EMPTY.fg(Color.CYAN)), - Span.raw(" = "), - Span.raw(p.getValue() != null ? p.getValue().toString() : "null"))); - } - lines.add(Line.from(Span.raw(""))); - } - - // Exchange Variables - if (showTraceVariables && entry.exchangeVariables != null && !entry.exchangeVariables.isEmpty()) { - lines.add(Line.from(Span.styled(" Exchange Variables:", Style.EMPTY.fg(Color.GREEN).bold()))); - for (Map.Entry<String, Object> v : entry.exchangeVariables.entrySet()) { - String type = entry.exchangeVariableTypes != null ? entry.exchangeVariableTypes.get(v.getKey()) : null; - String typeLabel; - if (type != null) { - String t = "(" + type + ")"; - t = truncate(t, 20); - typeLabel = String.format("%-20s ", t); - } else { - typeLabel = String.format("%-21s", ""); - } - lines.add(Line.from( - Span.styled(" " + typeLabel, Style.EMPTY.dim()), - Span.styled(v.getKey(), Style.EMPTY.fg(Color.CYAN)), - Span.raw(" = "), - Span.raw(v.getValue() != null ? v.getValue().toString() : "null"))); - } - lines.add(Line.from(Span.raw(""))); + if (showTraceVariables) { + addKvLines(lines, " Exchange Variables:", entry.exchangeVariables, entry.exchangeVariableTypes); } - - // Headers - if (showTraceHeaders && entry.headers != null && !entry.headers.isEmpty()) { - lines.add(Line.from(Span.styled(" Headers:", Style.EMPTY.fg(Color.GREEN).bold()))); - for (Map.Entry<String, Object> h : entry.headers.entrySet()) { - String type = entry.headerTypes != null ? entry.headerTypes.get(h.getKey()) : null; - String typeLabel; - if (type != null) { - String t = "(" + type + ")"; - t = truncate(t, 20); - typeLabel = String.format("%-20s ", t); - } else { - typeLabel = String.format("%-21s", ""); - } - lines.add(Line.from( - Span.styled(" " + typeLabel, Style.EMPTY.dim()), - Span.styled(h.getKey(), Style.EMPTY.fg(Color.CYAN)), - Span.raw(" = "), - Span.raw(h.getValue() != null ? h.getValue().toString() : "null"))); - } - lines.add(Line.from(Span.raw(""))); + if (showTraceHeaders) { + addKvLines(lines, " Headers:", entry.headers, entry.headerTypes); } - - // Body if (showTraceBody) { - if (entry.body != null) { - if (entry.bodyType != null) { - lines.add(Line.from( - Span.styled(" Body: ", Style.EMPTY.fg(Color.GREEN).bold()), - Span.styled("(" + entry.bodyType + ")", Style.EMPTY.dim()))); - } else { - lines.add(Line.from(Span.styled(" Body:", Style.EMPTY.fg(Color.GREEN).bold()))); - } - String[] bodyLines = entry.body.split("\n"); - for (String bl : bodyLines) { - lines.add(Line.from(Span.raw(" " + bl))); - } - } else { - lines.add(Line.from(Span.styled(" Body is null", Style.EMPTY.fg(Color.GREEN).bold()))); - } - lines.add(Line.from(Span.raw(""))); + addBodyLines(lines, entry.body, entry.bodyType); } - Block block = Block.builder().borderType(BorderType.ROUNDED).build(); - frame.renderWidget(block, area); - - Rect inner = block.inner(area); - int visibleHeight = Math.max(1, inner.height()); - int contentHeight; - if (traceWordWrap) { - int width = Math.max(1, inner.width() - 1); - contentHeight = 0; - for (Line l : lines) { - int w = l.width(); - contentHeight += Math.max(1, (w + width - 1) / width); - } - } else { - contentHeight = lines.size(); - } - int maxScroll = Math.max(0, contentHeight - visibleHeight); - if (traceDetailScroll > maxScroll) { - traceDetailScroll = maxScroll; - } - - List<Rect> hChunks = Layout.horizontal() - .constraints(Constraint.fill(), Constraint.length(1)) - .split(inner); - - Paragraph detail = Paragraph.builder() - .text(Text.from(lines)) - .overflow(traceWordWrap ? Overflow.WRAP_WORD : Overflow.CLIP) - .scroll(traceDetailScroll) - .build(); - frame.renderWidget(detail, hChunks.get(0)); - - if (contentHeight > visibleHeight) { - traceDetailScrollState.contentLength(contentHeight); - traceDetailScrollState.viewportContentLength(visibleHeight); - traceDetailScrollState.position(traceDetailScroll); - frame.renderStatefulWidget( - Scrollbar.builder().build(), - hChunks.get(1), traceDetailScrollState); - } + int[] scroll = { traceDetailScroll }; + renderDetailPanel(frame, area, lines, traceWordWrap, scroll, traceDetailScrollState); + traceDetailScroll = scroll[0]; } private List<String> getTraceExchangeIds() { @@ -2485,131 +2352,113 @@ public class CamelMonitor extends CamelCommand { HistoryEntry entry = current.get(sel); List<Line> lines = new ArrayList<>(); - // Exchange info + addExchangeInfoLines(lines, entry.exchangeId, entry.routeId, entry.nodeId, entry.nodeLabel, + entry.location, entry.elapsed, entry.threadName, entry.failed); + if (showHistoryProperties) { + addKvLines(lines, " Exchange Properties:", entry.exchangeProperties, entry.exchangePropertyTypes); + } + if (showHistoryVariables) { + addKvLines(lines, " Exchange Variables:", entry.exchangeVariables, entry.exchangeVariableTypes); + } + if (showHistoryHeaders) { + addKvLines(lines, " Headers:", entry.headers, entry.headerTypes); + } + if (showHistoryBody) { + addBodyLines(lines, entry.body, entry.bodyType); + } + if (entry.exception != null) { + lines.add(Line.from(Span.styled(" Exception:", Style.EMPTY.fg(Color.RED).bold()))); + lines.add(Line.from(Span.raw(" " + entry.exception))); + } + + int[] scroll = { historyDetailScroll }; + renderDetailPanel(frame, area, lines, historyWordWrap, scroll, historyDetailScrollState); + historyDetailScroll = scroll[0]; + } + + private static void addExchangeInfoLines( + List<Line> lines, String exchangeId, String routeId, + String nodeId, String nodeLabel, String location, long elapsed, String threadName, boolean failed) { lines.add(Line.from( Span.styled(" Exchange: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.exchangeId != null ? entry.exchangeId : ""))); + Span.raw(exchangeId != null ? exchangeId : ""))); lines.add(Line.from( Span.styled(" Route: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.routeId != null ? entry.routeId : ""), + Span.raw(routeId != null ? routeId : ""), Span.styled(" Node: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.nodeId != null ? entry.nodeId : ""), - Span.raw(entry.nodeLabel != null ? " (" + entry.nodeLabel + ")" : ""))); + Span.raw(nodeId != null ? nodeId : ""), + Span.raw(nodeLabel != null ? " (" + nodeLabel + ")" : ""))); lines.add(Line.from( Span.styled(" Location: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.location != null ? entry.location : ""))); + Span.raw(location != null ? location : ""))); lines.add(Line.from( Span.styled(" Elapsed: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.elapsed >= 0 ? entry.elapsed + "ms" : ""), + Span.raw(elapsed >= 0 ? elapsed + "ms" : ""), Span.styled(" Thread: ", Style.EMPTY.fg(Color.YELLOW).bold()), - Span.raw(entry.threadName != null ? entry.threadName : ""))); - if (entry.failed) { + Span.raw(threadName != null ? threadName : ""))); + if (failed) { lines.add(Line.from( Span.styled(" Status: ", Style.EMPTY.fg(Color.YELLOW).bold()), Span.styled("Failed", Style.EMPTY.fg(Color.RED).bold()))); } lines.add(Line.from(Span.raw(""))); + } - // Headers - // Exchange Properties - if (showHistoryProperties && entry.exchangeProperties != null && !entry.exchangeProperties.isEmpty()) { - lines.add(Line.from(Span.styled(" Exchange Properties:", Style.EMPTY.fg(Color.GREEN).bold()))); - for (Map.Entry<String, Object> p : entry.exchangeProperties.entrySet()) { - String type = entry.exchangePropertyTypes != null ? entry.exchangePropertyTypes.get(p.getKey()) : null; - String typeLabel; - if (type != null) { - String t = "(" + type + ")"; - t = truncate(t, 20); - typeLabel = String.format("%-20s ", t); - } else { - typeLabel = String.format("%-21s", ""); - } - lines.add(Line.from( - Span.styled(" " + typeLabel, Style.EMPTY.dim()), - Span.styled(p.getKey(), Style.EMPTY.fg(Color.CYAN)), - Span.raw(" = "), - Span.raw(p.getValue() != null ? p.getValue().toString() : "null"))); - } - lines.add(Line.from(Span.raw(""))); - } - - // Exchange Variables - if (showHistoryVariables && entry.exchangeVariables != null && !entry.exchangeVariables.isEmpty()) { - lines.add(Line.from(Span.styled(" Exchange Variables:", Style.EMPTY.fg(Color.GREEN).bold()))); - for (Map.Entry<String, Object> v : entry.exchangeVariables.entrySet()) { - String type = entry.exchangeVariableTypes != null ? entry.exchangeVariableTypes.get(v.getKey()) : null; - String typeLabel; - if (type != null) { - String t = "(" + type + ")"; - t = truncate(t, 20); - typeLabel = String.format("%-20s ", t); - } else { - typeLabel = String.format("%-21s", ""); - } - lines.add(Line.from( - Span.styled(" " + typeLabel, Style.EMPTY.dim()), - Span.styled(v.getKey(), Style.EMPTY.fg(Color.CYAN)), - Span.raw(" = "), - Span.raw(v.getValue() != null ? v.getValue().toString() : "null"))); - } - lines.add(Line.from(Span.raw(""))); + private static void addKvLines( + List<Line> lines, String section, + Map<String, Object> map, Map<String, String> types) { + if (map == null || map.isEmpty()) { + return; } - - // Headers - if (showHistoryHeaders && entry.headers != null && !entry.headers.isEmpty()) { - lines.add(Line.from(Span.styled(" Headers:", Style.EMPTY.fg(Color.GREEN).bold()))); - for (Map.Entry<String, Object> h : entry.headers.entrySet()) { - String type = entry.headerTypes != null ? entry.headerTypes.get(h.getKey()) : null; - String typeLabel; - if (type != null) { - String t = "(" + type + ")"; - t = truncate(t, 20); - typeLabel = String.format("%-20s ", t); - } else { - typeLabel = String.format("%-21s", ""); - } - lines.add(Line.from( - Span.styled(" " + typeLabel, Style.EMPTY.dim()), - Span.styled(h.getKey(), Style.EMPTY.fg(Color.CYAN)), - Span.raw(" = "), - Span.raw(h.getValue() != null ? h.getValue().toString() : "null"))); + lines.add(Line.from(Span.styled(section, Style.EMPTY.fg(Color.GREEN).bold()))); + for (Map.Entry<String, Object> entry : map.entrySet()) { + String type = types != null ? types.get(entry.getKey()) : null; + String typeLabel; + if (type != null) { + String t = "(" + type + ")"; + t = truncate(t, 20); + typeLabel = String.format("%-20s ", t); + } else { + typeLabel = String.format("%-21s", ""); } - lines.add(Line.from(Span.raw(""))); + lines.add(Line.from( + Span.styled(" " + typeLabel, Style.EMPTY.dim()), + Span.styled(entry.getKey(), Style.EMPTY.fg(Color.CYAN)), + Span.raw(" = "), + Span.raw(entry.getValue() != null ? entry.getValue().toString() : "null"))); } + lines.add(Line.from(Span.raw(""))); + } - // Body - if (showHistoryBody) { - if (entry.body != null) { - if (entry.bodyType != null) { - lines.add(Line.from( - Span.styled(" Body: ", Style.EMPTY.fg(Color.GREEN).bold()), - Span.styled("(" + entry.bodyType + ")", Style.EMPTY.dim()))); - } else { - lines.add(Line.from(Span.styled(" Body:", Style.EMPTY.fg(Color.GREEN).bold()))); - } - String[] bodyLines = entry.body.split("\n"); - for (String bl : bodyLines) { - lines.add(Line.from(Span.raw(" " + bl))); - } + private static void addBodyLines(List<Line> lines, String body, String bodyType) { + if (body != null) { + if (bodyType != null) { + lines.add(Line.from( + Span.styled(" Body: ", Style.EMPTY.fg(Color.GREEN).bold()), + Span.styled("(" + bodyType + ")", Style.EMPTY.dim()))); } else { - lines.add(Line.from(Span.styled(" Body is null", Style.EMPTY.fg(Color.GREEN).bold()))); + lines.add(Line.from(Span.styled(" Body:", Style.EMPTY.fg(Color.GREEN).bold()))); } - lines.add(Line.from(Span.raw(""))); - } - - // Exception - if (entry.exception != null) { - lines.add(Line.from(Span.styled(" Exception:", Style.EMPTY.fg(Color.RED).bold()))); - lines.add(Line.from(Span.raw(" " + entry.exception))); + String[] bodyParts = body.split("\n"); + for (String bl : bodyParts) { + lines.add(Line.from(Span.raw(" " + bl))); + } + } else { + lines.add(Line.from(Span.styled(" Body is null", Style.EMPTY.fg(Color.GREEN).bold()))); } + lines.add(Line.from(Span.raw(""))); + } + private void renderDetailPanel( + Frame frame, Rect area, List<Line> lines, + boolean wordWrap, int[] scroll, ScrollbarState scrollState) { Block block = Block.builder().borderType(BorderType.ROUNDED).build(); frame.renderWidget(block, area); Rect inner = block.inner(area); int visibleHeight = Math.max(1, inner.height()); int contentHeight; - if (historyWordWrap) { + if (wordWrap) { int width = Math.max(1, inner.width() - 1); contentHeight = 0; for (Line l : lines) { @@ -2620,8 +2469,8 @@ public class CamelMonitor extends CamelCommand { contentHeight = lines.size(); } int maxScroll = Math.max(0, contentHeight - visibleHeight); - if (historyDetailScroll > maxScroll) { - historyDetailScroll = maxScroll; + if (scroll[0] > maxScroll) { + scroll[0] = maxScroll; } List<Rect> hChunks = Layout.horizontal() @@ -2630,18 +2479,18 @@ public class CamelMonitor extends CamelCommand { Paragraph detail = Paragraph.builder() .text(Text.from(lines)) - .overflow(historyWordWrap ? Overflow.WRAP_WORD : Overflow.CLIP) - .scroll(historyDetailScroll) + .overflow(wordWrap ? Overflow.WRAP_WORD : Overflow.CLIP) + .scroll(scroll[0]) .build(); frame.renderWidget(detail, hChunks.get(0)); if (contentHeight > visibleHeight) { - historyDetailScrollState.contentLength(contentHeight); - historyDetailScrollState.viewportContentLength(visibleHeight); - historyDetailScrollState.position(historyDetailScroll); + scrollState.contentLength(contentHeight); + scrollState.viewportContentLength(visibleHeight); + scrollState.position(scroll[0]); frame.renderStatefulWidget( Scrollbar.builder().build(), - hChunks.get(1), historyDetailScrollState); + hChunks.get(1), scrollState); } }
