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");

Reply via email to