This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 22a7d90 CAMEL-14938: Added file name customization method to
GroovyShellFactory for compiled classes (#3763)
22a7d90 is described below
commit 22a7d9031637ecf6baa33821a7c8422ea900ec0f
Author: Soner Köksal <[email protected]>
AuthorDate: Wed Apr 22 07:23:06 2020 +0300
CAMEL-14938: Added file name customization method to GroovyShellFactory for
compiled classes (#3763)
---
components/camel-groovy/pom.xml | 5 --
.../src/main/docs/groovy-language.adoc | 28 +++++++++--
.../camel/language/groovy/GroovyExpression.java | 30 ++++++------
.../camel/language/groovy/GroovyShellFactory.java | 4 ++
.../language/groovy/GroovyShellFactoryTest.java | 57 ++++++++++++++++------
5 files changed, 85 insertions(+), 39 deletions(-)
diff --git a/components/camel-groovy/pom.xml b/components/camel-groovy/pom.xml
index fb17d37..96e297b 100644
--- a/components/camel-groovy/pom.xml
+++ b/components/camel-groovy/pom.xml
@@ -83,10 +83,5 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
diff --git a/components/camel-groovy/src/main/docs/groovy-language.adoc
b/components/camel-groovy/src/main/docs/groovy-language.adoc
index b82ce6f..02f79a8 100644
--- a/components/camel-groovy/src/main/docs/groovy-language.adoc
+++ b/components/camel-groovy/src/main/docs/groovy-language.adoc
@@ -18,7 +18,7 @@ To use a Groovy expression use the following Java code
[source,java]
---------------------------------------
-... groovy("someGroovyExpression") ...
+... groovy("someGroovyExpression") ...
---------------------------------------
For example you could use the *groovy* function to create an
@@ -55,7 +55,7 @@ bean to your Spring context...
[source,java]
----------------------------------------------------------------------
public class CustomGroovyShellFactory implements GroovyShellFactory {
-
+
public GroovyShell createGroovyShell(Exchange exchange) {
ImportCustomizer importCustomizer = new ImportCustomizer();
importCustomizer.addStaticStars("com.example.Utils");
@@ -70,6 +70,26 @@ public class CustomGroovyShellFactory implements
GroovyShellFactory {
...Camel will use your custom GroovyShell instance (containing your
custom static imports), instead of the default one.
+=== Customizing Groovy class file name
+
+You may rarely in need of customizing generated Groovy class file name for
debugging purposes.
+This is also possible by implementing `getFileName` method.
+
+[source,java]
+----------------------------------------------------------------------
+public class CustomGroovyShellFactory implements GroovyShellFactory {
+
+ public GroovyShell createGroovyShell(Exchange exchange) {
+ return new GroovyShell();
+ }
+
+ public String getFileName(Exchange exchange) {
+ return "Foo.groovy";
+ }
+
+}
+----------------------------------------------------------------------
+
== Example
[source,java]
@@ -133,7 +153,7 @@ header on the Camel message with the key
`CamelScriptArguments`. +
If you need to use the xref:ROOT:properties-component.adoc[Properties]
component from a
script to lookup property placeholders, then its a bit cumbersome to do
-so.
+so.
For example to set a header name myHeader with a value from a property
placeholder, which key is provided in a header named "foo".
@@ -176,7 +196,7 @@ variable as the script return value.
[source,text]
-------------------------------------------------------------
bar = "baz";
-# some other statements ...
+# some other statements ...
# camel take the result value as the script evaluation result
result = body * 2 + 1
-------------------------------------------------------------
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 0681f15..8f5c84b 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
@@ -58,28 +58,26 @@ public class GroovyExpression extends ExpressionSupport {
private Script instantiateScript(Exchange exchange) {
// Get the script from the cache, or create a new instance
GroovyLanguage language = (GroovyLanguage)
exchange.getContext().resolveLanguage("groovy");
- Class<Script> scriptClass = language.getScriptFromCache(text);
+ Set<GroovyShellFactory> shellFactories =
exchange.getContext().getRegistry().findByType(GroovyShellFactory.class);
+ GroovyShellFactory shellFactory = null;
+ String fileName = null;
+ if (shellFactories.size() == 1) {
+ shellFactory = shellFactories.iterator().next();
+ fileName = shellFactory.getFileName(exchange);
+ }
+ final String key = fileName != null ? fileName + text : text;
+ Class<Script> scriptClass = language.getScriptFromCache(key);
if (scriptClass == null) {
- GroovyShell shell;
- Set<GroovyShellFactory> shellFactories =
exchange.getContext().getRegistry().findByType(GroovyShellFactory.class);
- if (shellFactories.size() > 1) {
- throw new IllegalStateException("Too many GroovyShellFactory
instances found: " + shellFactories.size());
- } else if (shellFactories.size() == 1) {
- shell =
shellFactories.iterator().next().createGroovyShell(exchange);
- } else {
- ClassLoader cl =
exchange.getContext().getApplicationContextClassLoader();
- shell = cl != null ? new GroovyShell(cl) : new GroovyShell();
- }
- scriptClass = shell.getClassLoader().parseClass(text);
- language.addScriptToCache(text, scriptClass);
+ ClassLoader cl =
exchange.getContext().getApplicationContextClassLoader();
+ GroovyShell shell = shellFactory != null ?
shellFactory.createGroovyShell(exchange) : cl != null ? new GroovyShell(cl) :
new GroovyShell();
+ scriptClass = fileName != null ?
shell.getClassLoader().parseClass(text, fileName) :
shell.getClassLoader().parseClass(text);
+ language.addScriptToCache(key, scriptClass);
}
// New instance of the script
try {
return scriptClass.newInstance();
- } catch (InstantiationException e) {
- throw new RuntimeCamelException(e);
- } catch (IllegalAccessException e) {
+ } catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeCamelException(e);
}
}
diff --git
a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyShellFactory.java
b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyShellFactory.java
index 15bddce..491ea2f 100644
---
a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyShellFactory.java
+++
b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyShellFactory.java
@@ -23,4 +23,8 @@ public interface GroovyShellFactory {
GroovyShell createGroovyShell(Exchange exchange);
+ default String getFileName(Exchange exchange) {
+ return null;
+ }
+
}
diff --git
a/components/camel-groovy/src/test/java/org/apache/camel/language/groovy/GroovyShellFactoryTest.java
b/components/camel-groovy/src/test/java/org/apache/camel/language/groovy/GroovyShellFactoryTest.java
index dfd40f6..5e09904 100644
---
a/components/camel-groovy/src/test/java/org/apache/camel/language/groovy/GroovyShellFactoryTest.java
+++
b/components/camel-groovy/src/test/java/org/apache/camel/language/groovy/GroovyShellFactoryTest.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.language.groovy;
+import java.util.Arrays;
+
import groovy.lang.GroovyShell;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
@@ -23,29 +25,56 @@ import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.support.SimpleRegistry;
import org.apache.camel.test.junit4.CamelTestSupport;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.junit.Test;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
public class GroovyShellFactoryTest extends CamelTestSupport {
@Test
- public void testExpressionReturnsTheCorrectValue() {
- // Given
- GroovyShellFactory groovyShellFactory = mock(GroovyShellFactory.class);
-
given(groovyShellFactory.createGroovyShell(any(Exchange.class))).willReturn(new
GroovyShell());
+ public void testGroovyShellFactoryWithoutFilename() {
SimpleRegistry registry = new SimpleRegistry();
- registry.bind("groovyShellFactory", groovyShellFactory);
+ registry.bind("groovyShellFactory", (GroovyShellFactory) exchange -> {
+ ImportCustomizer importCustomizer = new ImportCustomizer();
+
importCustomizer.addStaticStars("org.apache.camel.language.groovy.GroovyShellFactoryTest.Utils");
+ CompilerConfiguration configuration = new CompilerConfiguration();
+ configuration.addCompilationCustomizers(importCustomizer);
+ return new GroovyShell(configuration);
+ });
+
CamelContext camelContext = new DefaultCamelContext(registry);
- // When
- assertExpression(GroovyLanguage.groovy("exchange.in.body"), new
DefaultExchange(camelContext), null);
+ assertExpression(GroovyLanguage.groovy("dummy()"), new
DefaultExchange(camelContext), "foo");
+ }
+
+ @Test
+ public void testGroovyShellFactoryFilename() {
+ SimpleRegistry registry = new SimpleRegistry();
+ registry.bind("groovyShellFactory", new GroovyShellFactory() {
+ @Override
+ public GroovyShell createGroovyShell(Exchange exchange) {
+ return new GroovyShell();
+ }
+
+ @Override
+ public String getFileName(Exchange exchange) {
+ return exchange.getIn().getHeader("fileName", String.class);
+ }
+ });
+
+ CamelContext camelContext = new DefaultCamelContext(registry);
+
+ final DefaultExchange exchange = new DefaultExchange(camelContext);
+ exchange.getIn().setHeader("fileName", "Test.groovy");
+
+ final Exception e = GroovyLanguage.groovy("new
Exception()").evaluate(exchange, Exception.class);
+ assertTrue(Arrays.stream(e.getStackTrace()).anyMatch(stackTraceElement
-> "Test.groovy".equals(stackTraceElement.getFileName())));
+ }
- // Then
- verify(groovyShellFactory).createGroovyShell(any(Exchange.class));
+ public static class Utils {
+ public static String dummy() {
+ return "foo";
+ }
}
}