This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new a3ac6af2d7c CAMEL-18856: camel-main - Unable to declare java.util.List
bean
a3ac6af2d7c is described below
commit a3ac6af2d7c557786741e59cd49e8491a96f170b
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jan 4 09:04:09 2023 +0100
CAMEL-18856: camel-main - Unable to declare java.util.List bean
---
.../org/apache/camel/util/ObjectHelperTest.java | 21 ++++++++++++++
.../org/apache/camel/main/BaseMainSupport.java | 11 ++++++--
.../java/org/apache/camel/main/MainHelper.java | 31 +++++++--------------
.../java/org/apache/camel/main/MainBeansTest.java | 30 ++++++++++++++++++++
.../camel/support/PropertyBindingSupport.java | 32 +++++++++-------------
.../java/org/apache/camel/util/ObjectHelper.java | 25 +++++++++++++++++
.../java/org/apache/camel/util/StringHelper.java | 9 ++++++
7 files changed, 116 insertions(+), 43 deletions(-)
diff --git
a/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
b/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
index 6818c586a77..4b48a7f9a5d 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
@@ -48,6 +48,7 @@ import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.DefaultMessage;
import org.apache.camel.support.ObjectHelper;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@@ -1078,4 +1079,24 @@ public class ObjectHelperTest {
StreamSupport.stream(ObjectHelper.createIterable(content,
";+", false, true).spliterator(), false)
.collect(Collectors.joining("-")));
}
+
+ @Test
+ public void testAddListByIndex() {
+ List<Object> list = new ArrayList<>();
+ org.apache.camel.util.ObjectHelper.addListByIndex(list, 0, "aaa");
+ org.apache.camel.util.ObjectHelper.addListByIndex(list, 2, "ccc");
+ org.apache.camel.util.ObjectHelper.addListByIndex(list, 1, "bbb");
+
+ Assertions.assertEquals(3, list.size());
+ Assertions.assertEquals("aaa", list.get(0));
+ Assertions.assertEquals("bbb", list.get(1));
+ Assertions.assertEquals("ccc", list.get(2));
+
+ org.apache.camel.util.ObjectHelper.addListByIndex(list, 99, "zzz");
+ Assertions.assertEquals(100, list.size());
+ Assertions.assertNull(list.get(4));
+ Assertions.assertNull(list.get(50));
+ Assertions.assertNull(list.get(98));
+ Assertions.assertEquals("zzz", list.get(99));
+ }
}
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 31a46faa36c..329eac41901 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -1409,8 +1409,13 @@ public abstract class BaseMainSupport extends
BaseService {
// create map beans if none already exists
for (String name : beansMap) {
if (camelContext.getRegistry().lookupByName(name) == null) {
- // register bean as a map
- Map<String, Object> bean = new LinkedHashMap<>();
+
+ // is the config list or map style
+ OrderedLocationProperties config =
MainHelper.extractProperties(properties, name + "[", "]", false);
+ boolean list =
config.keySet().stream().map(Object::toString).allMatch(StringHelper::isDigit);
+
+ // register bean as a list or map
+ Object bean = list ? new ArrayList<>() : new LinkedHashMap<>();
if (logSummary) {
LOG.info("Binding bean: {} (type: {}) to the registry",
name, ObjectHelper.classCanonicalName(bean));
} else {
@@ -1432,7 +1437,7 @@ public abstract class BaseMainSupport extends BaseService
{
setPropertiesOnTarget(camelContext, bean, config, optionPrefix +
name + ".", failIfNotSet, ignoreCase,
autoConfiguredProperties);
}
- // then set properties per bean (map style)
+ // then set properties per bean (map/list style)
for (String name : beansMap) {
Object bean = camelContext.getRegistry().lookupByName(name);
if (bean == null) {
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
index d4eb6aa1bdc..df8dcf85cd2 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
@@ -493,29 +493,16 @@ public final class MainHelper {
}
public static OrderedLocationProperties
extractProperties(OrderedLocationProperties properties, String optionPrefix) {
- if (properties == null) {
- return new OrderedLocationProperties();
- }
- OrderedLocationProperties rc = new OrderedLocationProperties();
-
- Set<Object> toRemove = new HashSet<>();
- for (var entry : properties.entrySet()) {
- String key = entry.getKey().toString();
- String loc = properties.getLocation(key);
- if (key.startsWith(optionPrefix)) {
- Object value = properties.get(key);
- key = key.substring(optionPrefix.length());
- rc.put(loc, key, value);
- toRemove.add(entry.getKey());
- }
- }
- toRemove.forEach(properties::remove);
-
- return rc;
+ return extractProperties(properties, optionPrefix, null, true);
}
public static OrderedLocationProperties extractProperties(
OrderedLocationProperties properties, String optionPrefix, String
optionSuffix) {
+ return extractProperties(properties, optionPrefix, optionSuffix, true);
+ }
+
+ public static OrderedLocationProperties extractProperties(
+ OrderedLocationProperties properties, String optionPrefix, String
optionSuffix, boolean remove) {
if (properties == null) {
return new OrderedLocationProperties();
}
@@ -528,11 +515,13 @@ public final class MainHelper {
if (key.startsWith(optionPrefix)) {
Object value = properties.get(key);
key = key.substring(optionPrefix.length());
- if (key.endsWith(optionSuffix)) {
+ if (optionSuffix != null && key.endsWith(optionSuffix)) {
key = key.substring(0, key.length() -
optionSuffix.length());
}
rc.put(loc, key, value);
- toRemove.add(entry.getKey());
+ if (remove) {
+ toRemove.add(entry.getKey());
+ }
}
}
toRemove.forEach(properties::remove);
diff --git
a/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
b/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
index dd704b2faae..6fa07348eb1 100644
--- a/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
+++ b/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.main;
+import java.util.List;
import java.util.Map;
import org.apache.camel.CamelContext;
@@ -23,6 +24,7 @@ import org.apache.camel.builder.RouteBuilder;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
@@ -141,6 +143,34 @@ public class MainBeansTest {
main.stop();
}
+ @Test
+ public void testBindBeansListSquare() throws Exception {
+ Main main = new Main();
+ main.configure().addRoutesBuilder(new MyRouteBuilder());
+
+ // defining a list bean (un-ordered)
+ main.addProperty("camel.beans.myprojects[0]", "Camel");
+ main.addProperty("camel.beans.myprojects[2]", "Quarkus");
+ main.addProperty("camel.beans.myprojects[1]", "Kafka");
+
+ main.start();
+
+ CamelContext camelContext = main.getCamelContext();
+ assertNotNull(camelContext);
+
+ Object bean = camelContext.getRegistry().lookupByName("myprojects");
+ assertNotNull(bean);
+ assertInstanceOf(List.class, bean);
+
+ List<?> list = (List<?>) bean;
+ assertEquals(3, list.size());
+ assertEquals("Camel", list.get(0));
+ assertEquals("Kafka", list.get(1));
+ assertEquals("Quarkus", list.get(2));
+
+ main.stop();
+ }
+
@Test
public void testBindBeansMapSquareDotKey() throws Exception {
Main main = new Main();
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 6ce1abb5b92..1288a6ea9b6 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
@@ -499,6 +499,18 @@ public final class PropertyBindingSupport {
((Map) target).put(key, value);
bound = true;
}
+ // if the target value is a list type (and key is digit),
+ // then we can skip reflection and set the entry
+ if (!bound && List.class.isAssignableFrom(target.getClass())
&& StringHelper.isDigit(key)) {
+ try {
+ // key must be digit
+ int idx = Integer.parseInt(key);
+
org.apache.camel.util.ObjectHelper.addListByIndex((List) target, idx, value);
+ bound = true;
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
if (!bound && reflection) {
// fallback to reflection based
bound = setSimplePropertyViaReflection(camelContext,
target, key, value, fluentBuilder, allowPrivateSetter,
@@ -585,25 +597,7 @@ public final class PropertyBindingSupport {
List list = (List) obj;
if (isNotEmpty(lookupKey)) {
int idx = Integer.parseInt(lookupKey);
- if (idx < list.size()) {
- list.set(idx, value);
- } else if (idx == list.size()) {
- list.add(value);
- } else {
- // If the list implementation is based on an array, we
- // can increase tha capacity to the required value to
- // avoid potential re-allocation weh invoking List::add.
- //
- // Note that ArrayList is the default List impl that
- // is automatically created if the property is null.
- if (list instanceof ArrayList) {
- ((ArrayList) list).ensureCapacity(idx + 1);
- }
- while (list.size() < idx) {
- list.add(null);
- }
- list.add(idx, value);
- }
+ org.apache.camel.util.ObjectHelper.addListByIndex(list, idx,
value);
} else {
list.add(value);
}
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
b/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
index e1afbbaea1f..35d8efe3466 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
@@ -1316,4 +1316,29 @@ public final class ObjectHelper {
return objects != null ? Arrays.asList(objects) :
Collections.emptyList();
}
+ /**
+ * Adds the value to the list at the given index
+ */
+ public static void addListByIndex(List<Object> list, int idx, Object
value) {
+ if (idx < list.size()) {
+ list.set(idx, value);
+ } else if (idx == list.size()) {
+ list.add(value);
+ } else {
+ // If the list implementation is based on an array, we
+ // can increase tha capacity to the required value to
+ // avoid potential re-allocation when invoking List::add.
+ //
+ // Note that ArrayList is the default List impl that
+ // is automatically created if the property is null.
+ if (list instanceof ArrayList) {
+ ((ArrayList<?>) list).ensureCapacity(idx + 1);
+ }
+ while (list.size() < idx) {
+ list.add(null);
+ }
+ list.add(idx, value);
+ }
+ }
+
}
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
b/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
index aff3b0bf298..26fb5d61bb0 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
@@ -1156,4 +1156,13 @@ public final class StringHelper {
}
}
+ public static boolean isDigit(String s) {
+ for (char ch : s.toCharArray()) {
+ if (!Character.isDigit(ch)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
}