This is an automated email from the ASF dual-hosted git repository.

luigidemasi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit eb237cd22793894f9a379a9574a4590ca811b5c3
Author: Luigi De Masi <[email protected]>
AuthorDate: Tue Sep 29 14:30:32 2026 +0200

    CAMEL-25138: Fix semantic XML documentation and numeric diagnostics
    
    Use the XML IO namespace for the native XML declaration example so the
    catalog documentation schema check validates it, and regenerate its mirror.
    
    Identify threshold and uncertainty in non-numeric validation errors while
    preserving the question context and original cause. Cover both fields in
    the existing invalid-reload tests, including preservation of the previous
    definitions and recovery after corrected input. Clarify why duplicate
    discovery of the stateless default configurer is harmless.
    
    Validation: 109 semantic tests and 1082 catalog tests passed, including the
    documentation schema checks. Full 695-module clean install passed with
    tests skipped.
    
    Co-authored-by: Codex <[email protected]>
    Signed-off-by: Luigi De Masi <[email protected]>
---
 .../org/apache/camel/catalog/docs/semantic-language.adoc     |  2 +-
 .../camel-semantic/src/main/docs/semantic-language.adoc      |  2 +-
 .../camel/semantic/DefaultSemanticDefinitionConfigurer.java  | 12 ++++++++++--
 .../apache/camel/semantic/SemanticDeclarationDslTest.java    |  4 ++++
 .../java/org/apache/camel/model/app/SemanticDefinition.java  |  2 ++
 5 files changed, 18 insertions(+), 4 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
index b2dd15c021d4..c360bacb879c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
@@ -141,7 +141,7 @@ With xref:others:java-xml-io-dsl.adoc[XML DSL], place a 
`semantic` element insid
 
 [source,xml]
 ----
-<camel xmlns="http://camel.apache.org/schema/spring";>
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
   <semantic>
     <question name="department" type="choice" state="${header.myState}">
       <instructions>Which department should handle this message?</instructions>
diff --git 
a/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc 
b/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc
index b2dd15c021d4..c360bacb879c 100644
--- a/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc
+++ b/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc
@@ -141,7 +141,7 @@ With xref:others:java-xml-io-dsl.adoc[XML DSL], place a 
`semantic` element insid
 
 [source,xml]
 ----
-<camel xmlns="http://camel.apache.org/schema/spring";>
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
   <semantic>
     <question name="department" type="choice" state="${header.myState}">
       <instructions>Which department should handle this message?</instructions>
diff --git 
a/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/DefaultSemanticDefinitionConfigurer.java
 
b/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/DefaultSemanticDefinitionConfigurer.java
index 2d7b34e75374..871f378049fb 100644
--- 
a/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/DefaultSemanticDefinitionConfigurer.java
+++ 
b/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/DefaultSemanticDefinitionConfigurer.java
@@ -72,13 +72,21 @@ public class DefaultSemanticDefinitionConfigurer implements 
SemanticDefinitionCo
         return new SemanticQuestion(
                 type, definition.getInstructions(), definition.getState(), 
criteria,
                 definition.getLevels(),
-                definition.getThreshold() == null ? 0.5 : 
Double.parseDouble(definition.getThreshold()),
-                definition.getUncertainty() == null ? 0 : 
Double.parseDouble(definition.getUncertainty()),
+                definition.getThreshold() == null ? 0.5 : 
parseDouble(definition.getThreshold(), "threshold"),
+                definition.getUncertainty() == null ? 0 : 
parseDouble(definition.getUncertainty(), "uncertainty"),
                 definition.getUncertaintyPolicy() == null
                         ? SemanticQuestion.UncertaintyPolicy.FAIL
                         : enumeration(definition.getUncertaintyPolicy(), 
SemanticQuestion.UncertaintyPolicy.class));
     }
 
+    private static double parseDouble(String value, String field) {
+        try {
+            return Double.parseDouble(value);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(field + " must be a valid 
number: " + value, e);
+        }
+    }
+
     private static <T extends Enum<T>> T enumeration(String value, Class<T> 
type) {
         String normalized = StringHelper.asEnumConstantValue(value);
         for (T constant : type.getEnumConstants()) {
diff --git 
a/components/camel-ai/camel-semantic/src/test/java/org/apache/camel/semantic/SemanticDeclarationDslTest.java
 
b/components/camel-ai/camel-semantic/src/test/java/org/apache/camel/semantic/SemanticDeclarationDslTest.java
index 54bef6037643..e2b3f13a7f24 100644
--- 
a/components/camel-ai/camel-semantic/src/test/java/org/apache/camel/semantic/SemanticDeclarationDslTest.java
+++ 
b/components/camel-ai/camel-semantic/src/test/java/org/apache/camel/semantic/SemanticDeclarationDslTest.java
@@ -192,6 +192,10 @@ class SemanticDeclarationDslTest {
                         "Duplicate semantic criterion"),
                 Arguments.of(question.replace("type=\"boolean\"", 
"type=\"score\""), "score needs ordered levels"),
                 Arguments.of(question.replace("type=\"boolean\"", 
"type=\"boolean\" threshold=\"NaN\""), "within [0,1]"),
+                Arguments.of(question.replace("type=\"boolean\"", 
"type=\"boolean\" threshold=\"abc\""),
+                        "Invalid semantic question 'q': threshold must be a 
valid number: abc"),
+                Arguments.of(question.replace("type=\"boolean\"", 
"type=\"boolean\" uncertainty=\"abc\""),
+                        "Invalid semantic question 'q': uncertainty must be a 
valid number: abc"),
                 Arguments.of(question.replace("type=\"boolean\"", 
"type=\"boolean\" state=\" \""),
                         "state selector must not be blank"),
                 Arguments.of(question.replace("name=\"q\"", "unknown=\"q\""), 
"Unexpected attribute"));
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/app/SemanticDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/app/SemanticDefinition.java
index 66ae92ca2496..ac1f2f50c0dd 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/app/SemanticDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/app/SemanticDefinition.java
@@ -62,6 +62,8 @@ public class SemanticDefinition {
             if (definition == null || definition.getQuestions().isEmpty()) {
                 return;
             }
+            // Concurrent discovery may create equivalent instances of the 
stateless default configurer.
+            // The semantic module synchronizes access to shared question 
state.
             configurer = 
context.getCamelContextExtension().getDefaultFactoryFinder()
                     .newInstance("semantic-configurer", 
SemanticDefinitionConfigurer.class)
                     .orElseThrow(() -> new IllegalArgumentException(

Reply via email to