Repository: camel
Updated Branches:
  refs/heads/master 6826e7a47 -> cbaeb0481


[CAMEL-11487] provided support for resources load through custom defined 
protocols by registering custom UrlHandlers


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cbaeb048
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cbaeb048
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cbaeb048

Branch: refs/heads/master
Commit: cbaeb048175938b4268741a0ebf7f4aeaedbed22
Parents: 6826e7a
Author: Andrea Tarocchi <ataro...@redhat.com>
Authored: Fri Jun 30 16:18:15 2017 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Tue Jul 4 09:14:16 2017 +0200

----------------------------------------------------------------------
 .../org/apache/camel/util/ResourceHelper.java   |  10 ++
 .../test/java/org/apache/camel/TestSupport.java |  34 +++++-
 .../ValidatorEndpointClearCachedSchemaTest.java |  68 +----------
 .../apache/camel/urlhandler/custom/Handler.java |  42 +++++++
 .../org/apache/camel/urlhandler/pd/Handler.java | 113 +++++++++++++++++++
 .../apache/camel/util/ResourceHelperTest.java   |  74 ++++++++++++
 6 files changed, 272 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java 
b/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java
index 316c179..6f28dac 100644
--- a/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java
@@ -128,6 +128,8 @@ public final class ResourceHelper {
      *     <il>http:uri - to load the resource using HTTP</il>
      *     <il>ref:nameOfBean - to lookup the resource in the {@link 
org.apache.camel.spi.Registry}</il>
      *     <il>bean:nameOfBean.methodName - to lookup a bean in the {@link 
org.apache.camel.spi.Registry} and call the method</il>
+     *     <il><customProtocol>:uri - to lookup the resource using a custom 
{@link java.net.URLStreamHandler} registered for the <customProtocol>,
+     *     on how to register it @see java.net.URL#URL(java.lang.String, 
java.lang.String, int, java.lang.String)</il>
      * </ul>
      * If no prefix has been given, then the resource is loaded from the 
classpath
      * <p/>
@@ -236,6 +238,11 @@ public final class ResourceHelper {
         } else if (uri.startsWith("classpath:")) {
             uri = ObjectHelper.after(uri, "classpath:");
             uri = tryDecodeUri(uri);
+        } else if (uri.contains(":")) {
+            LOG.trace("Loading resource: {} with UrlHandler for protocol {}", 
uri, uri.split(":")[0]);
+            URL url = new URL(uri);
+            URLConnection con = url.openConnection();
+            return con.getInputStream();
         }
 
         // load from classpath by default
@@ -288,6 +295,9 @@ public final class ResourceHelper {
         } else if (uri.startsWith("classpath:")) {
             uri = ObjectHelper.after(uri, "classpath:");
             uri = tryDecodeUri(uri);
+        } else if (uri.contains(":")) {
+            LOG.trace("Loading resource: {} with UrlHandler for protocol {}", 
uri, uri.split(":")[0]);
+            return new URL(uri);
         }
 
         // load from classpath by default

