You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/11/06 16:24:25 UTC

svn commit: r1198392 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/component/ main/java/org/apache/camel/component/language/ main/java/org/apache/camel/util/ test/java/org/apache/camel/component/language/ test/resources/org/apache/camel/...

Author: davsclaus
Date: Sun Nov  6 15:24:24 2011
New Revision: 1198392

URL: http://svn.apache.org/viewvc?rev=1198392&view=rev
Log:
CAMEL-4627: Language component can now load scripts from classpath or file system. And it has content cache.

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathTest.java
      - copied, changed from r1198148, camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptRouteTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileUpdateTest.java
    camel/trunk/camel-core/src/test/resources/org/apache/camel/component/language/
    camel/trunk/camel-core/src/test/resources/org/apache/camel/component/language/mysimplescript.txt
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/ResourceEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/ResourceEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/ResourceEndpoint.java?rev=1198392&r1=1198391&r2=1198392&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/ResourceEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/ResourceEndpoint.java Sun Nov  6 15:24:24 2011
@@ -75,7 +75,18 @@ public abstract class ResourceEndpoint e
     }
 
     protected InputStream getResourceAsInputStreamWithoutCache() throws IOException {
-        return ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext().getClassResolver(), resourceUri);
+        return loadResource(resourceUri);
+    }
+
+    /**
+     * Loads the given resource.
+     *
+     * @param uri uri of the resource.
+     * @return the loaded resource
+     * @throws IOException is thrown if resource is not found or cannot be loaded
+     */
+    protected InputStream loadResource(String uri) throws IOException {
+        return ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext().getClassResolver(), uri);
     }
 
     public boolean isContentCache() {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java?rev=1198392&r1=1198391&r2=1198392&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageComponent.java Sun Nov  6 15:24:24 2011
@@ -24,6 +24,7 @@ import org.apache.camel.Expression;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.Language;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ResourceHelper;
 
 /**
  * The <a href="http://camel.apache.org/language-component.html">language component</a> to send
@@ -47,10 +48,17 @@ public class LanguageComponent extends D
         Language language = getCamelContext().resolveLanguage(name);
 
         Expression expression = null;
-        if (ObjectHelper.isNotEmpty(script)) {
-            expression = language.createExpression(URLDecoder.decode(script, "UTF-8"));
+        String resourceUri = null;
+        if (script != null) {
+            if (ResourceHelper.hasScheme(script)) {
+                // the script is a uri for a resource
+                resourceUri = script;
+            } else {
+                // the script is provided as text in the uri, so decode to utf-8
+                expression = language.createExpression(URLDecoder.decode(script, "UTF-8"));
+            }
         }
 
-        return new LanguageEndpoint(uri, this, language, expression);
+        return new LanguageEndpoint(uri, this, language, expression, resourceUri);
     }
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java?rev=1198392&r1=1198391&r2=1198392&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java Sun Nov  6 15:24:24 2011
@@ -16,7 +16,10 @@
  */
 package org.apache.camel.component.language;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 
 import org.apache.camel.Component;
@@ -25,16 +28,18 @@ import org.apache.camel.Expression;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.component.ResourceEndpoint;
 import org.apache.camel.spi.Language;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ResourceHelper;
 
 /**
  * Language endpoint.
  *
  * @version 
  */
-public class LanguageEndpoint extends DefaultEndpoint {
+public class LanguageEndpoint extends ResourceEndpoint {
     private Language language;
     private Expression expression;
     private String languageName;
@@ -44,8 +49,8 @@ public class LanguageEndpoint extends De
     public LanguageEndpoint() {
     }
 
-    public LanguageEndpoint(String endpointUri, Component component, Language language, Expression expression) {
-        super(endpointUri, component);
+    public LanguageEndpoint(String endpointUri, Component component, Language language, Expression expression, String resourceUri) {
+        super(endpointUri, component, resourceUri);
         this.language = language;
         this.expression = expression;
     }
@@ -59,6 +64,7 @@ public class LanguageEndpoint extends De
 
         ObjectHelper.notNull(language, "language", this);
         if (expression == null && script != null) {
+            script = resolveScript(script);
             expression = language.createExpression(script);
         }
 
@@ -69,6 +75,26 @@ public class LanguageEndpoint extends De
         throw new RuntimeCamelException("Cannot consume to a LanguageEndpoint: " + getEndpointUri());
     }
 
+    /**
+     * Resolves the script.
+     *
+     * @param script script or uri for a script to load
+     * @return the script
+     * @throws IOException is thrown if error loading the script
+     */
+    protected String resolveScript(String script) throws IOException {
+        String answer;
+        if (ResourceHelper.hasScheme(script)) {
+            InputStream is = loadResource(script);
+            answer = getCamelContext().getTypeConverter().convertTo(String.class, is);
+            IOHelper.close(is);
+        } else {
+            answer = script;
+        }
+
+        return answer;
+    }
+
     public boolean isSingleton() {
         return true;
     }
@@ -92,6 +118,10 @@ public class LanguageEndpoint extends De
         return expression;
     }
 
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+
     public boolean isTransform() {
         return transform;
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java?rev=1198392&r1=1198391&r2=1198392&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/language/LanguageProducer.java Sun Nov  6 15:24:24 2011
@@ -16,9 +16,13 @@
  */
 package org.apache.camel.component.language;
 
+import java.io.InputStream;
+
+import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.impl.DefaultProducer;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 
 /**
@@ -38,6 +42,8 @@ public class LanguageProducer extends De
         if (exp == null) {
             String script = exchange.getIn().getHeader(Exchange.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);
             }
         }
@@ -46,6 +52,29 @@ public class LanguageProducer extends De
             exp = getEndpoint().getExpression();
         }
 
+        // fallback and use resource uri from endpoint
+        if (exp == null) {
+            if (getEndpoint().getResourceUri() != null) {
+                // load the resource
+                String script;
+                InputStream is = getEndpoint().getResourceAsInputStream();
+                try {
+                    script = getEndpoint().getCamelContext().getTypeConverter().convertTo(String.class, is);
+                } finally {
+                    IOHelper.close(is);
+                }
+                // create the expression from the script
+                exp = getEndpoint().getLanguage().createExpression(script);
+                // if we cache then set this as expression on endpoint so we don't re-create it again
+                if (getEndpoint().isContentCache()) {
+                    getEndpoint().setExpression(exp);
+                }
+            } else {
+                // no script to execute
+                throw new CamelExchangeException("No script to evaluate", exchange);
+            }
+        }
+
         ObjectHelper.notNull(exp, "expression");
 
         Object result = exp.evaluate(exchange, Object.class);

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java?rev=1198392&r1=1198391&r2=1198392&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java Sun Nov  6 15:24:24 2011
@@ -38,6 +38,20 @@ public final class ResourceHelper {
     }
 
     /**
+     * Determines whether the uri has a scheme (eg file:, classpath: or http:)
+     *
+     * @param uri the uri
+     * @return <tt>true</tt> if the uri starts with a scheme
+     */
+    public static boolean hasScheme(String uri) {
+        if (uri == null) {
+            return false;
+        }
+
+        return uri.startsWith("file:") || uri.startsWith("classpath:") || uri.startsWith("http:");
+    }
+
+    /**
      * Resolves the mandatory resource.
      * <p/>
      * If possible prefer to use {@link #resolveMandatoryResourceAsUrl(org.apache.camel.spi.ClassResolver, String)}

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java?rev=1198392&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathHeaderTest.java Sun Nov  6 15:24:24 2011
@@ -0,0 +1,48 @@
+/**
+ * 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.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class LanguageLoadScriptFromClasspathHeaderTest extends ContextTestSupport {
+
+    public void testLanguage() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Hello World");
+
+        template.sendBodyAndHeader("direct:start", "World",
+                Exchange.LANGUAGE_SCRIPT, "classpath:org/apache/camel/component/language/mysimplescript.txt");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .to("language:simple")
+                    .to("mock:result");
+            }
+        };
+    }
+}

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathTest.java (from r1198148, camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptRouteTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptRouteTest.java&r1=1198148&r2=1198392&rev=1198392&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageScriptRouteTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromClasspathTest.java Sun Nov  6 15:24:24 2011
@@ -18,12 +18,11 @@ package org.apache.camel.component.langu
 
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.impl.JndiRegistry;
 
 /**
  * @version 
  */
-public class LanguageScriptRouteTest extends ContextTestSupport {
+public class LanguageLoadScriptFromClasspathTest extends ContextTestSupport {
 
     public void testLanguage() throws Exception {
         getMockEndpoint("mock:result").expectedBodiesReceived("Hello World");
@@ -34,19 +33,15 @@ public class LanguageScriptRouteTest ext
     }
 
     @Override
-    protected JndiRegistry createRegistry() throws Exception {
-        JndiRegistry jndi = super.createRegistry();
-        jndi.bind("myScript", "Hello ${body}");
-        return jndi;
-    }
-
-    @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
                 // START SNIPPET: e1
-                from("direct:start").to("language:simple?script=#myScript").to("mock:result");
+                from("direct:start")
+                    // load the script from the classpath
+                    .to("language:simple:classpath:org/apache/camel/component/language/mysimplescript.txt")
+                    .to("mock:result");
                 // END SNIPPET: e1
             }
         };

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java?rev=1198392&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileCachedTest.java Sun Nov  6 15:24:24 2011
@@ -0,0 +1,60 @@
+/**
+ * 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.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class LanguageLoadScriptFromFileCachedTest extends ContextTestSupport {
+
+    @Override
+    protected void setUp() throws Exception {
+        deleteDirectory("target/script");
+        super.setUp();
+    }
+
+    public void testLanguage() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Hello World", "Hello World");
+
+        template.sendBody("direct:start", "World");
+
+        // even if we update the file the content is cached
+        template.sendBodyAndHeader("file:target/script", "Bye ${body}", Exchange.FILE_NAME, "myscript.txt");
+        template.sendBody("direct:start", "World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // create script to start with
+                template.sendBodyAndHeader("file:target/script", "Hello ${body}", Exchange.FILE_NAME, "myscript.txt");
+
+                from("direct:start")
+                    .to("language:simple:file:target/script/myscript.txt?contentCache=true")
+                    .to("mock:result");
+            }
+        };
+    }
+}

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileUpdateTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileUpdateTest.java?rev=1198392&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileUpdateTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/language/LanguageLoadScriptFromFileUpdateTest.java Sun Nov  6 15:24:24 2011
@@ -0,0 +1,62 @@
+/**
+ * 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.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class LanguageLoadScriptFromFileUpdateTest extends ContextTestSupport {
+
+    @Override
+    protected void setUp() throws Exception {
+        deleteDirectory("target/script");
+        super.setUp();
+    }
+
+    public void testLanguage() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Hello World", "Bye World");
+
+        template.sendBody("direct:start", "World");
+
+        template.sendBodyAndHeader("file:target/script", "Bye ${body}", Exchange.FILE_NAME, "myscript.txt");
+        template.sendBody("direct:start", "World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // create script to start with
+                template.sendBodyAndHeader("file:target/script", "Hello ${body}", Exchange.FILE_NAME, "myscript.txt");
+
+                // START SNIPPET: e1
+                from("direct:start")
+                    // disable cache so the file is re-read
+                    .to("language:simple:file:target/script/myscript.txt?contentCache=false")
+                    .to("mock:result");
+                // END SNIPPET: e1
+            }
+        };
+    }
+}

Added: camel/trunk/camel-core/src/test/resources/org/apache/camel/component/language/mysimplescript.txt
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/resources/org/apache/camel/component/language/mysimplescript.txt?rev=1198392&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/resources/org/apache/camel/component/language/mysimplescript.txt (added)
+++ camel/trunk/camel-core/src/test/resources/org/apache/camel/component/language/mysimplescript.txt Sun Nov  6 15:24:24 2011
@@ -0,0 +1 @@
+Hello ${body}
\ No newline at end of file