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

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

commit 318d9a0ca66557541f9b43b3fbb460037594ae92
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jun 26 11:32:30 2025 +0200

    CAMEL-22200: components that are resource endpoint based should have 
content cache true as default and make it configurable on component level.
---
 .../language/LanguageComponentConfigurer.java      | 12 ++++++
 .../language/LanguageEndpointConfigurer.java       |  6 +++
 .../language/LanguageEndpointUriFactory.java       |  3 +-
 .../apache/camel/component/language/language.json  | 23 +++++-----
 .../component/language/LanguageComponent.java      | 33 ++++++++++++++
 .../camel/component/language/LanguageEndpoint.java | 35 +++++++++------
 .../camel/component/language/LanguageProducer.java | 19 ++++----
 .../language/LanguageEndpointScriptRouteTest.java  | 50 ----------------------
 .../LanguageLoadScriptFromClasspathHeaderTest.java |  2 +-
 ...guageScriptInHeaderRouteTakePrecedenceTest.java |  2 +-
 .../language/LanguageScriptInHeaderRouteTest.java  |  2 +-
 .../camel/language/XPathLanguageEndpointTest.java  |  2 +-
 .../ROOT/pages/camel-4x-upgrade-guide-4_13.adoc    |  4 ++
 13 files changed, 107 insertions(+), 86 deletions(-)

diff --git 
a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageComponentConfigurer.java
 
