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 a421bf83c9fc5628731db50da81d7b9372c15ad7
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Nov 15 16:05:43 2020 +0100

    CAMEL-15852: PropertyBindingSupport should support dots in map keys
---
 .../PropertyBindingSupportMapDotKeyTest.java       | 76 ++++++++++++++++++++++
 .../camel/support/PropertyBindingSupport.java      | 58 +++++++++++++++--
 2 files changed, 130 insertions(+), 4 deletions(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapDotKeyTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapDotKeyTest.java
new file mode 100644
index 0000000..c3bf109
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapDotKeyTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.support;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Unit test for PropertyBindingSupport
+ */
+public class PropertyBindingSupportMapDotKeyTest extends ContextTestSupport {
+
+    @Test
+    public void testPropertiesMapDotKey() throws Exception {
+        Foo foo = new Foo();
+
+        Map<String, Object> prop = new LinkedHashMap<>();
+        prop.put("name", "James");
+        prop.put("data[age]", "33");
+        prop.put("data[zip.code]", "90210");
+        prop.put("data[ISO.CODE]", "USA");
+        prop.put("data[with-dash]", "123");
+        prop.put("data[with_underscore]", "456");
+
+        PropertyBindingSupport.build().bind(context, foo, prop);
+
+        assertEquals("James", foo.getName());
+        assertEquals("33", foo.getData().get("age"));
+        assertEquals("90210", foo.getData().get("zip.code"));
+        assertEquals("USA", foo.getData().get("ISO.CODE"));
+        assertEquals("123", foo.getData().get("with-dash"));
+        assertEquals("456", foo.getData().get("with_underscore"));
+    }
+
+    public static class Foo {
+        private String name;
+        private Map<String, String> data = new HashMap<>();
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public Map<String, String> getData() {
+            return data;
+        }
+
+        public void setData(Map<String, String> data) {
+            this.data = data;
+        }
+    }
+
+}
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 342bf29..bec7363 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
@@ -201,7 +201,7 @@ public final class PropertyBindingSupport {
             Object value = entry.getValue();
 
             // if nesting is not allowed, then only bind properties without 
dots (OGNL graph)
-            if (!nesting && key.indexOf('.') != -1) {
+            if (!nesting && isDotKey(key)) {
                 continue;
             }
 
@@ -217,6 +217,56 @@ public final class PropertyBindingSupport {
         return answer;
     }
 
+    // TODO: Move these methods to other location
+    private static String[] splitKey(String key) {
+        List<String> parts = new ArrayList<>();
+
+        boolean mapKey = false;
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < key.length(); i++) {
+            char ch = key.charAt(i);
+            if (ch == '[') {
+                mapKey = true;
+            } else if (ch == ']') {
+                mapKey = false;
+            }
+            if (ch == '.' && !mapKey) {
+                // dont include the separator dot
+                parts.add(sb.toString());
+                sb.setLength(0);
+            } else {
+                sb.append(ch);
+            }
+        }
+        if (sb.length() > 0) {
+            parts.add(sb.toString());
+        }
+
+        return parts.toArray(new String[parts.size()]);
+    }
+
+    private static boolean isDotKey(String key) {
+        // we only want to know if there is a dot in OGNL path, so any map 
keys [iso.code] is accepted
+
+        if (key.indexOf('[') == -1 && key.indexOf('.') != -1) {
+            return true;
+        }
+
+        boolean mapKey = false;
+        for (int i = 0; i < key.length(); i++) {
+            char ch = key.charAt(i);
+            if (ch == '[') {
+                mapKey = true;
+            } else if (ch == ']') {
+                mapKey = false;
+            }
+            if (ch == '.' && !mapKey) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static boolean doBuildPropertyOgnlPath(
             final CamelContext camelContext, final Object originalTarget, 
String name, final Object value,
             boolean deepNesting, boolean fluentBuilder, boolean 
allowPrivateSetter,
@@ -239,8 +289,8 @@ public final class PropertyBindingSupport {
 
         // we should only walk and create OGNL path for the middle graph
         String[] parts;
-        if (name.contains(".")) {
-            parts = name.split("\\.");
+        if (isDotKey(name)) {
+            parts = splitKey(name);
         } else {
             parts = new String[] { name };
         }
@@ -1808,7 +1858,7 @@ public final class PropertyBindingSupport {
             // so we can remove the corresponding key from the original map
 
             // walk key with dots to remove right node
-            String[] parts = key.toString().split("\\.");
+            String[] parts = splitKey(key.toString());
             Map map = originalMap;
             for (int i = 0; i < parts.length; i++) {
                 String part = parts[i];

Reply via email to