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 e37c4a4dcc04ee14e5bf0008dfc9973da92e4af8
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Jun 26 09:25:09 2019 +0200

    CAMEL-13681: Property binding support should have support for ignore case 
in property keys
---
 .../camel/support/IntrospectionSupportTest.java    |   2 +-
 .../camel/support/PropertyBindingSupportTest.java  |  51 +++++++
 .../java/org/apache/camel/main/MainSupport.java    |  19 ++-
 .../apache/camel/support/IntrospectionSupport.java |  96 +++++++++----
 .../camel/support/PropertyBindingSupport.java      | 153 ++++++++++++++-------
 5 files changed, 239 insertions(+), 82 deletions(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java
index debe26b..6043a6c 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java
@@ -552,7 +552,7 @@ public class IntrospectionSupportTest extends 
ContextTestSupport {
 
     @Test
     public void testFindSetterMethodsOrderedByParameterType() throws Exception 
{
-        List<Method> setters = 
IntrospectionSupport.findSetterMethodsOrderedByParameterType(MyOverloadedBean.class,
 "bean", false, false);
+        List<Method> setters = 
IntrospectionSupport.findSetterMethodsOrderedByParameterType(MyOverloadedBean.class,
 "bean", false, false, false);
 
         assertNotNull(setters);
         assertEquals(2, setters.size());
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 fdc9c7a..588f3ec 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
@@ -68,6 +68,32 @@ public class PropertyBindingSupportTest extends 
ContextTestSupport {
         assertTrue(foo.getBar().isGoldCustomer());
         assertEquals(123, foo.getBar().getWork().getId());
         assertEquals("Acme", foo.getBar().getWork().getName());
+
+        assertTrue("Should bind all properties", prop.isEmpty());
+    }
+
+    @Test
+    public void testPropertiesIgnoreCase() throws Exception {
+        Foo foo = new Foo();
+
+        Map<String, Object> prop = new HashMap<>();
+        prop.put("name", "James");
+        prop.put("bar.AGE", "33");
+        prop.put("BAR.{{committer}}", "true");
+        prop.put("bar.gOLd-Customer", "true");
+        prop.put("bAr.work.ID", "123");
+        prop.put("bar.WORk.naME", "{{companyName}}");
+
+        PropertyBindingSupport.bindProperties(context, foo, prop, true);
+
+        assertEquals("James", foo.getName());
+        assertEquals(33, foo.getBar().getAge());
+        assertTrue(foo.getBar().isRider());
+        assertTrue(foo.getBar().isGoldCustomer());
+        assertEquals(123, foo.getBar().getWork().getId());
+        assertEquals("Acme", foo.getBar().getWork().getName());
+
+        assertTrue("Should bind all properties", prop.isEmpty());
     }
 
     @Test
@@ -96,6 +122,31 @@ public class PropertyBindingSupportTest extends 
ContextTestSupport {
     }
 
     @Test
+    public void testBindPropertiesWithOptionPrefixIgnoreCase() throws 
Exception {
+        Foo foo = new Foo();
+
+        Map<String, Object> prop = new HashMap<>();
+        prop.put("my.prefix.name", "James");
+        prop.put("my.PREFIX.bar.AGE", "33");
+        prop.put("my.prefix.bar.{{committer}}", "true");
+        prop.put("My.prefix.bar.Gold-custoMER", "true");
+        prop.put("mY.prefix.bar.work.ID", "123");
+        prop.put("my.prEFIx.bar.Work.Name", "{{companyName}}");
+        prop.put("my.other.prefix.something", "test");
+
+        PropertyBindingSupport.bindProperties(context, foo, prop, 
"my.prefix.", true);
+
+        assertEquals("James", foo.getName());
+        assertEquals(33, foo.getBar().getAge());
+        assertTrue(foo.getBar().isRider());
+        assertTrue(foo.getBar().isGoldCustomer());
+        assertEquals(123, foo.getBar().getWork().getId());
+        assertEquals("Acme", foo.getBar().getWork().getName());
+        assertTrue(prop.containsKey("my.other.prefix.something"));
+        assertEquals(1, prop.size());
+    }
+
+    @Test
     public void testNested() throws Exception {
         Foo foo = new Foo();
 
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java 
b/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java
index 3f80690..c9e3ce1 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java
@@ -63,7 +63,6 @@ import org.slf4j.LoggerFactory;
 
 import static org.apache.camel.support.ObjectHelper.invokeMethod;
 import static org.apache.camel.util.ReflectionHelper.findMethod;
-import static org.apache.camel.util.StringHelper.dashToCamelCase;
 import static org.apache.camel.util.StringHelper.matches;
 
 /**
@@ -833,7 +832,7 @@ public abstract class MainSupport extends ServiceSupport {
         }
         if (!properties.isEmpty()) {
             LOG.info("Auto configuring CamelContext from loaded properties: 
{}", properties.size());
-            setCamelProperties(camelContext, camelContext, properties, true);
+            setPropertiesOnTarget(camelContext, camelContext, properties, 
true, true);
         }
         if (!hystrixProperties.isEmpty()) {
             LOG.info("Auto configuring Hystrix EIP from loaded properties: 
{}", hystrixProperties.size());
@@ -843,7 +842,7 @@ public abstract class MainSupport extends ServiceSupport {
                 hystrix = new HystrixConfigurationDefinition();
                 model.setHystrixConfiguration(hystrix);
             }
-            setCamelProperties(camelContext, hystrix, hystrixProperties, true);
+            setPropertiesOnTarget(camelContext, hystrix, hystrixProperties, 
true, true);
         }
         if (!restProperties.isEmpty()) {
             LOG.info("Auto configuring Rest DSL from loaded properties: {}", 
restProperties.size());
@@ -853,7 +852,7 @@ public abstract class MainSupport extends ServiceSupport {
                 rest = new RestConfiguration();
                 model.setRestConfiguration(rest);
             }
-            setCamelProperties(camelContext, rest, restProperties, true);
+            setPropertiesOnTarget(camelContext, rest, restProperties, true, 
true);
         }
     }
 
@@ -920,7 +919,7 @@ public abstract class MainSupport extends ServiceSupport {
 
         for (Object obj : properties.keySet()) {
             Map<String, Object> values = properties.get(obj);
-            setCamelProperties(camelContext, obj, values, true);
+            setPropertiesOnTarget(camelContext, obj, values, true, true);
         }
     }
 
@@ -957,7 +956,7 @@ public abstract class MainSupport extends ServiceSupport {
 
         if (!properties.isEmpty()) {
             LOG.info("Auto configuring main from loaded properties: {}", 
properties.size());
-            setCamelProperties(camelContext, config, properties, true);
+            setPropertiesOnTarget(camelContext, config, properties, true, 
true);
         }
     }
 
@@ -1059,7 +1058,7 @@ public abstract class MainSupport extends ServiceSupport {
 
         for (Object obj : properties.keySet()) {
             Map<String, Object> values = properties.get(obj);
-            setCamelProperties(camelContext, obj, values, true);
+            setPropertiesOnTarget(camelContext, obj, values, true, true);
         }
     }
 
@@ -1095,7 +1094,7 @@ public abstract class MainSupport extends ServiceSupport {
         setRouteBuilderClasses(existing);
     }
 
-    private static boolean setCamelProperties(CamelContext context, Object 
target, Map<String, Object> properties, boolean failIfNotSet) throws Exception {
+    private static boolean setPropertiesOnTarget(CamelContext context, Object 
target, Map<String, Object> properties, boolean failIfNotSet, boolean 
ignoreCase) throws Exception {
         ObjectHelper.notNull(context, "context");
         ObjectHelper.notNull(target, "target");
         ObjectHelper.notNull(properties, "properties");
@@ -1111,10 +1110,10 @@ public abstract class MainSupport extends 
ServiceSupport {
 
             LOG.debug("Setting property {} on {} with value {}", name, target, 
stringValue);
             if (failIfNotSet) {
-                PropertyBindingSupport.bindMandatoryProperty(context, target, 
name, stringValue);
+                PropertyBindingSupport.bindMandatoryProperty(context, target, 
name, stringValue, ignoreCase);
                 rc = true;
             } else {
-                boolean hit = PropertyBindingSupport.bindProperty(context, 
target, name, stringValue);
+                boolean hit = PropertyBindingSupport.bindProperty(context, 
target, name, stringValue, ignoreCase);
                 if (hit) {
                     it.remove();
                     rc = true;
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
index d2b325a..21c5d9a 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
@@ -365,30 +365,64 @@ public final class IntrospectionSupport {
         }
     }
 
-    public static Object getProperty(Object target, String property) throws 
NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    public static Object getProperty(Object target, String propertyName) 
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 
{
         ObjectHelper.notNull(target, "target");
-        ObjectHelper.notNull(property, "property");
+        ObjectHelper.notNull(propertyName, "property");
 
-        property = property.substring(0, 1).toUpperCase(Locale.ENGLISH) + 
property.substring(1);
+        propertyName = propertyName.substring(0, 
1).toUpperCase(Locale.ENGLISH) + propertyName.substring(1);
 
         Class<?> clazz = target.getClass();
-        Method method = getPropertyGetter(clazz, property);
+        Method method = getPropertyGetter(clazz, propertyName);
         return method.invoke(target);
     }
 
-    public static Object getOrElseProperty(Object target, String property, 
Object defaultValue) {
+    public static Object getOrElseProperty(Object target, String propertyName, 
Object defaultValue) {
+        return getOrElseProperty(target, propertyName, defaultValue, false);
+    }
+
+    public static Object getOrElseProperty(Object target, String propertyName, 
Object defaultValue, boolean ignoreCase) {
         try {
-            return getProperty(target, property);
+            if (ignoreCase) {
+                Class<?> clazz = target.getClass();
+                Method method = getPropertyGetter(clazz, propertyName, true);
+                if (method != null) {
+                    return method.invoke(target);
+                } else {
+                    // not found so return default value
+                    return defaultValue;
+                }
+            } else {
+                return getProperty(target, propertyName);
+            }
         } catch (Exception e) {
             return defaultValue;
         }
     }
 
     public static Method getPropertyGetter(Class<?> type, String propertyName) 
throws NoSuchMethodException {
-        if (isPropertyIsGetter(type, propertyName)) {
-            return type.getMethod("is" + StringHelper.capitalize(propertyName, 
true));
+        return getPropertyGetter(type, propertyName, false);
+    }
+
+    public static Method getPropertyGetter(Class<?> type, String propertyName, 
boolean ignoreCase) throws NoSuchMethodException {
+        if (ignoreCase) {
+            Method[] methods = type.getDeclaredMethods();
+            for (Method m : methods) {
+                if (isGetter(m)) {
+                    if (m.getName().startsWith("is") && 
m.getName().substring(2).equalsIgnoreCase(propertyName)) {
+                        return m;
+                    } else if (m.getName().startsWith("get") && 
m.getName().substring(3).equalsIgnoreCase(propertyName)) {
+                        return m;
+                    }
+                }
+            }
+            // not found
+            return null;
         } else {
-            return type.getMethod("get" + 
StringHelper.capitalize(propertyName, true));
+            if (isPropertyIsGetter(type, propertyName)) {
+                return type.getMethod("is" + 
StringHelper.capitalize(propertyName, true));
+            } else {
+                return type.getMethod("get" + 
StringHelper.capitalize(propertyName, true));
+            }
         }
     }
 
@@ -539,7 +573,7 @@ public final class IntrospectionSupport {
      */
     public static boolean setProperty(CamelContext context, TypeConverter 
typeConverter, Object target, String name, Object value, String refName,
                                       boolean allowBuilderPattern) throws 
Exception {
-        return setProperty(context, typeConverter, target, name, value, 
refName, allowBuilderPattern, false);
+        return setProperty(context, typeConverter, target, name, value, 
refName, allowBuilderPattern, false, false);
     }
 
     /**
@@ -555,7 +589,7 @@ public final class IntrospectionSupport {
      * {@code context} and {@code refName} must NOT be NULL, and {@code value} 
MUST be NULL.
      */
     public static boolean setProperty(CamelContext context, TypeConverter 
typeConverter, Object target, String name, Object value, String refName,
-                                      boolean allowBuilderPattern, boolean 
allowPrivateSetter) throws Exception {
+                                      boolean allowBuilderPattern, boolean 
allowPrivateSetter, boolean ignoreCase) throws Exception {
 
         // does the property name include a lookup key, then we need to set 
the property as a map or list
         if (name.contains("[") && name.endsWith("]")) {
@@ -563,10 +597,10 @@ public final class IntrospectionSupport {
             String lookupKey = name.substring(pos + 1, name.length() - 1);
             String key = name.substring(0, pos);
 
-            Object obj = IntrospectionSupport.getOrElseProperty(target, key, 
null);
+            Object obj = IntrospectionSupport.getOrElseProperty(target, key, 
null, ignoreCase);
             if (obj == null) {
                 // it was supposed to be a list or map, but its null, so lets 
create a new list or map and set it automatically
-                Method getter = 
IntrospectionSupport.getPropertyGetter(target.getClass(), key);
+                Method getter = 
IntrospectionSupport.getPropertyGetter(target.getClass(), key, ignoreCase);
                 if (getter != null) {
                     // what type does it have
                     Class<?> returnType = getter.getReturnType();
@@ -616,10 +650,10 @@ public final class IntrospectionSupport {
 
         // we need to lookup the value from the registry
         if (context != null && refName != null && value == null) {
-            setters = findSetterMethodsOrderedByParameterType(clazz, name, 
allowBuilderPattern, allowPrivateSetter);
+            setters = findSetterMethodsOrderedByParameterType(clazz, name, 
allowBuilderPattern, allowPrivateSetter, ignoreCase);
         } else {
             // find candidates of setter methods as there can be overloaded 
setters
-            setters = findSetterMethods(clazz, name, value, 
allowBuilderPattern, allowPrivateSetter);
+            setters = findSetterMethods(clazz, name, value, 
allowBuilderPattern, allowPrivateSetter, ignoreCase);
         }
         if (setters.isEmpty()) {
             return false;
@@ -740,22 +774,22 @@ public final class IntrospectionSupport {
 
     public static boolean setProperty(CamelContext context, Object target, 
String name, Object value) throws Exception {
         // allow build pattern as a setter as well
-        return setProperty(context, context != null ? 
context.getTypeConverter() : null, target, name, value, null, true, false);
+        return setProperty(context, context != null ? 
context.getTypeConverter() : null, target, name, value, null, true, false, 
false);
     }
 
     public static boolean setProperty(CamelContext context, TypeConverter 
typeConverter, Object target, String name, Object value) throws Exception {
         // allow build pattern as a setter as well
-        return setProperty(context, typeConverter, target, name, value, null, 
true, false);
+        return setProperty(context, typeConverter, target, name, value, null, 
true, false, false);
     }
     
     public static boolean setProperty(TypeConverter typeConverter, Object 
target, String name, Object value) throws Exception {
         // allow build pattern as a setter as well
-        return setProperty(null, typeConverter, target, name, value, null, 
true, false);
+        return setProperty(null, typeConverter, target, name, value, null, 
true, false, false);
     }
 
     @Deprecated
     public static boolean setProperty(Object target, String name, Object 
value, boolean allowBuilderPattern) throws Exception {
-        return setProperty(null, null, target, name, value, null, 
allowBuilderPattern, false);
+        return setProperty(null, null, target, name, value, null, 
allowBuilderPattern, false, false);
     }
 
     @Deprecated
@@ -764,7 +798,8 @@ public final class IntrospectionSupport {
         return setProperty(target, name, value, true);
     }
 
-    public static Set<Method> findSetterMethods(Class<?> clazz, String name, 
boolean allowBuilderPattern, boolean allowPrivateSetter) {
+    public static Set<Method> findSetterMethods(Class<?> clazz, String name,
+                                                boolean allowBuilderPattern, 
boolean allowPrivateSetter, boolean ignoreCase) {
         Set<Method> candidates = new LinkedHashSet<>();
 
         // Build the method name
@@ -778,7 +813,16 @@ public final class IntrospectionSupport {
             Method objectSetMethod = null;
             Method[] methods = allowPrivateSetter ? clazz.getDeclaredMethods() 
: clazz.getMethods();
             for (Method method : methods) {
-                boolean validName = method.getName().equals(setName) || 
allowBuilderPattern && method.getName().equals(builderName) || 
allowBuilderPattern && method.getName().equals(builderName2);
+                boolean validName;
+                if (ignoreCase) {
+                    validName = method.getName().equalsIgnoreCase(setName)
+                            || allowBuilderPattern && 
method.getName().equalsIgnoreCase(builderName)
+                            || allowBuilderPattern && 
method.getName().equalsIgnoreCase(builderName2);
+                } else {
+                    validName = method.getName().equals(setName)
+                            || allowBuilderPattern && 
method.getName().equals(builderName)
+                            || allowBuilderPattern && 
method.getName().equals(builderName2);
+                }
                 if (validName) {
                     if (isSetter(method, allowBuilderPattern)) {
                         Class<?>[] params = method.getParameterTypes();
@@ -798,8 +842,9 @@ public final class IntrospectionSupport {
         return candidates;
     }
 
-    static Set<Method> findSetterMethods(Class<?> clazz, String name, Object 
value, boolean allowBuilderPattern, boolean allowPrivateSetter) {
-        Set<Method> candidates = findSetterMethods(clazz, name, 
allowBuilderPattern, allowPrivateSetter);
+    static Set<Method> findSetterMethods(Class<?> clazz, String name, Object 
value,
+                                         boolean allowBuilderPattern, boolean 
allowPrivateSetter, boolean ignoreCase) {
+        Set<Method> candidates = findSetterMethods(clazz, name, 
allowBuilderPattern, allowPrivateSetter, ignoreCase);
 
         if (candidates.isEmpty()) {
             return candidates;
@@ -824,10 +869,11 @@ public final class IntrospectionSupport {
         }
     }
 
-    static List<Method> findSetterMethodsOrderedByParameterType(Class<?> 
target, String propertyName, boolean allowBuilderPattern, boolean 
allowPrivateSetter) {
+    static List<Method> findSetterMethodsOrderedByParameterType(Class<?> 
target, String propertyName,
+                                                                boolean 
allowBuilderPattern, boolean allowPrivateSetter, boolean ignoreCase) {
         List<Method> answer = new LinkedList<>();
         List<Method> primitives = new LinkedList<>();
-        Set<Method> setters = findSetterMethods(target, propertyName, 
allowBuilderPattern, allowPrivateSetter);
+        Set<Method> setters = findSetterMethods(target, propertyName, 
allowBuilderPattern, allowPrivateSetter, ignoreCase);
         for (Method setter : setters) {
             Class<?> parameterType = setter.getParameterTypes()[0];
             if (PRIMITIVE_CLASSES.contains(parameterType)) {
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 40752a0..0d32d91 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
@@ -21,6 +21,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -43,6 +44,7 @@ import static org.apache.camel.util.ObjectHelper.isNotEmpty;
  *     <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 #autowired</li>
  *     <li>reference new class - Values can refer to creating new beans by 
their class name by prefixing with #class, eg #class:com.foo.MyClassType</li>
+ *     <li>ignore case - Whether to ignore case for property keys<li>
  * </ul>
  * <p/>
  * This implementations reuses parts of {@link IntrospectionSupport}.
@@ -60,6 +62,7 @@ public final class PropertyBindingSupport {
         private boolean placeholder = true;
         private boolean fluentBuilder = true;
         private boolean allowPrivateSetter = true;
+        private boolean ignoreCase = false;
         private String optionPrefix;
 
         /**
@@ -107,8 +110,16 @@ public final class PropertyBindingSupport {
          * Whether properties should be filtered by prefix.         *
          * Note that the prefix is removed from the key before the property is 
bound.
          */
-        public Builder withOptionPrefix(String optionPrefix) {
-            this.optionPrefix = optionPrefix;
+        public Builder withAllowPrivateSetter(boolean allowPrivateSetter) {
+            this.allowPrivateSetter = allowPrivateSetter;
+            return this;
+        }
+
+        /**
+         * Whether to ignore case in the property names (keys).
+         */
+        public Builder withIgnoreCase(boolean ignoreCase) {
+            this.ignoreCase = ignoreCase;
             return this;
         }
 
@@ -116,8 +127,8 @@ public final class PropertyBindingSupport {
          * Whether properties should be filtered by prefix.         *
          * Note that the prefix is removed from the key before the property is 
bound.
          */
-        public Builder withAllowPrivateSetter(boolean allowPrivateSetter) {
-            this.allowPrivateSetter = allowPrivateSetter;
+        public Builder withOptionPrefix(String optionPrefix) {
+            this.optionPrefix = optionPrefix;
             return this;
         }
 
@@ -134,7 +145,8 @@ public final class PropertyBindingSupport {
             org.apache.camel.util.ObjectHelper.notNull(target, "target");
             org.apache.camel.util.ObjectHelper.notNull(properties, 
"properties");
 
-            return bindProperties(camelContext, target, properties, 
optionPrefix, nesting, deepNesting, fluentBuilder, allowPrivateSetter, 
reference, placeholder);
+            return bindProperties(camelContext, target, properties, 
optionPrefix, ignoreCase, nesting, deepNesting,
+                    fluentBuilder, allowPrivateSetter, reference, placeholder);
         }
 
     }
@@ -215,7 +227,7 @@ public final class PropertyBindingSupport {
         for (Map.Entry<String, Object> entry : properties.entrySet()) {
             String key = entry.getKey();
             Object value = entry.getValue();
-            Class<?> type = getGetterType(target, key);
+            Class<?> type = getGetterType(target, key, false);
 
             boolean skip = parents.contains(value) || value instanceof 
CamelContext;
             if (skip) {
@@ -242,7 +254,7 @@ public final class PropertyBindingSupport {
                 // attempt to create new instances to walk down the tree if 
its null (deepNesting option)
                 if (value == null && deepNesting) {
                     // okay is there a setter so we can create a new instance 
and set it automatic
-                    Method method = findBestSetterMethod(target.getClass(), 
key, true, true);
+                    Method method = findBestSetterMethod(target.getClass(), 
key, true, true, false);
                     if (method != null) {
                         Class<?> parameterType = method.getParameterTypes()[0];
                         if (parameterType != null && 
org.apache.camel.util.ObjectHelper.hasDefaultPublicNoArgConstructor(parameterType))
 {
@@ -283,6 +295,19 @@ public final class PropertyBindingSupport {
     }
 
     /**
+     * Binds the properties to the target object, and removes the property 
that was bound from properties.
+     *
+     * @param camelContext  the camel context
+     * @param target        the target object
+     * @param properties    the properties where the bound properties will be 
removed from
+     * @param ignoreCase    whether to ignore case for property keys
+     * @return              true if one or more properties was bound
+     */
+    public static boolean bindProperties(CamelContext camelContext, Object 
target, Map<String, Object> properties, boolean ignoreCase) {
+        return bindProperties(camelContext, target, properties, null, 
ignoreCase, true, true, true, true, true, true);
+    }
+
+    /**
      * Binds the properties with the given prefix to the target object, and 
removes the property that was bound from properties.
      * Note that the prefix is removed from the key before the property is 
bound.
      *
@@ -293,29 +318,22 @@ public final class PropertyBindingSupport {
      * @return              true if one or more properties was bound
      */
     public static boolean bindProperties(CamelContext camelContext, Object 
target, Map<String, Object> properties, String optionPrefix) {
-        return bindProperties(camelContext, target, properties, optionPrefix, 
true, true, true, true, true, true);
+        return bindProperties(camelContext, target, properties, optionPrefix, 
false);
     }
 
     /**
      * Binds the properties with the given prefix to the target object, and 
removes the property that was bound from properties.
+     * Note that the prefix is removed from the key before the property is 
bound.
      *
-     * @param camelContext        the camel context
-     * @param target              the target object
-     * @param properties          the properties where the bound properties 
will be removed from
-     * @param nesting             whether nesting is in use
-     * @param deepNesting         whether deep nesting is in use, where Camel 
will attempt to walk as deep as possible by creating new objects in the OGNL 
graph if
-     *                            a property has a setter and the object can 
be created from a default no-arg constructor.
-     * @param fluentBuilder       whether fluent builder is allowed as a valid 
getter/setter
-     * @param allowPrivateSetter  whether autowiring components allows to use 
private setter method when setting the value
-     * @param reference           whether reference parameter (syntax starts 
with #) is in use
-     * @param placeholder         whether to use Camels property placeholder 
to resolve placeholders on keys and values
-     * @return                    true if one or more properties was bound
+     * @param camelContext  the camel context
+     * @param target        the target object
+     * @param properties    the properties where the bound properties will be 
removed from
+     * @param optionPrefix  the prefix used to filter properties
+     * @param ignoreCase    whether to ignore case for property keys
+     * @return              true if one or more properties was bound
      */
-    public static boolean bindProperties(CamelContext camelContext, Object 
target, Map<String, Object> properties,
-                                         boolean nesting, boolean deepNesting, 
boolean fluentBuilder, boolean allowPrivateSetter,
-                                         boolean reference, boolean 
placeholder) {
-
-        return bindProperties(camelContext, target, properties, null, nesting, 
deepNesting, fluentBuilder, allowPrivateSetter, reference, placeholder);
+    public static boolean bindProperties(CamelContext camelContext, Object 
target, Map<String, Object> properties, String optionPrefix, boolean 
ignoreCase) {
+        return bindProperties(camelContext, target, properties, optionPrefix, 
ignoreCase, true, true, true, true, true, true);
     }
 
     /**
@@ -326,6 +344,7 @@ public final class PropertyBindingSupport {
      * @param target              the target object
      * @param properties          the properties where the bound properties 
will be removed from
      * @param optionPrefix        the prefix used to filter properties
+     * @param ignoreCase          whether to ignore case for property keys
      * @param nesting             whether nesting is in use
      * @param deepNesting         whether deep nesting is in use, where Camel 
will attempt to walk as deep as possible by creating new objects in the OGNL 
graph if
      *                            a property has a setter and the object can 
be created from a default no-arg constructor.
@@ -336,7 +355,7 @@ public final class PropertyBindingSupport {
      * @return                    true if one or more properties was bound
      */
     public static boolean bindProperties(CamelContext camelContext, Object 
target, Map<String, Object> properties,
-                                         String optionPrefix,
+                                         String optionPrefix, boolean 
ignoreCase,
                                          boolean nesting, boolean deepNesting, 
boolean fluentBuilder, boolean allowPrivateSetter,
                                          boolean reference, boolean 
placeholder) {
         org.apache.camel.util.ObjectHelper.notNull(camelContext, 
"camelContext");
@@ -347,19 +366,25 @@ public final class PropertyBindingSupport {
         // must set reference parameters first before the other bindings
         setReferenceProperties(camelContext, target, properties);
 
+        String uOptionPrefix = "";
+        if (ignoreCase && isNotEmpty(optionPrefix)) {
+            uOptionPrefix = optionPrefix.toUpperCase(Locale.US);
+        }
+
         for (Iterator<Map.Entry<String, Object>> iter = 
properties.entrySet().iterator(); iter.hasNext();) {
             Map.Entry<String, Object> entry = iter.next();
             String key = entry.getKey();
             Object value = entry.getValue();
 
             if (isNotEmpty(optionPrefix)) {
-                if (!key.startsWith(optionPrefix)) {
+                boolean match = key.startsWith(optionPrefix) || ignoreCase && 
key.toUpperCase(Locale.US).startsWith(uOptionPrefix);
+                if (!match) {
                     continue;
                 }
                 key = key.substring(optionPrefix.length());
             }
 
-            if (bindProperty(camelContext, target, key, value, nesting, 
deepNesting, fluentBuilder, allowPrivateSetter, reference, placeholder)) {
+            if (bindProperty(camelContext, target, key, value, ignoreCase, 
nesting, deepNesting, fluentBuilder, allowPrivateSetter, reference, 
placeholder)) {
                 iter.remove();
                 rc = true;
             }
@@ -378,9 +403,23 @@ public final class PropertyBindingSupport {
      * @return              true if property was bound, false otherwise
      */
     public static boolean bindProperty(CamelContext camelContext, Object 
target, String name, Object value) {
+        return bindProperty(camelContext, target, name, value, false);
+    }
+
+    /**
+     * Binds the property to the target object.
+     *
+     * @param camelContext  the camel context
+     * @param target        the target object
+     * @param name          name of property
+     * @param value         value of property
+     * @param ignoreCase    whether to ignore case for property keys
+     * @return              true if property was bound, false otherwise
+     */
+    public static boolean bindProperty(CamelContext camelContext, Object 
target, String name, Object value, boolean ignoreCase) {
         try {
             if (target != null && name != null) {
-                return setProperty(camelContext, target, name, value, false, 
true, true, true, true, true, true);
+                return setProperty(camelContext, target, name, value, false, 
ignoreCase, true, true, true, true, true, true);
             }
         } catch (Exception e) {
             throw new PropertyBindingException(target, name, e);
@@ -390,10 +429,11 @@ public final class PropertyBindingSupport {
     }
 
     private static boolean bindProperty(CamelContext camelContext, Object 
target, String name, Object value,
-                                        boolean nesting, boolean deepNesting, 
boolean fluentBuilder, boolean allowPrivateSetter, boolean reference, boolean 
placeholder) {
+                                        boolean ignoreCase, boolean nesting, 
boolean deepNesting, boolean fluentBuilder,
+                                        boolean allowPrivateSetter, boolean 
reference, boolean placeholder) {
         try {
             if (target != null && name != null) {
-                return setProperty(camelContext, target, name, value, false, 
nesting, deepNesting, fluentBuilder, allowPrivateSetter, reference, 
placeholder);
+                return setProperty(camelContext, target, name, value, false, 
ignoreCase, nesting, deepNesting, fluentBuilder, allowPrivateSetter, reference, 
placeholder);
             }
         } catch (Exception e) {
             throw new PropertyBindingException(target, name, e);
@@ -411,9 +451,22 @@ public final class PropertyBindingSupport {
      * @param value         value of property
      */
     public static void bindMandatoryProperty(CamelContext camelContext, Object 
target, String name, Object value) {
+        bindMandatoryProperty(camelContext, target, name, value, false);
+    }
+
+    /**
+     * Binds the mandatory property to the target object (will fail if not 
set/bound).
+     *
+     * @param camelContext  the camel context
+     * @param target        the target object
+     * @param name          name of property
+     * @param value         value of property
+     * @param ignoreCase    whether to ignore case for property keys
+     */
+    public static void bindMandatoryProperty(CamelContext camelContext, Object 
target, String name, Object value, boolean ignoreCase) {
         try {
             if (target != null && name != null) {
-                boolean bound = setProperty(camelContext, target, name, value, 
true, true, true, true, true, true, true);
+                boolean bound = setProperty(camelContext, target, name, value, 
true, ignoreCase, true, true, true, true, true, true);
                 if (!bound) {
                     throw new PropertyBindingException(target, name);
                 }
@@ -424,8 +477,8 @@ public final class PropertyBindingSupport {
     }
 
     private static boolean setProperty(CamelContext context, Object target, 
String name, Object value, boolean mandatory,
-                                       boolean nesting, boolean deepNesting, 
boolean fluentBuilder, boolean allowPrivateSetter,
-                                       boolean reference, boolean placeholder) 
throws Exception {
+                                       boolean ignoreCase, boolean nesting, 
boolean deepNesting, boolean fluentBuilder,
+                                       boolean allowPrivateSetter, boolean 
reference, boolean placeholder) throws Exception {
         String refName = null;
 
         if (placeholder) {
@@ -448,14 +501,14 @@ public final class PropertyBindingSupport {
                 // 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];
-                    Object prop = getOrElseProperty(newTarget, part, null);
+                    Object prop = getOrElseProperty(newTarget, part, null, 
ignoreCase);
                     if (prop == null) {
                         if (!deepNesting) {
                             // okay we cannot go further down
                             break;
                         }
                         // okay is there a setter so we can create a new 
instance and set it automatic
-                        Method method = findBestSetterMethod(newClass, part, 
fluentBuilder, allowPrivateSetter);
+                        Method method = findBestSetterMethod(newClass, part, 
fluentBuilder, allowPrivateSetter, ignoreCase);
                         if (method != null) {
                             Class<?> parameterType = 
method.getParameterTypes()[0];
                             Object instance = null;
@@ -509,7 +562,7 @@ public final class PropertyBindingSupport {
                 }
             } else if (value.toString().equals("#autowired")) {
                 // we should get the type from the setter
-                Method method = findBestSetterMethod(target.getClass(), name, 
fluentBuilder, allowPrivateSetter);
+                Method method = findBestSetterMethod(target.getClass(), name, 
fluentBuilder, allowPrivateSetter, ignoreCase);
                 if (method != null) {
                     Class<?> parameterType = method.getParameterTypes()[0];
                     if (parameterType != null) {
@@ -526,7 +579,7 @@ public final class PropertyBindingSupport {
             }
         }
 
-        boolean hit = IntrospectionSupport.setProperty(context, 
context.getTypeConverter(), target, name, value, refName, fluentBuilder, 
allowPrivateSetter);
+        boolean hit = IntrospectionSupport.setProperty(context, 
context.getTypeConverter(), target, name, value, refName, fluentBuilder, 
allowPrivateSetter, ignoreCase);
         if (!hit && mandatory) {
             // there is no setter with this given name, so lets report this as 
a problem
             throw new IllegalArgumentException("Cannot find setter method: " + 
name + " on bean: " + target + " when binding property: " + ognlPath);
@@ -534,7 +587,7 @@ public final class PropertyBindingSupport {
         return hit;
     }
 
-    private static Object getOrElseProperty(Object target, String property, 
Object defaultValue) {
+    private static Object getOrElseProperty(Object target, String property, 
Object defaultValue, boolean ignoreCase) {
         String key = property;
         String lookupKey = null;
 
@@ -545,7 +598,7 @@ public final class PropertyBindingSupport {
             key = property.substring(0, pos);
         }
 
-        Object answer = IntrospectionSupport.getOrElseProperty(target, key, 
defaultValue);
+        Object answer = IntrospectionSupport.getOrElseProperty(target, key, 
defaultValue, ignoreCase);
         if (answer instanceof Map && lookupKey != null) {
             Map map = (Map) answer;
             answer = map.getOrDefault(lookupKey, defaultValue);
@@ -566,16 +619,17 @@ public final class PropertyBindingSupport {
         return answer != null ? answer : defaultValue;
     }
 
-    private static Method findBestSetterMethod(Class clazz, String name, 
boolean fluentBuilder, boolean allowPrivateSetter) {
+    private static Method findBestSetterMethod(Class clazz, String name,
+                                               boolean fluentBuilder, boolean 
allowPrivateSetter, boolean ignoreCase) {
         // is there a direct setter?
-        Set<Method> candidates = findSetterMethods(clazz, name, fluentBuilder, 
allowPrivateSetter);
+        Set<Method> candidates = findSetterMethods(clazz, name, false, 
allowPrivateSetter, ignoreCase);
         if (candidates.size() == 1) {
             return candidates.iterator().next();
         }
 
         // okay now try with builder pattern
         if (fluentBuilder) {
-            candidates = findSetterMethods(clazz, name, fluentBuilder, 
allowPrivateSetter);
+            candidates = findSetterMethods(clazz, name, fluentBuilder, 
allowPrivateSetter, ignoreCase);
             if (candidates.size() == 1) {
                 return candidates.iterator().next();
             }
@@ -584,11 +638,18 @@ public final class PropertyBindingSupport {
         return null;
     }
 
-    private static Class getGetterType(Object target, String name) {
+    private static Class getGetterType(Object target, String name, boolean 
ignoreCase) {
         try {
-            Method getter = 
IntrospectionSupport.getPropertyGetter(target.getClass(), name);
-            if (getter != null) {
-                return getter.getReturnType();
+            if (ignoreCase) {
+                Method getter = 
IntrospectionSupport.getPropertyGetter(target.getClass(), name, true);
+                if (getter != null) {
+                    return getter.getReturnType();
+                }
+            } else {
+                Method getter = 
IntrospectionSupport.getPropertyGetter(target.getClass(), name);
+                if (getter != null) {
+                    return getter.getReturnType();
+                }
             }
         } catch (NoSuchMethodException e) {
             // ignore

Reply via email to