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);