This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch 13557
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 6bd93adb6db776b3a2f51b20238f5aa2e96b99d3
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu May 23 10:12:14 2019 +0200

    CAMEL-13557: Add property binding support to make it convenient to 
configure components and whatnot.
---
 .../camel/support/PropertyBindingSupportTest.java  | 18 +++++++++++
 .../camel/support/PropertyBindingSupport.java      | 35 ++++++++++++++++++++--
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
index bce0ad0..35bfadf 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
@@ -162,6 +162,24 @@ public class PropertyBindingSupportTest extends 
ContextTestSupport {
     }
 
     @Test
+    public void testAutowire() throws Exception {
+        Foo foo = new Foo();
+
+        PropertyBindingSupport.bindProperty(context, foo, "name", "James");
+        PropertyBindingSupport.bindProperty(context, foo, "bar.age", "33");
+        PropertyBindingSupport.bindProperty(context, foo, "bar.{{committer}}", 
"true");
+        PropertyBindingSupport.bindProperty(context, foo, "bar.gold-customer", 
"true");
+        PropertyBindingSupport.bindProperty(context, foo, "bar.work", 
"#autowire");
+
+        assertEquals("James", foo.getName());
+        assertEquals(33, foo.getBar().getAge());
+        assertTrue(foo.getBar().isRider());
+        assertTrue(foo.getBar().isGoldCustomer());
+        assertEquals(456, foo.getBar().getWork().getId());
+        assertEquals("Acme", foo.getBar().getWork().getName());
+    }
+
+    @Test
     public void testMandatory() throws Exception {
         Foo foo = new Foo();
 
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 6765233..453e5b0 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
@@ -34,19 +34,34 @@ import static 
org.apache.camel.support.IntrospectionSupport.getOrElseProperty;
  *     <li>nested - Properties can be nested using the dot syntax (OGNL and 
builder pattern using with as prefix), eg foo.bar=123</li>
  *     <li>reference by id - Values can refer to other beans in the registry 
by prefixing with #id: or # syntax, eg #id:myBean or #myBean</li>
  *     <li>reference by type - Values can refer to singleton beans by their 
type in the registry by prefixing with #type: syntax, eg 
#type:com.foo.MyClassType</li>
+ *     <li>autowire by type - Values can refer to singleton beans by auto 
wiring by setting the value to #autowire</li>
  *     <li>new class - Values can refer to creating new beans by their class 
name syntax, eg class:com.foo.MyClassType</li>
  * </ul>
  * This implementations reuses parts of {@link IntrospectionSupport}.
  */
 public final class PropertyBindingSupport {
 
-    // TODO: Add support for auto binding to singleton instance by type from 
registry (boolean on|off)
     // TODO: Add support for Map/List
 
     private PropertyBindingSupport() {
     }
 
     /**
+     * This will discover all the properties on the target, and automatic bind 
the properties that are null by
+     * looking up in the registry to see if there is a single instance of the 
same type as the property.
+     * This is used for convention over configuration to automatic configure 
resources such as DataSource, Amazon Logins and
+     * so on.
+     *
+     * @param camelContext  the camel context
+     * @param target        the target object
+     * @return              true if one ore more properties was auto wired
+     */
+    public static boolean autowireSingletonPropertiesFromRegistry(CamelContext 
camelContext, Object target) {
+        // TODO: implement me
+        return false;
+    }
+
+    /**
      * Binds the properties to the target object.
      *
      * @param camelContext  the camel context
@@ -105,7 +120,6 @@ public final class PropertyBindingSupport {
     }
 
     private static boolean setProperty(CamelContext context, Object target, 
String name, Object value) throws Exception {
-        Class<?> clazz = target.getClass();
         String refName = null;
 
         // resolve property placeholders
@@ -119,7 +133,7 @@ public final class PropertyBindingSupport {
         if (name.indexOf('.') > 0) {
             String[] parts = name.split("\\.");
             Object newTarget = target;
-            Class<?> newClass = clazz;
+            Class<?> newClass = target.getClass();
             // we should only iterate until until 2nd last so we use -1 in the 
for loop
             for (int i = 0; i < parts.length - 1; i++) {
                 String part = parts[i];
@@ -127,6 +141,7 @@ public final class PropertyBindingSupport {
                 if (prop == null) {
                     // okay is there a setter so we can create a new instance 
and set it automatic
                     Set<Method> newSetters = findSetterMethods(newClass, part, 
true);
+                    // TODO: you may have setter + fluent builder at the same 
time, so grab setter first, and fallback to fluent builder afterwards
                     if (newSetters.size() == 1) {
                         Method method = newSetters.iterator().next();
                         Class<?> parameterType = method.getParameterTypes()[0];
@@ -167,6 +182,20 @@ public final class PropertyBindingSupport {
                         value = types.iterator().next();
                     }
                 }
+            } else if (value.toString().equals("#autowire")) {
+                // we should get the type from the setter
+                // TODO: you may have setter + fluent builder at the same 
time, so grab setter first, and fallback to fluent builder afterwards
+                Set<Method> newSetters = findSetterMethods(target.getClass(), 
name, true);
+                if (newSetters.size() == 1) {
+                    Method method = newSetters.iterator().next();
+                    Class<?> parameterType = method.getParameterTypes()[0];
+                    if (parameterType != null) {
+                        Set<?> types = 
context.getRegistry().findByType(parameterType);
+                        if (types.size() == 1) {
+                            value = types.iterator().next();
+                        }
+                    }
+                }
             } else if (value.toString().startsWith("#id:")) {
                 // okay its a reference so swap to lookup this which is 
already supported in IntrospectionSupport
                 refName = ((String) value).substring(4);

Reply via email to