b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageComponentConfigurer.java
index 7402138bdab..a714c312ed0 100644
--- 
a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageComponentConfigurer.java
+++ 
b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageComponentConfigurer.java
@@ -23,8 +23,12 @@ public class LanguageComponentConfigurer extends 
PropertyConfigurerSupport imple
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         LanguageComponent target = (LanguageComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": 
target.setAllowTemplateFromHeader(property(camelContext, boolean.class, 
value)); return true;
         case "autowiredenabled":
         case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
+        case "contentcache":
+        case "contentCache": target.setContentCache(property(camelContext, 
boolean.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         default: return false;
@@ -34,8 +38,12 @@ public class LanguageComponentConfigurer extends 
PropertyConfigurerSupport imple
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return boolean.class;
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
+        case "contentcache":
+        case "contentCache": return boolean.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         default: return null;
@@ -46,8 +54,12 @@ public class LanguageComponentConfigurer extends 
PropertyConfigurerSupport imple
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         LanguageComponent target = (LanguageComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return 
target.isAllowTemplateFromHeader();
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "contentcache":
+        case "contentCache": return target.isContentCache();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         default: return null;
diff --git 
a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java
 
b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java
index 02609ce57c9..21c7f866be0 100644
--- 
a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java
+++ 
b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java
@@ -25,6 +25,8 @@ public class LanguageEndpointConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowcontextmapall":
         case "allowContextMapAll": 
target.setAllowContextMapAll(property(camelContext, boolean.class, value)); 
return true;
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": 
target.setAllowTemplateFromHeader(property(camelContext, boolean.class, 
value)); return true;
         case "binary": target.setBinary(property(camelContext, boolean.class, 
value)); return true;
         case "cachescript":
         case "cacheScript": target.setCacheScript(property(camelContext, 
boolean.class, value)); return true;
@@ -45,6 +47,8 @@ public class LanguageEndpointConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowcontextmapall":
         case "allowContextMapAll": return boolean.class;
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return boolean.class;
         case "binary": return boolean.class;
         case "cachescript":
         case "cacheScript": return boolean.class;
@@ -66,6 +70,8 @@ public class LanguageEndpointConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowcontextmapall":
         case "allowContextMapAll": return target.isAllowContextMapAll();
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return 
target.isAllowTemplateFromHeader();
         case "binary": return target.isBinary();
         case "cachescript":
         case "cacheScript": return target.isCacheScript();
diff --git 
a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java
 
b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java
index 4fc34404333..8c57a5745af 100644
--- 
a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java
+++ 
b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java
@@ -23,8 +23,9 @@ public class LanguageEndpointUriFactory extends 
org.apache.camel.support.compone
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(10);
+        Set<String> props = new HashSet<>(11);
         props.add("allowContextMapAll");
+        props.add("allowTemplateFromHeader");
         props.add("binary");
         props.add("cacheScript");
         props.add("contentCache");
diff --git 
a/components/camel-language/src/generated/resources/META-INF/org/apache/camel/component/language/language.json
 
b/components/camel-language/src/generated/resources/META-INF/org/apache/camel/component/language/language.json
index 41dfb7220d8..3358f330517 100644
--- 
a/components/camel-language/src/generated/resources/META-INF/org/apache/camel/component/language/language.json
+++ 
b/components/camel-language/src/generated/resources/META-INF/org/apache/camel/component/language/language.json
@@ -24,22 +24,25 @@
     "remote": false
   },
   "componentProperties": {
-    "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "allowTemplateFromHeader": { "index": 0, "kind": "property", 
"displayName": "Allow Template From Header", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Whether to allow to use resource template from header or not 
(default false). Enabling this allows to specify dynamic templates via message 
header. However this can be seen as a potential se [...]
+    "contentCache": { "index": 1, "kind": "property", "displayName": "Content 
Cache", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": true, "description": "Sets whether to use resource 
content cache or not" },
+    "lazyStartProducer": { "index": 2, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
+    "autowiredEnabled": { "index": 3, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
   "headers": {
     "CamelLanguageScript": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String or 
Expression", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The script to execute provided in the header. 
Takes precedence over script configured on the endpoint.", "constantName": 
"org.apache.camel.component.language.LanguageConstants#LANGUAGE_SCRIPT" }
   },
   "properties": {
-    "languageName": { "index": 0, "kind": "path", "displayName": "Language 
Name", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "enum": [ "bean", "constant", "csimple", 
"datasonnet", "exchangeProperty", "file", "groovy", "header", "hl7terser", 
"java", "joor", "jq", "jsonpath", "mvel", "ognl", "ref", "simple", "spel", 
"sql", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, 
"deprecationNote": "", "autowired": false,  [...]
+    "languageName": { "index": 0, "kind": "path", "displayName": "Language 
Name", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "enum": [ "bean", "constant", "csimple", 
"datasonnet", "exchangeProperty", "file", "groovy", "header", "hl7terser", 
"java", "joor", "jq", "js", "jsonpath", "mvel", "ognl", "python", "ref", 
"simple", "spel", "tokenize", "variable", "wasm", "xpath", "xquery", 
"xtokenize" ], "deprecated": false, "deprecationNo [...]
     "resourceUri": { "index": 1, "kind": "path", "displayName": "Resource 
Uri", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"description": "Path to the resource, or a reference to lookup a bean in the 
Registry to use as the resource" },
     "allowContextMapAll": { "index": 2, "kind": "parameter", "displayName": 
"Allow Context Map All", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Sets whether the 
context map should allow access to all details. By default only the message 
body and headers can be accessed. This option can be enabled for full access to 
the current Exchange and C [...]
-    "binary": { "index": 3, "kind": "parameter", "displayName": "Binary", 
"group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "description": "Whether the script is binary 
content or text content. By default the script is read as text content (eg 
java.lang.String)" },
-    "cacheScript": { "index": 4, "kind": "parameter", "displayName": "Cache 
Script", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to cache the 
compiled script and reuse Notice reusing the script can cause side effects from 
processing one Camel org.apache.camel.Exchange to the next 
org.apache.camel.Exchange." },
-    "contentCache": { "index": 5, "kind": "parameter", "displayName": "Content 
Cache", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": true, "description": "Sets whether to use resource 
content cache or not" },
-    "resultType": { "index": 6, "kind": "parameter", "displayName": "Result 
Type", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the class of the result type (type from 
output)" },
-    "script": { "index": 7, "kind": "parameter", "displayName": "Script", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the script to execute" },
-    "transform": { "index": 8, "kind": "parameter", "displayName": 
"Transform", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether or not the 
result of the script should be used as message body. This options is default 
true." },
-    "lazyStartProducer": { "index": 9, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "allowTemplateFromHeader": { "index": 3, "kind": "parameter", 
"displayName": "Allow Template From Header", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Whether to allow to use resource template from header or not 
(default false). Enabling this allows to specify dynamic templates via message 
header. However this can be seen as a potential s [...]
+    "contentCache": { "index": 4, "kind": "parameter", "displayName": "Content 
Cache", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": true, "description": "Sets whether to use resource 
content cache or not" },
+    "resultType": { "index": 5, "kind": "parameter", "displayName": "Result 
Type", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the class of the result type (type from 
output)" },
+    "script": { "index": 6, "kind": "parameter", "displayName": "Script", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the script to execute" },
+    "transform": { "index": 7, "kind": "parameter", "displayName": 
"Transform", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether or not the 
result of the script should be used as message body. This options is default 
true." },
+    "lazyStartProducer": { "index": 8, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "binary": { "index": 9, "kind": "parameter", "displayName": "Binary", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "description": "Whether the script is binary 
content or text content. By default the script is read as text content (eg 
java.lang.String)" },
+    "cacheScript": { "index": 10, "kind": "parameter", "displayName": "Cache 
Script", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to cache the 
compiled script and reuse Notice reusing the script can cause side effects from 
processing one Camel org.apache.camel.Exchange to the next 
org.apache.camel.Exchange." }
   }
 }
diff --git 
a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageComponent.java
 
b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageComponent.java
index a8258df04bc..969f64acfab 100644
--- 
a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageComponent.java
+++ 
b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageComponent.java
@@ -22,6 +22,7 @@ import java.util.Map;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.spi.Language;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultComponent;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
@@ -35,6 +36,11 @@ public class LanguageComponent extends DefaultComponent {
 
     public static final String RESOURCE = "resource:";
 
+    @Metadata(defaultValue = "true", description = "Sets whether to use 
resource content cache or not")
+    private boolean contentCache;
+    @Metadata(defaultValue = "false")
+    private boolean allowTemplateFromHeader;
+
     public LanguageComponent() {
     }
 
@@ -75,8 +81,35 @@ public class LanguageComponent extends DefaultComponent {
 
         LanguageEndpoint endpoint = new LanguageEndpoint(uri, this, language, 
null, resourceUri);
         endpoint.setScript(script);
+        endpoint.setAllowTemplateFromHeader(allowTemplateFromHeader);
+        endpoint.setContentCache(contentCache);
         setProperties(endpoint, parameters);
         return endpoint;
     }
 
+    public boolean isContentCache() {
+        return contentCache;
+    }
+
+    /**
+     * Sets whether to use resource content cache or not
+     */
+    public void setContentCache(boolean contentCache) {
+        this.contentCache = contentCache;
+    }
+
+    public boolean isAllowTemplateFromHeader() {
+        return allowTemplateFromHeader;
+    }
+
+    /**
+     * Whether to allow to use resource template from header or not (default 
false).
+     *
+     * Enabling this allows to specify dynamic templates via message header. 
However this can be seen as a potential
+     * security vulnerability if the header is coming from a malicious user, 
so use this with care.
+     */
+    public void setAllowTemplateFromHeader(boolean allowTemplateFromHeader) {
+        this.allowTemplateFromHeader = allowTemplateFromHeader;
+    }
+
 }
diff --git 
a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
 
b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
index 90c6d25a91d..d92116d0a03 100644
--- 
a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
+++ 
b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
@@ -50,11 +50,13 @@ import org.apache.camel.util.IOHelper;
              remote = false, producerOnly = true, category = { Category.CORE, 
Category.SCRIPT },
              headersClass = LanguageConstants.class)
 public class LanguageEndpoint extends ResourceEndpoint {
+
     private Language language;
     private Expression expression;
     private boolean contentResolvedFromResource;
-    @UriPath(enums = 
"bean,constant,csimple,datasonnet,exchangeProperty,file,groovy,header,hl7terser,java,joor,jq,jsonpath"
-                     + 
",mvel,ognl,ref,simple,spel,sql,tokenize,xpath,xquery,xtokenize")
+
+    @UriPath(enums = 
"bean,constant,csimple,datasonnet,exchangeProperty,file,groovy,header,hl7terser,java,joor,jq,js,jsonpath"
+                     + 
",mvel,ognl,python,ref,simple,spel,tokenize,variable,wasm,xpath,xquery,xtokenize")
     @Metadata(required = true)
     private String languageName;
     // resourceUri is optional in the language endpoint
@@ -65,28 +67,21 @@ public class LanguageEndpoint extends ResourceEndpoint {
     private String script;
     @UriParam(defaultValue = "true")
     private boolean transform = true;
-    @UriParam
+    @UriParam(label = "advanced")
     private boolean binary;
-    @UriParam
+    @UriParam(label = "advanced")
     private boolean cacheScript;
-    @UriParam(defaultValue = "true", description = "Sets whether to use 
resource content cache or not")
-    private boolean contentCache;
+    @UriParam(defaultValue = "false")
+    private boolean allowTemplateFromHeader;
     @UriParam
     private String resultType;
     private volatile Class<?> resultTypeClass;
 
-    public LanguageEndpoint() {
-        // enable cache by default
-        setContentCache(true);
-    }
-
     public LanguageEndpoint(String endpointUri, Component component, Language 
language, Expression expression,
                             String resourceUri) {
         super(endpointUri, component, resourceUri);
         this.language = language;
         this.expression = expression;
-        // enable cache by default
-        setContentCache(true);
     }
 
     @Override
@@ -266,6 +261,20 @@ public class LanguageEndpoint extends ResourceEndpoint {
         this.cacheScript = cacheScript;
     }
 
+    public boolean isAllowTemplateFromHeader() {
+        return allowTemplateFromHeader;
+    }
+
+    /**
+     * Whether to allow to use resource template from header or not (default 
false).
+     *
+     * Enabling this allows to specify dynamic templates via message header. 
However this can be seen as a potential
+     * security vulnerability if the header is coming from a malicious user, 
so use this with care.
+     */
+    public void setAllowTemplateFromHeader(boolean allowTemplateFromHeader) {
+        this.allowTemplateFromHeader = allowTemplateFromHeader;
+    }
+
     public String getResultType() {
         return resultType;
     }
diff --git 
a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java
 
b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java
index 1be8a01cfad..fb478bbec88 100644
--- 
a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java
+++ 
b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java
@@ -47,14 +47,17 @@ public class LanguageProducer extends DefaultProducer {
         String script = null;
 
         // is there a custom expression in the header?
-        Expression exp = 
exchange.getIn().getHeader(LanguageConstants.LANGUAGE_SCRIPT, Expression.class);
-        if (exp == null) {
-            script = 
exchange.getIn().getHeader(LanguageConstants.LANGUAGE_SCRIPT, String.class);
-            if (script != null) {
-                // the script may be a file: so resolve it before using
-                script = getEndpoint().resolveScript(script);
-                exp = getEndpoint().getLanguage().createExpression(script);
-                exp.init(getEndpoint().getCamelContext());
+        Expression exp = null;
+        if (getEndpoint().isAllowTemplateFromHeader()) {
+            exp = 
exchange.getIn().getHeader(LanguageConstants.LANGUAGE_SCRIPT, Expression.class);
+            if (exp == null) {
+                script = 
exchange.getIn().getHeader(LanguageConstants.LANGUAGE_SCRIPT, String.class);
+                if (script != null) {
+                    // the script may be a file: so resolve it before using
+                    script = getEndpoint().resolveScript(script);
+                    exp = getEndpoint().getLanguage().createExpression(script);
+                    exp.init(getEndpoint().getCamelContext());
+                }
             }
         }
         // if not fallback to use expression from endpoint
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageEndpointScriptRouteTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageEndpointScriptRouteTest.java
deleted file mode 100644
index 32be849484e..00000000000
--- 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageEndpointScriptRouteTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.component.language;
-
-import org.apache.camel.ContextTestSupport;
-import org.apache.camel.builder.RouteBuilder;
-import org.junit.jupiter.api.Test;
-
-public class LanguageEndpointScriptRouteTest extends ContextTestSupport {
-
-    @Test
-    public void testLanguage() throws Exception {
-        getMockEndpoint("mock:result").expectedBodiesReceived("Hello World");
-
-        template.sendBody("direct:start", "World");
-
-        assertMockEndpointsSatisfied();
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() {
-        return new RouteBuilder() {
-            @Override
-            public void configure() {
-                // START SNIPPET: e1
-                LanguageEndpoint le = new LanguageEndpoint();
-                le.setCamelContext(context);
-                le.setLanguageName("simple");
-                le.setScript("Hello ${body}");
-
-                from("direct:start").to(le).to("mock:result");
-                // END SNIPPET: e1
-            }
-        };
-    }
-}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java
index aef441d11cf..6d291baedfb 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java
@@ -38,7 +38,7 @@ public class LanguageLoadScriptFromClasspathHeaderTest 
extends ContextTestSuppor
         return new RouteBuilder() {
             @Override
             public void configure() {
-                from("direct:start").to("language:simple").to("mock:result");
+                
from("direct:start").to("language:simple?allowTemplateFromHeader=true").to("mock:result");
             }
         };
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTakePrecedenceTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTakePrecedenceTest.java
index 5190eb310d7..634d5b6d011 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTakePrecedenceTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTakePrecedenceTest.java
@@ -50,7 +50,7 @@ public class LanguageScriptInHeaderRouteTakePrecedenceTest 
extends ContextTestSu
             @Override
             public void configure() {
                 String script = URLEncoder.encode("Bye ${body}", 
StandardCharsets.UTF_8);
-                from("direct:start").to("language:simple:" + 
script).to("mock:result");
+                from("direct:start").to("language:simple:" + script + 
"?allowTemplateFromHeader=true").to("mock:result");
             }
         };
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTest.java
index 75a288a6da8..8943123f191 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptInHeaderRouteTest.java
@@ -37,7 +37,7 @@ public class LanguageScriptInHeaderRouteTest extends 
ContextTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() {
-                from("direct:start").to("language:simple").to("mock:result");
+                
from("direct:start").to("language:simple?allowTemplateFromHeader=true").to("mock:result");
             }
         };
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/XPathLanguageEndpointTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/XPathLanguageEndpointTest.java
index 084d4ceaa32..525f030acc4 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/language/XPathLanguageEndpointTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/XPathLanguageEndpointTest.java
@@ -53,7 +53,7 @@ public class XPathLanguageEndpointTest extends 
ContextTestSupport {
             public void configure() {
                 from("direct:start")
                         .setHeader(Exchange.LANGUAGE_SCRIPT, 
constant("/foo/text()"))
-                        .to("language:xpath")
+                        .to("language:xpath?allowTemplateFromHeader=true")
                         .to("mock:result");
             }
         };
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_13.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_13.adoc
index 2117fbffc9a..e5cc7c29a09 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_13.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_13.adoc
@@ -44,6 +44,10 @@ and you would have to restart the route to attempt again.
 
 Renamed class 
`org.apache.camel.component.http.BasicAuthenticationHttpClientConfigurer` to 
`org.apache.camel.component.http.DefaultAuthenticationHttpClientConfigurer`.
 
+=== camel-language
+
+If using a header to provide a custom script, then this must now be turned on 
via `allowTemplateFromHeader=true` on the endpoint or component.
+
 === camel-yaml-dsl
 
 The deprecated kebab-case has been removed.

Reply via email to