davsclaus commented on code in PR #27082:
URL: https://github.com/apache/camel/pull/27082#discussion_r4134215590


##########
dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java:
##########
@@ -95,19 +97,50 @@ public void preParseRoute(Resource resource) throws 
Exception {
         if (preparseDone.getOrDefault(resource.getLocation(), false)) {
             return;
         }
-        XmlStreamInfo xmlInfo = xmlInfo(resource);
-        if (xmlInfo.isValid()) {
-            String root = xmlInfo.getRootElementName();
-            if ("beans".equals(root) || "blueprint".equals(root) || 
"camel".equals(root)) {
-                new XmlModelParser(resource, xmlInfo.getRootElementNamespace())
-                        .parseBeansDefinition()
-                        .ifPresent(bd -> {
-                            registerBeans(resource, bd);
-                            camelAppCache.put(resource.getLocation(), bd);
-                        });
+        try {
+            XmlStreamInfo xmlInfo = xmlInfo(resource);
+            if (xmlInfo.isValid()) {
+                String root = xmlInfo.getRootElementName();
+                SemanticDefinition semantic = null;
+                if ("beans".equals(root) || "blueprint".equals(root) || 
"camel".equals(root)) {
+                    new XmlModelParser(resource, 
xmlInfo.getRootElementNamespace())
+                            .parseBeansDefinition()
+                            .ifPresent(bd -> {
+                                registerBeans(resource, bd);
+                                camelAppCache.put(resource.getLocation(), bd);
+                            });
+                    BeansDefinition app = 
camelAppCache.get(resource.getLocation());
+                    if (app != null) {
+                        semantic = app.getSemantic();
+                    }
+                } else if ("routes".equals(root) || "route".equals(root)) {
+                    RoutesDefinition routes = new 
XmlModelParser(resource(resource), xmlInfo.getRootElementNamespace())
+                            .parseRoutesDefinition().orElse(null);
+                    if (routes != null) {
+                        routesCache.put(resource.getLocation(), routes);

Review Comment:
   With this, plain `<routes>` files are now fully parsed at preparse and 
cached. `routesCache`/`preparseDone` are only cleared in `configure()` or in 
this loader's own preparse catch, so if the batch fails after this preparse 
succeeded (another loader's preparse throws, or an earlier builder fails in 
`addRoutes`), the entries stay behind and a retry with corrected content at the 
same location skips preparse and loads the old routes. The `<camel>` cache 
already had this; this extends it to the most common XML file. Clearing pending 
entries at the start of each load/update batch (or keying by content) would 
avoid it.



##########
core/camel-core-model/src/main/java/org/apache/camel/model/app/SemanticQuestionDefinition.java:
##########
@@ -0,0 +1,183 @@
+/*
+ * 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.model.app;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlElement;
+import jakarta.xml.bind.annotation.XmlType;
+
+import org.apache.camel.model.PropertyDefinition;
+import org.apache.camel.spi.Metadata;
+
+/** A semantic question with the same fields and policies as a YAML 
declaration. */
+@Metadata(label = "configuration")
+@XmlType(name = "semanticQuestionDefinition", propOrder = { "instructions", 
"criteria", "levels" })
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SemanticQuestionDefinition {
+    @XmlAttribute(required = true)
+    @Metadata(required = true, description = "The context-wide question name.")
+    private String name;
+    @XmlAttribute(required = true)
+    @Metadata(required = true, enums = "boolean,choice,score", description = 
"The question type.")
+    private String type;
+    @XmlAttribute
+    @Metadata(description = "The Simple expression selecting the message 
state.")
+    private String state;
+    @XmlAttribute
+    @Metadata(description = "The boolean decision threshold.")
+    private String threshold;
+    @XmlAttribute
+    @Metadata(description = "The boolean uncertainty band.")
+    private String uncertainty;
+    @XmlAttribute
+    @Metadata(enums = "fail,non-match", description = "The boolean uncertainty 
policy.")
+    private String uncertaintyPolicy;

Review Comment:
   `threshold` and `uncertainty` end up as `"type": "string"` in the catalog 
with no default, and `uncertaintyPolicy` has no default either, although the 
runtime defaults are 0.5, 0 and `fail`. Adding `javaType = "java.lang.Double", 
defaultValue = "0.5"` / `defaultValue = "0"` and `defaultValue = "fail"` to the 
`@Metadata` (then regenerating) lets tooling show and validate them.



##########
core/camel-java-io/src/main/java/org/apache/camel/java/out/JavaDslModelWriterSupport.java:
##########
@@ -1131,6 +1133,43 @@ protected String indent() {
         return "    ".repeat(indentLevel);
     }
 
+    public String writeSemanticDefinition(SemanticDefinition definition) {
+        StringBuilder result = new StringBuilder();
+        doWriteSemanticDefinition(result, definition);
+        return result.toString();
+    }
+
+    protected void doWriteSemanticDefinition(StringBuilder result, 
SemanticDefinition definition) {
+        for (SemanticQuestionDefinition question : definition.getQuestions()) {
+            if (!result.isEmpty()) {
+                result.append(NL);
+            }
+            
result.append("semanticQuestions().question(").append(quote(question.getName())).append(")")
+                    
.append(".type(").append(quote(question.getType())).append(")")
+                    
.append(".instructions(").append(quote(question.getInstructions())).append(")");
+            if (question.getState() != null) {
+                
result.append(".state(").append(quote(question.getState())).append(")");
+            }
+            if (question.getThreshold() != null) {
+                
result.append(".threshold(").append(Double.parseDouble(question.getThreshold())).append(")");

Review Comment:
   `Double.parseDouble` throws when the value is a property placeholder such as 
`{{threshold}}`, which makes the whole export fail (same for `uncertainty` 
below). Emitting the value as-is, or falling back to a string argument when it 
is not a literal number, would avoid that.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to