This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-25208-code-assist in repository https://gitbox.apache.org/repos/asf/camel.git
commit c44d7a392b9f5d05a72d673f8e0fd3ba3216cdfe Author: Claus Ibsen <[email protected]> AuthorDate: Thu Oct 1 07:59:03 2026 +0200 CAMEL-25208: camel-jbang - TUI does not save an XML route file with problems, as YAML An XML route file with Camel problems is not saved: the problems are shown, as for a YAML file. A Java file is still saved and its problems said, as it is the application's code. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../modules/ROOT/pages/camel-jbang-tui.adoc | 6 ++-- .../dsl/jbang/core/commands/tui/SourceViewer.java | 21 +++++++++--- .../src/main/resources/tui/help/source.md | 4 +-- .../commands/tui/SourceRouteValidationTest.java | 37 ++++++++++++++++++++++ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-tui.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang-tui.adoc index 96bb27ab346f..c4a7c1de8179 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang-tui.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-tui.adoc @@ -236,9 +236,9 @@ file is not saved and errors are displayed in a popup. This catches mistakes ear Java and XML routes get the same Camel checks, on the Camel model the routes are read into: the endpoint URIs (also those built with the endpoint DSL, or from a constant), Simple expressions, and a `to` whose URI holds -`+${...}+` and should be a `toD`. Their problems are marked on their lines while you type (*F9* jumps to the next) -and said when saving, but they never keep a Java or XML file from being saved: a Java file is the application's -code, and a check that cannot know something (a value computed at runtime) must not stop you. +`+${...}+` and should be a `toD`. Their problems are marked on their lines while you type (*F9* jumps to the next). +An XML file with problems is not saved, as a YAML file; a Java file is saved and its problems are said, as it is +the application's code, and a check that cannot know something (a value computed at runtime) must not stop you. Validation can be toggled off in the Settings (F2 > Settings). diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java index 67a84656d18e..356feb3c1d79 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java @@ -265,8 +265,8 @@ class SourceViewer { /** * The Camel checks of a Java or XML DSL route file (CAMEL-25208): its problems are marked on their lines while - * editing and said on save, which they do not block - a Java file is the application's code, and what the checks - * cannot know must never keep it from being saved. + * editing. An XML file with problems is not saved, as a YAML file; a Java file is saved and the problems are said, + * as a Java file is the application's code, and what the checks cannot know must never keep it from being saved. */ void setRouteValidator(EndpointValidator routeValidator) { this.routeValidator = routeValidator; @@ -1006,6 +1006,10 @@ class SourceViewer { && editableFile.getFileName().toString().toLowerCase().endsWith(".properties"); } + private boolean isXmlFile() { + return editableFile != null && editableFile.getFileName().toString().toLowerCase().endsWith(".xml"); + } + private boolean isCamelYamlFile() { if (editableFile == null) { return false; @@ -1486,10 +1490,17 @@ class SourceViewer { return; } } else if (validateOnSave && routeValidator != null) { - // marked, and said when saved, but not blocking the save List<String> msgs = routeValidator.validate(content); - routeProblems = msgs != null ? msgs : List.of(); - inlineErrors = routeProblems.isEmpty() ? Collections.emptyMap() : buildInlineErrors(routeProblems, content); + msgs = msgs != null ? msgs : List.of(); + inlineErrors = msgs.isEmpty() ? Collections.emptyMap() : buildInlineErrors(msgs, content); + if (isXmlFile() && !msgs.isEmpty()) { + // XML routes as YAML routes: the problems are shown and the file is not saved + validationErrors = msgs; + validationErrorScroll = 0; + } else { + // Java: marked, and said when saved, but not blocking the save + routeProblems = msgs; + } return; } inlineErrors = Collections.emptyMap(); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/help/source.md b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/help/source.md index 933c86b03efb..4f71eee20eb8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/help/source.md +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/help/source.md @@ -42,8 +42,8 @@ explorer on the left and a source viewer on the right. - **F9** — jump to next validation error - Java and XML DSL routes are checked as you type, like YAML routes: endpoint options, simple expressions, and a `to` with `${...}` that should be a `toD`. - The problems are marked on their lines and said when saving, but never keep a - Java or XML file from being saved. + The problems are marked on their lines; an XML file with problems is not saved + (as YAML), a Java file is saved and the problems are said. ## Edit Mode (Tab Completion) Press **F4** to enter edit mode, then **Tab** for context-aware completion: diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceRouteValidationTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceRouteValidationTest.java index dd56ee0d9d9f..6d4b9dc1fcc7 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceRouteValidationTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceRouteValidationTest.java @@ -145,6 +145,43 @@ class SourceRouteValidationTest { assertThat(from.get(0).text()).startsWith("Timer — "); } + @Test + void anXmlFileWithAProblemIsNotSaved() throws Exception { + String xml = """ + <routes xmlns="http://camel.apache.org/schema/xml-io"> + <route> + <from uri="timer:tick?period=1000"/> + <to uri="seda:out"/> + </route> + </routes> + """; + Path file = tempDir.resolve("routes.xml"); + Files.writeString(file, xml, StandardCharsets.UTF_8); + SourceViewer viewer = new SourceViewer(); + SourceEditAssist assist = assist(); + viewer.setRouteValidator(content -> assist.validateRoutes(file, content)); + viewer.loadFile(file); + viewer.enterEditMode(); + // line 3: period=1000 becomes peroid=1000 + viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.DOWN, KeyModifiers.NONE)); + viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.DOWN, KeyModifiers.NONE)); + viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.HOME, KeyModifiers.NONE)); + int col = viewer.editText().split("\n")[2].indexOf("period") + 3; + for (int i = 0; i < col; i++) { + viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.RIGHT, KeyModifiers.NONE)); + } + viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.DELETE, KeyModifiers.NONE)); + viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.RIGHT, KeyModifiers.NONE)); + viewer.handleKeyEvent(KeyEvent.ofChar('i', KeyModifiers.NONE)); + assertThat(viewer.editText()).contains("peroid=1000"); + + // as a YAML file: the problems are shown and the file is not saved + viewer.handleKeyEvent(KeyEvent.ofChar('s', KeyModifiers.CTRL)); + assertThat(Files.readString(file, StandardCharsets.UTF_8)).contains("period=1000"); + assertThat(viewer.isEditMode()).isTrue(); + assertThat(viewer.inlineErrors()).containsOnlyKeys(2); + } + @Test void aProblemIsMarkedAndSaidButTheFileIsSaved() throws Exception { Path file = tempDir.resolve("MyRoute.java");