http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/TestSupport.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/TestSupport.java 
b/camel-core/src/test/java/org/apache/camel/TestSupport.java
index 85a710c..70ee0bf 100644
--- a/camel-core/src/test/java/org/apache/camel/TestSupport.java
+++ b/camel-core/src/test/java/org/apache/camel/TestSupport.java
@@ -74,7 +74,7 @@ public abstract class TestSupport extends TestCase {
 
     /**
      * Returns a value builder for the given exchange property
-     * 
+     *
      * @deprecated use {@link #exchangeProperty(String)}
      */
     @Deprecated
@@ -107,7 +107,7 @@ public abstract class TestSupport extends TestCase {
     /**
      * Returns a predicate and value builder for the outbound body on an
      * exchange
-     * 
+     *
      * @deprecated use {@link #body()}
      */
     @Deprecated
@@ -118,7 +118,7 @@ public abstract class TestSupport extends TestCase {
     /**
      * Returns a predicate and value builder for the outbound message body as a
      * specific type
-     * 
+     *
      * @deprecated use {@link #bodyAs(Class)}
      */
     @Deprecated
@@ -137,7 +137,7 @@ public abstract class TestSupport extends TestCase {
     /**
      * Returns a predicate and value builder for the fault message body as a
      * specific type
-     * 
+     *
      * @deprecated use {@link #bodyAs(Class)}
      */
     @Deprecated
@@ -530,7 +530,7 @@ public abstract class TestSupport extends TestCase {
      * <p/>
      * Uses <tt>java.version</tt> from the system properties to determine the 
version.
      *
-     * @param version such as 1.6 or 6 
+     * @param version such as 1.6 or 6
      * @return <tt>true</tt> if its that vendor.
      */
     public static boolean isJavaVersion(String version) {
@@ -556,4 +556,28 @@ public abstract class TestSupport extends TestCase {
             return Integer.parseInt(javaSpecVersion);
         }
     }
+
+    /**
+     * Used for registering a sysetem property.
+     * <p/>
+     * if the property already contains the passed value nothing will happen.
+     * If the system property has already a value, the passed value will be 
appended separated by <tt>separator</tt>
+     *
+     * @param sysPropertyName   the name of the system property to be set
+     * @param sysPropertyValue  the value to be set for the system property 
passed as sysPropertyName
+     * @param separator         the property separator to be used to append 
sysPropertyValue
+     *
+     */
+    public static void registerSystemProperty(String sysPropertyName, String 
sysPropertyValue, String separator) {
+        synchronized (System.getProperties()) {
+            if (System.getProperties().contains(sysPropertyName)) {
+                String current = System.getProperty(sysPropertyName);
+                if (!current.contains(sysPropertyValue)) {
+                    System.setProperty(sysPropertyName, current + separator + 
sysPropertyValue);
+                }
+            } else {
+                System.setProperty(sysPropertyName, sysPropertyValue);
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
 
b/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
index e144208..e9151f1 100644
--- 
a/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
@@ -90,9 +90,12 @@ public class ValidatorEndpointClearCachedSchemaTest extends 
ContextTestSupport {
 
     @Override
     protected CamelContext createCamelContext() throws Exception {
+        String handlerPackageSystemProp = "java.protocol.handler.pkgs";
+        String customUrlHandlerPackage = "org.apache.camel.urlhandler";
+        registerSystemProperty(handlerPackageSystemProp, 
customUrlHandlerPackage, "|");
+
         simpleReg = new SimpleRegistry();
         context = new DefaultCamelContext(simpleReg);
-        context.setClassResolver(new ClassResolverImpl());
         return context;
     }
 
@@ -159,67 +162,4 @@ public class ValidatorEndpointClearCachedSchemaTest 
extends ContextTestSupport {
         }
     }
 
-    /**
-     * Class to simulate a change of the XSD document. During the first call of
-     * the resource a XSD is returned which does not fit to the XML document. 
In
-     * the second call a XSD fitting to the XML document is returned.
-     */
-    static class ClassResolverImpl extends DefaultClassResolver {
-
-        private final String xsdtemplate1 = "<?xml version=\"1.0\" 
encoding=\"UTF-8\"?>\n" + //
-                                            "<xsd:schema 
targetNamespace=\"http://apache.camel.org/test\"; 
xmlns=\"http://apache.camel.org/test\"; 
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\";>"
-                                            + //
-                                            "    <xsd:complexType 
name=\"TestMessage\">" + //
-                                            "        <xsd:sequence>" + //
-                                            "            <xsd:element 
name=\"Content\" type=\"xsd:string\" />" + // //
-                                                                               
                                  // wrong
-                                                                               
                                  // element
-                                                                               
                                  // name
-                                                                               
                                  // will
-                                                                               
                                  // cause
-                                                                               
                                  // the
-                                                                               
                                  // validation
-                                                                               
                                  // to
-                                                                               
                                  // fail
-        "        </xsd:sequence>" + //
-                                            "        <xsd:attribute 
name=\"attr\" type=\"xsd:string\" default=\"xsd1\"/>" + //
-                                            "    </xsd:complexType>" + //
-                                            "    <xsd:element 
name=\"TestMessage\" type=\"TestMessage\" />" + //
-                                            "</xsd:schema>"; //
-
-        private final String xsdtemplate2 = 
xsdtemplate1.replace("\"Content\"", "\"MessageContent\""); // correct
-                                                                               
                        // element
-                                                                               
                        // name
-                                                                               
                        // -->
-                                                                               
                        // validation
-                                                                               
                        // will
-                                                                               
                        // be
-                                                                               
                        // correct
-
-        private byte[] xsd1 = xsdtemplate1.getBytes(StandardCharsets.UTF_8);
-
-        private byte[] xsd2 = xsdtemplate2.getBytes(StandardCharsets.UTF_8);
-
-        private volatile short counter;
-
-        @Override
-        public InputStream loadResourceAsStream(String uri) {
-            if (uri.startsWith("pd:")) {
-                byte[] xsd;
-                if (counter == 0) {
-                    xsd = xsd1;
-                    LOG.info("resolved XSD1");
-                } else {
-                    xsd = xsd2;
-                    LOG.info("resolved XSD2");
-                }
-                counter++;
-                return new ByteArrayInputStream(xsd);
-            } else {
-                return super.loadResourceAsStream(uri);
-            }
-        }
-
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java 
b/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java
new file mode 100644
index 0000000..54aef4b
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java
@@ -0,0 +1,42 @@
+/**
+ * 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.urlhandler.custom;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+public class Handler extends URLStreamHandler {
+    @Override
+    protected URLConnection openConnection(URL u) throws IOException {
+        final String echo = u.getHost();
+        return new URLConnection(u) {
+            @Override
+            public void connect() throws IOException {
+                connected = true;
+            }
+
+            @Override
+            public InputStream getInputStream() throws IOException {
+                return new ByteArrayInputStream(echo.getBytes());
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java 
b/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java
new file mode 100644
index 0000000..c14b9c1
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java
@@ -0,0 +1,113 @@
+/**
+ * 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.urlhandler.pd;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.nio.charset.StandardCharsets;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to simulate a change of the XSD document. During the first call of
+ * the resource a XSD is returned which does not fit to the XML document. In
+ * the second call a XSD fitting to the XML document is returned.
+ * Used in 
org.apache.camel.component.validator.ValidatorEndpointClearCachedSchemaTest
+ */
+public class Handler extends URLStreamHandler {
+    private static int counter;
+    private static final Logger LOG = LoggerFactory.getLogger(Handler.class);
+
+    private final String xsdtemplate1 = "<?xml version=\"1.0\" 
encoding=\"UTF-8\"?>\n" + //
+            "<xsd:schema targetNamespace=\"http://apache.camel.org/test\"; 
xmlns=\"http://apache.camel.org/test\"; 
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\";>"
+            + //
+            "    <xsd:complexType name=\"TestMessage\">" + //
+            "        <xsd:sequence>" + //
+            "            <xsd:element name=\"Content\" type=\"xsd:string\" />" 
+ // //
+            // wrong
+            // element
+            // name
+            // will
+            // cause
+            // the
+            // validation
+            // to
+            // fail
+            "        </xsd:sequence>" + //
+            "        <xsd:attribute name=\"attr\" type=\"xsd:string\" 
default=\"xsd1\"/>" + //
+            "    </xsd:complexType>" + //
+            "    <xsd:element name=\"TestMessage\" type=\"TestMessage\" />" + 
//
+            "</xsd:schema>"; //
+
+    private final String xsdtemplate2 = xsdtemplate1.replace("\"Content\"", 
"\"MessageContent\""); // correct
+    // element
+    // name
+    // -->
+    // validation
+    // will
+    // be
+    // correct
+
+    private byte[] xsd1 = xsdtemplate1.getBytes(StandardCharsets.UTF_8);
+    private byte[] xsd2 = xsdtemplate2.getBytes(StandardCharsets.UTF_8);
+
+    @Override
+    protected URLConnection openConnection(URL u) throws IOException {
+        if (getCounter() == 0) {
+            LOG.info("resolved XSD1");
+            incrementCounter();
+            return new URLConnection(u) {
+                @Override
+                public void connect() throws IOException {
+                    connected = true;
+                }
+
+                @Override
+                public InputStream getInputStream() throws IOException {
+                    return new ByteArrayInputStream(xsd1);
+                }
+            };
+        } else {
+            LOG.info("resolved XSD2");
+            incrementCounter();
+            return new URLConnection(u) {
+                @Override
+                public void connect() throws IOException {
+                    connected = true;
+                }
+
+                @Override
+                public InputStream getInputStream() throws IOException {
+                    return new ByteArrayInputStream(xsd2);
+                }
+            };
+        }
+    }
+
+    public static synchronized void incrementCounter() {
+        counter++;
+    }
+
+    public static synchronized int getCounter() {
+        return counter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java 
b/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java
index b0448e9..b6a4592 100644
--- a/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java
@@ -17,17 +17,28 @@
 package org.apache.camel.util;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
+import static javax.imageio.ImageIO.read;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.TestSupport;
+import org.apache.camel.converter.IOConverter;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.SimpleRegistry;
 
+import static org.junit.Assert.assertThat;
+
 /**
  *
  */
@@ -98,6 +109,7 @@ public class ResourceHelperTest extends TestSupport {
 
         context.stop();
     }
+
     public void testLoadClasspathDefault() throws Exception {
         CamelContext context = new DefaultCamelContext();
         context.start();
@@ -169,6 +181,68 @@ public class ResourceHelperTest extends TestSupport {
         context.stop();
     }
 
+    public void testLoadCustomUrlasInputStream() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        context.start();
+
+        String handlerPackageSystemProp = "java.protocol.handler.pkgs";
+        String customUrlHandlerPackage = "org.apache.camel.urlhandler";
+
+        registerSystemProperty(handlerPackageSystemProp, 
customUrlHandlerPackage, "|");
+
+        InputStream is = 
ResourceHelper.resolveMandatoryResourceAsInputStream(context, "custom://hello");
+        assertNotNull(is);
+
+        assertEquals("hello", IOConverter.toString(IOHelper.buffered(new 
InputStreamReader(is, "UTF-8"))));
+
+        context.stop();
+    }
+
+    public void testLoadCustomUrlasInputStreamFail() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        context.start();
+
+        try {
+            InputStream is = 
ResourceHelper.resolveMandatoryResourceAsInputStream(context, "custom://hello");
+            assertNotNull(is);
+        } catch (Exception e) {
+            assertEquals("unknown protocol: custom", e.getMessage());
+        }
+
+        context.stop();
+    }
+
+    public void testLoadCustomUrl() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        context.start();
+
+        String handlerPackageSystemProp = "java.protocol.handler.pkgs";
+        String customUrlHandlerPackage = "org.apache.camel.urlhandler";
+        registerSystemProperty(handlerPackageSystemProp, 
customUrlHandlerPackage, "|");
+
+        URL url = 
ResourceHelper.resolveResourceAsUrl(context.getClassResolver(), 
"custom://hello");
+        assertNotNull(url);
+
+        String text = context.getTypeConverter().convertTo(String.class, url);
+        assertNotNull(text);
+        assertTrue(text.contains("hello"));
+
+        context.stop();
+    }
+
+    public void testLoadCustomUrlFail() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        context.start();
+
+        try {
+            URL url = 
ResourceHelper.resolveResourceAsUrl(context.getClassResolver(), 
"custom://hello");
+        } catch (Exception e) {
+            assertEquals("unknown protocol: custom", e.getMessage());
+        }
+
+        context.stop();
+    }
+
     public void testIsHttp() throws Exception {
         assertFalse(ResourceHelper.isHttpUri("direct:foo"));
         assertFalse(ResourceHelper.isHttpUri(""));

Reply via email to