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