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

commit 5ced786ad0b307cf032f6a50d0780c399da6f477
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Jun 16 08:13:22 2019 +0200

    CAMEL-13647: Allow to do autowrire by classpath. Quick and dirty prototype.
---
 .../java/org/apache/camel/maven/AutowireMojo.java  | 75 ++++++++++++++++++----
 .../src/main/resources/known-types.properties      | 22 +++++++
 .../camel/support/PropertyBindingSupport.java      |  1 +
 .../org/apache/camel/example/MyRouteBuilder.java   |  2 +
 .../src/main/resources/application.properties      |  3 +
 5 files changed, 90 insertions(+), 13 deletions(-)

diff --git 
a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
 
b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
index 02616f7..ab205f3 100644
--- 
a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
+++ 
b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
@@ -18,6 +18,7 @@ package org.apache.camel.maven;
 
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -103,6 +104,10 @@ public class AutowireMojo extends AbstractExecMojo {
 
     private transient ClassLoader classLoader;
 
+    // TODO: Allow to configure known types in xml config, or refer to 
external file
+    // TODO: Allow to configure include/exclude names on components,names
+    // TODO: Skip some known types
+
     // CHECKSTYLE:OFF
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
@@ -159,7 +164,13 @@ public class AutowireMojo extends AbstractExecMojo {
                 .addClassLoader(classLoader)
                 .setScanners(new SubTypesScanner()));
 
-        List<String> autowires = 
findAutowireComponentOptionsByClasspath(catalog, components, reflections);
+        // load known types
+        Properties knownTypes = loadKnownTypes();
+        getLog().debug("Loaded known-types: " + knownTypes);
+
+        // find the autowire via classpath scanning
+        List<String> autowires = 
findAutowireComponentOptionsByClasspath(catalog, components, reflections, 
knownTypes);
+
         if (!autowires.isEmpty()) {
             outFolder.mkdirs();
             File file = new File(outFolder, "autowire.properties");
@@ -178,7 +189,21 @@ public class AutowireMojo extends AbstractExecMojo {
         }
     }
 
-    protected List<String> 
findAutowireComponentOptionsByClasspath(CamelCatalog catalog, Set<String> 
components, Reflections reflections) {
+    protected Properties loadKnownTypes() throws MojoFailureException {
+        Properties knownTypes = new Properties();
+        try {
+            InputStream is = 
AutowireMojo.class.getResourceAsStream("/known-types.properties");
+            if (is != null) {
+                knownTypes.load(is);
+            }
+        } catch (IOException e) {
+            throw new MojoFailureException("Cannot load known-types.properties 
from classpath");
+        }
+        return knownTypes;
+    }
+
+    protected List<String> 
findAutowireComponentOptionsByClasspath(CamelCatalog catalog, Set<String> 
components,
+                                                                   Reflections 
reflections, Properties knownTypes) {
         List<String> autowires = new ArrayList<>();
 
         for (String componentName : components) {
@@ -199,25 +224,21 @@ public class AutowireMojo extends AbstractExecMojo {
                 if ("object".equals(type)) {
                     try {
                         Class clazz = classLoader.loadClass(javaType);
-                        if (clazz.isInterface()) {
+                        if (clazz.isInterface() && isComplexUserType(clazz)) {
                             Set<Class<?>> classes = 
reflections.getSubTypesOf(clazz);
                             // filter classes to not be interfaces or not a 
top level class
                             classes = classes.stream().filter(c -> 
!c.isInterface() && c.getEnclosingClass() == null).collect(Collectors.toSet());
-                            if (classes.size() == 1) {
-                                Class cls = classes.iterator().next();
-                                if (isValidAutowireClass(cls)) {
-                                    String line = "camel.component." + 
componentName + "." + name + "=#class:" + cls.getName();
-                                    getLog().debug(line);
-                                    autowires.add(line);
-                                }
-                            } else if (classes.size() > 1) {
-                                getLog().debug("Found " + classes.size() + " 
for autowire: " + componentName + "." + name + ". Cannot chose one class: " + 
classes);
+                            Class best = chooseBestKnownType(clazz, classes, 
knownTypes);
+                            if (isValidAutowireClass(best)) {
+                                String line = "camel.component." + 
componentName + "." + name + "=#class:" + best.getName();
+                                getLog().debug(line);
+                                autowires.add(line);
                             }
                         }
 
                     } catch (Exception e) {
-                        getLog().debug("Cannot load class: " + name, e);
                         // ignore
+                        getLog().debug("Cannot load class: " + name, e);
                     }
                 }
             }
@@ -226,6 +247,34 @@ public class AutowireMojo extends AbstractExecMojo {
         return autowires;
     }
 
+    protected Class chooseBestKnownType(Class type, Set<Class<?>> candidates, 
Properties knownTypes) {
+        String known = knownTypes.getProperty(type.getName());
+        if (known != null) {
+            for (String k : known.split(",")) {
+                // special as we should skip this option
+                if ("#skip#".equals(k)) {
+                    return null;
+                }
+                Class found = candidates.stream().filter(c -> 
c.getName().equals(k)).findFirst().orElse(null);
+                if (found != null) {
+                    return found;
+                }
+            }
+        }
+
+        if (candidates.size() == 1) {
+            return candidates.iterator().next();
+        } else if (candidates.size() > 1) {
+            getLog().debug("Cannot chose best type: " + type.getName() + " 
among " + candidates.size() + " implementations: " + candidates);
+        }
+        return null;
+    }
+
+    private static boolean isComplexUserType(Class type) {
+        // lets consider all non java, as complex types
+        return type != null && !type.isPrimitive() && 
!type.getName().startsWith("java.");
+    }
+
     protected boolean isValidAutowireClass(Class clazz) {
         // skip all from Apache Camel and regular JDK as they would be default 
anyway
         return !clazz.getName().startsWith("org.apache.camel");
diff --git 
a/catalog/camel-main-maven-plugin/src/main/resources/known-types.properties 
b/catalog/camel-main-maven-plugin/src/main/resources/known-types.properties
new file mode 100644
index 0000000..78971fe
--- /dev/null
+++ b/catalog/camel-main-maven-plugin/src/main/resources/known-types.properties
@@ -0,0 +1,22 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# favour these classes if there are multiple on the classpath
+javax.jms.ConnectionFactory=org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory,org.apache.activemq.ActiveMQConnectionFactory
+
+# skip these types
+org.springframework.jms.core.JmsOperations=#skip#
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
index 7298242..10306f0 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
@@ -279,6 +279,7 @@ public final class PropertyBindingSupport {
      * @param target        the target object
      * @return              true if one ore more properties was auto wired
      */
+    @Deprecated
     public static boolean 
autowireInterfacePropertiesFromClasspath(CamelContext camelContext, Object 
target) {
         return autowireInterfacePropertiesFromClasspath(camelContext, target, 
false, false, null);
     }
diff --git 
a/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
 
b/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
index d98ae5f..09546c0 100644
--- 
a/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
+++ 
b/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
@@ -27,5 +27,7 @@ public class MyRouteBuilder extends RouteBuilder {
             .log("${body}")
             .bean("myBean", "bye")
             .log("${body}");
+
+        from("jms:queue:cheese").to("log:cheese");
     }
 }
diff --git 
a/examples/camel-example-main/src/main/resources/application.properties 
b/examples/camel-example-main/src/main/resources/application.properties
index 71ab7ab..334af88 100644
--- a/examples/camel-example-main/src/main/resources/application.properties
+++ b/examples/camel-example-main/src/main/resources/application.properties
@@ -42,6 +42,9 @@ camel.component.quartz2.start-delayed-seconds = 3
 # you can configure whether OS environment should override (=2 which is 
default) or as fallback (=1)
 ### camel.component.properties.environment-variable-mode=1
 
+camel.component.jms.configuration.connectionFactory=#class:org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory
+camel.component.jms.configuration.connectionFactory.brokerUrl=localhost:61616
+
 # properties used in the route
 myCron = 0/2 * * * * ?
 

Reply via email to