This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 3269ef15a999 CAMEL-25748: camel-yaml-dsl-validator - the hint for a
script file under groovy: resource: keeps the resource: prefix (#28046)
3269ef15a999 is described below
commit 3269ef15a9998f495c2bad4d39981a888391bff4
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Oct 18 18:04:44 2026 +0200
CAMEL-25748: camel-yaml-dsl-validator - the hint for a script file under
groovy: resource: keeps the resource: prefix (#28046)
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
---
.../camel/dsl/yaml/validator/SchemaHints.java | 24 +++++++++++++--
.../QuotingAndOptionPlacementHintTest.java | 35 ++++++++++++++++++++++
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/SchemaHints.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/SchemaHints.java
index 3254ac7cf905..d8ad480acf0a 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/SchemaHints.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/SchemaHints.java
@@ -128,6 +128,27 @@ final class SchemaHints {
return instance.get(key).isNull() ? "{" + key + "}" : null;
}
+ /** A value that names a script file by its scheme, as resource: loads it.
*/
+ private static final Pattern SCRIPT_FILE =
Pattern.compile("(file|classpath|https?):.+", Pattern.DOTALL);
+
+ /**
+ * Where the text of a language goes, for the text written under another
key (groovy: {script: "..."}). A script
+ * file under resource: (groovy: {resource: "file:x.groovy"}) is loaded
with the resource: prefix, which the value
+ * often lacks (CAMEL-25748): the expression "file:x.groovy" would run as
code.
+ */
+ static String languageTextHint(String language, String property, String
value) {
+ String key = property.toLowerCase(Locale.ROOT);
+ String text = value.strip();
+ boolean scriptFile = !text.startsWith("resource:")
+ && (key.contains("resource") || (key.startsWith("script") &&
SCRIPT_FILE.matcher(text).matches()));
+ if (scriptFile) {
+ return "a " + language + " script file is loaded in expression:
with the resource: prefix, write " + language
+ + ": {expression: \"resource:" + text.replace("\"", "\\\"")
+ "\"}";
+ }
+ return "the " + language + " text goes in expression:, write " +
language + ": {expression: \""
+ + value.replace("\"", "\\\"") + "\"}";
+ }
+
/** The text of a scalar property of the error's node, or the fallback
when it is not a scalar. */
private static String valueOf(Match m, String property, String fallback) {
JsonNode instance = m.error().getInstanceNode();
@@ -596,8 +617,7 @@ final class SchemaHints {
&& m.error().getInstanceNode() != null
&& !m.error().getInstanceNode().has("expression")
&&
m.error().getInstanceNode().path(m.unknown()).isTextual(),
- m -> "the " + m.name() + " text goes in expression:, write
" + m.name() + ": {expression: \""
- + valueOf(m, m.unknown(), "...").replace("\"",
"\\\"") + "\"}"),
+ m -> languageTextHint(m.name(), m.unknown(), valueOf(m,
m.unknown(), "..."))),
unknownProperty(null,
m -> YamlValidator.closest(m.unknown(),
m.validator().knownProperties(m.schemaLocation())) != null,
m -> "did you mean '"
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/QuotingAndOptionPlacementHintTest.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/QuotingAndOptionPlacementHintTest.java
index bb401243e07c..5560ee7dc377 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/QuotingAndOptionPlacementHintTest.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/QuotingAndOptionPlacementHintTest.java
@@ -151,6 +151,41 @@ public class QuotingAndOptionPlacementHintTest {
.contains("the simple text goes in expression:, write simple:
{expression: \"${body} != null\"}"));
}
+ /** CAMEL-25748: a script file is loaded with the resource: prefix, which
the value under resource: often lacks. */
+ @Test
+ public void aScriptFileUnderAnotherKey() {
+ String yaml = """
+ - route:
+ from:
+ uri: timer:x
+ steps:
+ - setBody:
+ expression:
+ groovy:
+ resource: "file:shipment-mapping.groovy"
+ - setHeader:
+ name: sku
+ expression:
+ groovy:
+ script: "classpath:sku.groovy"
+ - setHeader:
+ name: qty
+ expression:
+ groovy:
+ resourceUri: "resource:file:qty.groovy"
+ """;
+ List<String> lines = lines(yaml);
+ assertThat(lines).anySatisfy(m -> assertThat(m)
+ .contains("a groovy script file is loaded in expression: with
the resource: prefix,"
+ + " write groovy: {expression:
\"resource:file:shipment-mapping.groovy\"}"));
+ assertThat(lines).anySatisfy(m -> assertThat(m)
+ .contains("write groovy: {expression:
\"resource:classpath:sku.groovy\"}"));
+ // a value that has the prefix keeps it once
+ assertThat(lines).anySatisfy(m -> assertThat(m)
+ .contains("write groovy: {expression:
\"resource:file:qty.groovy\"}"));
+ assertThat(lines).noneSatisfy(m ->
assertThat(m).contains("resource:resource:"));
+ }
+
private static List<String> lines(String yaml) {
try {
return YamlValidator.describeAll(yaml, validator.validate(yaml));