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