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 62f3378470c CAMEL-21817: camel-bean: add support for invoking methods
with vararg… (#17318)
62f3378470c is described below
commit 62f3378470cfd47b6041b02c54234e646f8b835a
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Mar 1 11:28:22 2025 +0000
CAMEL-21817: camel-bean: add support for invoking methods with vararg…
(#17318)
* CAMEL-21817: camel-bean: add support for invoking methods with vararg
parameters
---
.../org/apache/camel/component/bean/BeanInfo.java | 9 +-
.../apache/camel/component/bean/MethodInfo.java | 139 ++++++++++++++-------
.../apache/camel/component/bean/ParameterInfo.java | 9 +-
.../component/bean/BeanParameterInfoTest.java | 2 +-
.../component/bean/BeanVarargsInject4Test.java | 61 +++++++++
.../component/bean/BeanVarargsInject5Test.java | 62 +++++++++
.../component/bean/BeanVarargsInject6Test.java | 64 ++++++++++
.../component/bean/BeanVarargsInject7Test.java | 67 ++++++++++
8 files changed, 362 insertions(+), 51 deletions(-)
diff --git
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
index cc0402c9510..aa8e1d9e0f0 100644
---
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
+++
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java
@@ -286,7 +286,7 @@ public class BeanInfo {
// and therefore use arrayLength from ObjectHelper to return the
array length field.
Method method =
org.apache.camel.util.ObjectHelper.class.getMethod("arrayLength",
Object[].class);
ParameterInfo pi = new ParameterInfo(
- 0, Object[].class, null,
ExpressionBuilder.mandatoryBodyExpression(Object[].class, true));
+ 0, Object[].class, false, null,
ExpressionBuilder.mandatoryBodyExpression(Object[].class, true));
List<ParameterInfo> lpi = new ArrayList<>(1);
lpi.add(pi);
methodInfo = new MethodInfo(exchange.getContext(),
pojo.getClass(), method, lpi, lpi, false, false);
@@ -447,6 +447,7 @@ public class BeanInfo {
boolean hasHandlerAnnotation =
org.apache.camel.util.ObjectHelper.hasAnnotation(method.getAnnotations(),
Handler.class);
int size = parameterTypes.length;
+
if (LOG.isTraceEnabled()) {
LOG.trace("Creating MethodInfo for class: {} method: {} having {}
parameters", clazz, method, size);
}
@@ -457,13 +458,15 @@ public class BeanInfo {
= parametersAnnotations[i].toArray(new Annotation[0]);
Expression expression = createParameterUnmarshalExpression(method,
parameterType, parameterAnnotations);
hasCustomAnnotation |= expression != null;
+ // whether this parameter is vararg which must be last parameter
+ boolean varargs = method.isVarArgs() && i == size - 1;
- ParameterInfo parameterInfo = new ParameterInfo(i, parameterType,
parameterAnnotations, expression);
+ ParameterInfo parameterInfo = new ParameterInfo(i, parameterType,
varargs, parameterAnnotations, expression);
LOG.trace("Parameter #{}: {}", i, parameterInfo);
parameters.add(parameterInfo);
if (expression == null) {
boolean bodyAnnotation =
org.apache.camel.util.ObjectHelper.hasAnnotation(parameterAnnotations,
Body.class);
- LOG.trace("Parameter #{} has @Body annotation", i);
+ LOG.trace("Parameter #{} has @Body annotation: {}", i,
bodyAnnotation);
hasCustomAnnotation |= bodyAnnotation;
if (bodyParameters.isEmpty()) {
// okay we have not yet set the body parameter and we have
found
diff --git
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/MethodInfo.java
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/MethodInfo.java
index 1d601e5cec6..6b553fcd073 100644
---
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/MethodInfo.java
+++
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/MethodInfo.java
@@ -21,6 +21,7 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
@@ -608,31 +609,36 @@ public class MethodInfo {
* Evaluates all the parameter expressions
*/
private Object[] evaluateParameterExpressions(Exchange exchange,
Object body, Iterator<?> it) {
- Object[] answer = new Object[expressions.length];
- for (int i = 0; i < expressions.length; i++) {
-
+ Object[] answer = new Object[expressions != null ?
expressions.length : 1];
+ for (int i = 0; expressions == null || i < expressions.length;
i++) {
if (body instanceof StreamCache) {
// need to reset stream cache for each expression as you
may access the message body in multiple parameters
((StreamCache) body).reset();
}
- // grab the parameter value for the given index
- Object parameterValue = it != null && it.hasNext() ? it.next()
: null;
+ // whether its vararg
+ boolean varargs = parameters.get(i).isVarargs();
// and the expected parameter type
Class<?> parameterType = parameters.get(i).getType();
// the value for the parameter to use
Object value = null;
- // prefer to use parameter value if given, as they override
any bean parameter binding
- // we should skip * as its a type placeholder to indicate any
type
- if (parameterValue != null && !parameterValue.equals("*")) {
- // evaluate the parameter value binding
- value = evaluateParameterValue(exchange, i,
parameterValue, parameterType);
+ if (varargs) {
+ value = evaluateVarargsParameterExpressions(exchange,
body, it);
+ } else {
+ // grab the parameter value for the given index
+ Object parameterValue = it != null && it.hasNext() ?
it.next() : null;
+ // prefer to use parameter value if given, as they
override any bean parameter binding
+ // we should skip * as its a type placeholder to indicate
any type
+ if (parameterValue != null && !parameterValue.equals("*"))
{
+ // evaluate the parameter value binding
+ value = evaluateParameterValue(exchange, i,
parameterValue, parameterType, false);
+ }
}
// use bean parameter binding, if still no value
- Expression expression = expressions[i];
+ Expression expression = expressions != null ? expressions[i] :
null;
if (value == null && expression != null) {
- value = evaluateParameterBinding(exchange, expression, i,
parameterType);
+ value = evaluateParameterBinding(exchange, expression, i,
parameterType, false);
}
// remember the value to use
if (value != Void.TYPE) {
@@ -643,6 +649,35 @@ public class MethodInfo {
return answer;
}
+ /**
+ * Evaluate the remainder parameter as a single vararg
+ */
+ private Object evaluateVarargsParameterExpressions(Exchange exchange,
Object body, Iterator<?> it) {
+ // special for varargs
+ if (body instanceof StreamCache) {
+ // need to reset stream cache for each expression as you may
access the message body in multiple parameters
+ ((StreamCache) body).reset();
+ }
+ List<Object> answer = new ArrayList<>();
+ int i = 0;
+ while (it.hasNext()) {
+ Object parameterValue = it.next();
+ Object value = null;
+ // prefer to use parameter value if given, as they override
any bean parameter binding
+ // we should skip * as its a type placeholder to indicate any
type
+ if (parameterValue != null && !parameterValue.equals("*")) {
+ // evaluate the parameter value binding
+ value = evaluateParameterValue(exchange, i,
parameterValue, Object.class, true);
+ }
+ // remember the value to use
+ if (value != Void.TYPE) {
+ answer.add(value);
+ }
+ i++;
+ }
+ return answer.toArray(new Object[0]);
+ }
+
/**
* Evaluate using parameter values where the values can be provided in
the method name syntax.
* <p/>
@@ -654,7 +689,9 @@ public class MethodInfo {
* <li>a non <tt>null</tt> value - if the parameter was a parameter
value, and to be used</li>
* </ul>
*/
- private Object evaluateParameterValue(Exchange exchange, int index,
Object parameterValue, Class<?> parameterType) {
+ private Object evaluateParameterValue(
+ Exchange exchange, int index, Object parameterValue, Class<?>
parameterType,
+ boolean varargs) {
Object answer = null;
// convert the parameter value to a String
@@ -669,7 +706,7 @@ public class MethodInfo {
// check if its a valid parameter value (no type declared via
.class syntax)
valid = BeanHelper.isValidParameterValue(exp);
- if (!valid) {
+ if (!valid && !varargs) {
// it may be a parameter type instead, and if so, then we
should return null,
// as this method is only for evaluating parameter values
Boolean isClass =
BeanHelper.isAssignableToExpectedType(exchange.getContext().getClassResolver(),
exp,
@@ -703,7 +740,7 @@ public class MethodInfo {
}
// the parameter value may match the expected type, then we
use it as-is
- if (parameterType.isAssignableFrom(parameterValue.getClass()))
{
+ if (varargs ||
parameterType.isAssignableFrom(parameterValue.getClass())) {
valid = true;
} else {
// String values from the simple language is always valid
@@ -724,20 +761,25 @@ public class MethodInfo {
if (parameterValue instanceof String) {
parameterValue =
StringHelper.removeLeadingAndEndingQuotes((String) parameterValue);
}
- try {
- // it is a valid parameter value, so convert it to the
expected type of the parameter
- answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType,
exchange,
- parameterValue);
- if (LOG.isTraceEnabled()) {
- LOG.trace("Parameter #{} evaluated as: {} type:
{}", index, answer,
-
org.apache.camel.util.ObjectHelper.type(answer));
- }
- } catch (Exception e) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Cannot convert from type: {} to type:
{} for parameter #{}",
-
org.apache.camel.util.ObjectHelper.type(parameterValue), parameterType, index);
+ if (varargs) {
+ // use the value as-is
+ answer = parameterValue;
+ } else {
+ try {
+ // it is a valid parameter value, so convert it to
the expected type of the parameter
+ answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType,
exchange,
+ parameterValue);
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Parameter #{} evaluated as: {}
type: {}", index, answer,
+
org.apache.camel.util.ObjectHelper.type(answer));
+ }
+ } catch (Exception e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Cannot convert from type: {} to
type: {} for parameter #{}",
+
org.apache.camel.util.ObjectHelper.type(parameterValue), parameterType, index);
+ }
+ throw new ParameterBindingException(e, method,
index, parameterType, parameterValue);
}
- throw new ParameterBindingException(e, method, index,
parameterType, parameterValue);
}
}
}
@@ -748,30 +790,35 @@ public class MethodInfo {
/**
* Evaluate using classic parameter binding using the pre compute
expression
*/
- private Object evaluateParameterBinding(Exchange exchange, Expression
expression, int index, Class<?> parameterType) {
+ private Object evaluateParameterBinding(
+ Exchange exchange, Expression expression, int index, Class<?>
parameterType, boolean varargs) {
Object answer = null;
// use object first to avoid type conversion so we know if there
is a value or not
Object result = expression.evaluate(exchange, Object.class);
if (result != null) {
- try {
- if (parameterType.isInstance(result)) {
- // optimize if the value is already the same type
- answer = result;
- } else {
- // we got a value now try to convert it to the
expected type
- answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType,
result);
- }
- if (LOG.isTraceEnabled()) {
- LOG.trace("Parameter #{} evaluated as: {} type: {}",
index, answer,
-
org.apache.camel.util.ObjectHelper.type(answer));
- }
- } catch (NoTypeConversionAvailableException e) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Cannot convert from type: {} to type: {}
for parameter #{}",
-
org.apache.camel.util.ObjectHelper.type(result), parameterType, index);
+ if (varargs) {
+ answer = result;
+ } else {
+ try {
+ if (parameterType.isInstance(result)) {
+ // optimize if the value is already the same type
+ answer = result;
+ } else {
+ // we got a value now try to convert it to the
expected type
+ answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType,
result);
+ }
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Parameter #{} evaluated as: {} type:
{}", index, answer,
+
org.apache.camel.util.ObjectHelper.type(answer));
+ }
+ } catch (NoTypeConversionAvailableException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Cannot convert from type: {} to type:
{} for parameter #{}",
+
org.apache.camel.util.ObjectHelper.type(result), parameterType, index);
+ }
+ throw new ParameterBindingException(e, method, index,
parameterType, result);
}
- throw new ParameterBindingException(e, method, index,
parameterType, result);
}
} else {
LOG.trace("Parameter #{} evaluated as null", index);
diff --git
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/ParameterInfo.java
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/ParameterInfo.java
index 7a593f4da1d..a3d14f21a85 100644
---
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/ParameterInfo.java
+++
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/ParameterInfo.java
@@ -28,12 +28,14 @@ final class ParameterInfo {
private final int index;
private final Class<?> type;
+ private final boolean varargs;
private final Annotation[] annotations;
private Expression expression;
- ParameterInfo(int index, Class<?> type, Annotation[] annotations,
Expression expression) {
+ ParameterInfo(int index, Class<?> type, boolean varargs, Annotation[]
annotations, Expression expression) {
this.index = index;
this.type = type;
+ this.varargs = varargs;
this.annotations = annotations;
this.expression = expression;
}
@@ -54,6 +56,10 @@ final class ParameterInfo {
return type;
}
+ public boolean isVarargs() {
+ return varargs;
+ }
+
public void setExpression(Expression expression) {
this.expression = expression;
}
@@ -64,6 +70,7 @@ final class ParameterInfo {
sb.append("ParameterInfo");
sb.append("[index=").append(index);
sb.append(", type=").append(type);
+ sb.append(", varargs=").append(varargs);
sb.append(", annotations=").append(annotations == null ? "null" :
Arrays.asList(annotations).toString());
sb.append(", expression=").append(expression);
sb.append(']');
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterInfoTest.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterInfoTest.java
index c6b1e3b1e44..03373ff0c68 100644
---
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterInfoTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanParameterInfoTest.java
@@ -31,7 +31,7 @@ public class BeanParameterInfoTest extends ContextTestSupport
{
@Test
public void testMethodPatternUsingMethodAnnotations() {
Class<?> foo = Foo.class.getClass();
- ParameterInfo info = new ParameterInfo(1, foo.getClass(),
foo.getAnnotations(), null);
+ ParameterInfo info = new ParameterInfo(1, foo.getClass(), false,
foo.getAnnotations(), null);
assertNotNull(info);
assertNotNull(info.toString());
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject4Test.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject4Test.java
new file mode 100644
index 00000000000..b4d13dd5100
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject4Test.java
@@ -0,0 +1,61 @@
+/*
+ * 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.component.bean;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.junit.jupiter.api.Test;
+
+public class BeanVarargsInject4Test extends ContextTestSupport {
+
+ private final MyBean myBean = new MyBean();
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ public void configure() {
+
from("direct:start").to("bean:myBean?method=doSomething(1,2,3)").to("mock:finish");
+ }
+ };
+ }
+
+ @Test
+ public void testVarargs() throws Exception {
+ MockEndpoint end = getMockEndpoint("mock:finish");
+ end.expectedBodiesReceived("Bye with 3 args");
+
+ sendBody("direct:start", "Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected Registry createCamelRegistry() throws Exception {
+ Registry answer = super.createCamelRegistry();
+ answer.bind("myBean", myBean);
+ return answer;
+ }
+
+ public static class MyBean {
+
+ public String doSomething(Object... args) {
+ return "Bye with " + args.length + " args";
+ }
+ }
+}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject5Test.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject5Test.java
new file mode 100644
index 00000000000..4cd394fa0c6
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject5Test.java
@@ -0,0 +1,62 @@
+/*
+ * 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.component.bean;
+
+import org.apache.camel.Body;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.junit.jupiter.api.Test;
+
+public class BeanVarargsInject5Test extends ContextTestSupport {
+
+ private final MyBean myBean = new MyBean();
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ public void configure() {
+
from("direct:start").to("bean:myBean?method=doSomething(*,1,2,3)").to("mock:finish");
+ }
+ };
+ }
+
+ @Test
+ public void testVarargs() throws Exception {
+ MockEndpoint end = getMockEndpoint("mock:finish");
+ end.expectedBodiesReceived("Bye Camel with 3 args");
+
+ sendBody("direct:start", "Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected Registry createCamelRegistry() throws Exception {
+ Registry answer = super.createCamelRegistry();
+ answer.bind("myBean", myBean);
+ return answer;
+ }
+
+ public static class MyBean {
+
+ public String doSomething(@Body String body, Object... args) {
+ return "Bye " + body + " with " + args.length + " args";
+ }
+ }
+}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject6Test.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject6Test.java
new file mode 100644
index 00000000000..632cb56e144
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject6Test.java
@@ -0,0 +1,64 @@
+/*
+ * 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.component.bean;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.junit.jupiter.api.Test;
+
+public class BeanVarargsInject6Test extends ContextTestSupport {
+
+ private final MyBean myBean = new MyBean();
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ public void configure() {
+
from("direct:start").to("bean:myBean?method=doSomething(${body},1,2,3)").to("mock:finish");
+ }
+ };
+ }
+
+ @Test
+ public void testVarargs() throws Exception {
+ MockEndpoint end = getMockEndpoint("mock:finish");
+ end.expectedBodiesReceived("Bye Camel with 3 args (sum=6)");
+
+ sendBody("direct:start", "Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected Registry createCamelRegistry() throws Exception {
+ Registry answer = super.createCamelRegistry();
+ answer.bind("myBean", myBean);
+ return answer;
+ }
+
+ public static class MyBean {
+
+ public String doSomething(String body, Object... args) {
+ int sum = Integer.parseInt((String) args[0]);
+ sum += Integer.parseInt((String) args[1]);
+ sum += Integer.parseInt((String) args[2]);
+ return "Bye " + body + " with " + args.length + " args (sum=" +
sum + ")";
+ }
+ }
+}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject7Test.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject7Test.java
new file mode 100644
index 00000000000..dae818a7950
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanVarargsInject7Test.java
@@ -0,0 +1,67 @@
+/*
+ * 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.component.bean;
+
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.junit.jupiter.api.Test;
+
+public class BeanVarargsInject7Test extends ContextTestSupport {
+
+ private final MyBean myBean = new MyBean();
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ public void configure() {
+
from("direct:start").to("bean:myBean?method=doSomething(${header.myArr},1,2,3)").to("mock:finish");
+ }
+ };
+ }
+
+ @Test
+ public void testVarargs() throws Exception {
+ MockEndpoint end = getMockEndpoint("mock:finish");
+ end.expectedBodiesReceived("Bye Camel with 3 args (sum=6)");
+
+ Object[] arr = new Object[] { "Cam", "el" };
+ sendBody("direct:start", "World", Map.of("myArr", arr));
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected Registry createCamelRegistry() throws Exception {
+ Registry answer = super.createCamelRegistry();
+ answer.bind("myBean", myBean);
+ return answer;
+ }
+
+ public static class MyBean {
+
+ public String doSomething(Object[] arr, Object... args) {
+ int sum = Integer.parseInt((String) args[0]);
+ sum += Integer.parseInt((String) args[1]);
+ sum += Integer.parseInt((String) args[2]);
+ return "Bye " + arr[0] + arr[1] + " with " + args.length + " args
(sum=" + sum + ")";
+ }
+ }
+}