diff --git a/catalog/camel-catalog/pom.xml b/catalog/camel-catalog/pom.xml
index 5a130061c7ddc..1c4706eb2130d 100644
--- a/catalog/camel-catalog/pom.xml
+++ b/catalog/camel-catalog/pom.xml
@@ -104,6 +104,12 @@
camel-jsonpath
test
+
+
+ org.apache.camel
+ camel-groovy
+ test
+
diff --git a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index 0863b9b0848a0..2b55875059051 100644
--- a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -1126,6 +1126,23 @@ public void testValidateJSonPathLanguage() {
assertEquals("$.store.book[?(@.price < 10)]", result.getText());
}
+ @Test
+ public void testValidateGroovyLanguage() {
+ LanguageValidationResult result = catalog.validateLanguageExpression(null, "groovy", "4 * 3");
+ assertTrue(result.isSuccess());
+ assertEquals("4 * 3", result.getText());
+
+ var code = """
+ var a = 123;
+ println a */ 2;
+ """;
+ result = catalog.validateLanguageExpression(null, "groovy", code);
+ assertFalse(result.isSuccess());
+ assertEquals(code, result.getText());
+ assertEquals(23, result.getIndex());
+ assertEquals("Unexpected input: '*' @ line 2, column 11.", result.getShortError());
+ }
+
@Test
public void testSpringCamelContext() {
String xml = catalog.springSchemaAsXml();
diff --git a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyExpression.java b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyExpression.java
index b5adb8215a653..ebbe38c75d96f 100644
--- a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyExpression.java
+++ b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyExpression.java
@@ -62,7 +62,7 @@ public T evaluate(Exchange exchange, Class type) {
}
@SuppressWarnings("unchecked")
- private Script instantiateScript(Exchange exchange, Map globalVariables) {
+ protected Script instantiateScript(Exchange exchange, Map globalVariables) {
// Get the script from the cache, or create a new instance
GroovyLanguage language = (GroovyLanguage) exchange.getContext().resolveLanguage("groovy");
Set shellFactories = exchange.getContext().getRegistry().findByType(GroovyShellFactory.class);
@@ -87,7 +87,7 @@ private Script instantiateScript(Exchange exchange, Map globalVa
return ObjectHelper.newInstance(scriptClass, Script.class);
}
- private Binding createBinding(Exchange exchange, Map globalVariables) {
+ protected Binding createBinding(Exchange exchange, Map globalVariables) {
Map map = new HashMap<>(globalVariables);
ExchangeHelper.populateVariableMap(exchange, map, true);
map.put("log", LOG);
diff --git a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
index 3a170b24f8ebf..a03145305ffaa 100644
--- a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
+++ b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
@@ -23,11 +23,13 @@
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
+import org.apache.camel.Exchange;
import org.apache.camel.Service;
import org.apache.camel.spi.CamelEvent;
import org.apache.camel.spi.EventNotifier;
import org.apache.camel.spi.ScriptingLanguage;
import org.apache.camel.spi.annotations.Language;
+import org.apache.camel.support.DefaultExchange;
import org.apache.camel.support.LRUCacheFactory;
import org.apache.camel.support.ObjectHelper;
import org.apache.camel.support.SimpleEventNotifierSupport;
@@ -156,6 +158,27 @@ public T evaluate(String script, Map bindings, Class resu
return getCamelContext().getTypeConverter().convertTo(resultType, value);
}
+ // use by tooling
+ public boolean validateExpression(String expression) throws GroovyValidationException {
+ final Exchange dummy = new DefaultExchange(getCamelContext());
+ Map globalVariables = new HashMap<>();
+
+ try {
+ GroovyExpression ge = createExpression(expression);
+ Script script = ge.instantiateScript(dummy, globalVariables);
+ script.setBinding(ge.createBinding(dummy, globalVariables));
+ script.run();
+ } catch (Exception e) {
+ throw new GroovyValidationException(expression, e);
+ }
+ return true;
+ }
+
+ // use by tooling
+ public boolean validatePredicate(String expression) throws GroovyValidationException {
+ return validateExpression(expression);
+ }
+
Class