You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/11/30 09:21:57 UTC
(camel) 01/04: CAMEL-20130: camel-core - PropertyBuilderSupport add support for fluent builder classes.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch builder-class
in repository https://gitbox.apache.org/repos/asf/camel.git
commit c65bdb48409e7ee05d7523a53c604267db7386fc
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Nov 30 09:32:43 2023 +0100
CAMEL-20130: camel-core - PropertyBuilderSupport add support for fluent builder classes.
---
.../PropertyBindingSupportBuildMethodTest.java | 104 +++++++++++++++++++++
.../camel/support/PropertyBindingSupport.java | 31 ++++++
.../modules/ROOT/pages/property-binding.adoc | 51 ++++++++++
3 files changed, 186 insertions(+)
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/PropertyBindingSupportBuildMethodTest.java b/core/camel-main/src/test/java/org/apache/camel/main/PropertyBindingSupportBuildMethodTest.java
new file mode 100644
index 00000000000..507b686f704
--- /dev/null
+++ b/core/camel-main/src/test/java/org/apache/camel/main/PropertyBindingSupportBuildMethodTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.main;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.PropertyBindingSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit test for PropertyBindingSupport
+ */
+public class PropertyBindingSupportBuildMethodTest {
+
+ @Test
+ public void testBuildClass() throws Exception {
+ CamelContext context = new DefaultCamelContext();
+
+ context.start();
+
+ MyDriver driver = PropertyBindingSupport.build()
+ .withCamelContext(context)
+ .withTarget(new MyDriverBuilder())
+ .withFluentBuilder(true)
+ .withProperty("url", "localhost:1234")
+ .withProperty("username", "scott")
+ .withProperty("password", "tiger")
+ .build(MyDriver.class);
+
+ Assertions.assertNotNull(driver);
+ Assertions.assertEquals("localhost:1234", driver.getUrl());
+ Assertions.assertEquals("scott", driver.getUsername());
+ Assertions.assertEquals("tiger", driver.getPassword());
+
+ context.stop();
+ }
+
+ public static class MyDriver {
+
+ private final String url;
+ private final String username;
+ private final String password;
+
+ public MyDriver(String url, String username, String password) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+ }
+
+ public static class MyDriverBuilder {
+
+ private String url;
+ private String username;
+ private String password;
+
+ public MyDriverBuilder url(String url) {
+ this.url = url;
+ return this;
+ }
+
+ public MyDriverBuilder username(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public MyDriverBuilder password(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public MyDriver build() {
+ return new MyDriver(url, username, password);
+ }
+ }
+
+}
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 7d766645ee1..5f6bcaae369 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
@@ -38,6 +38,7 @@ import java.util.stream.Collectors;
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
import org.apache.camel.PropertyBindingException;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.spi.BeanIntrospection;
import org.apache.camel.spi.PropertiesComponent;
import org.apache.camel.spi.PropertyConfigurer;
@@ -1874,6 +1875,36 @@ public final class PropertyBindingSupport {
return this;
}
+ /**
+ * Binds the properties to the target object, and builds the output as the given type, by invoking the build
+ * method (uses build as name)
+ *
+ * @param type the type of the output class
+ */
+ public <T> T build(Class<T> type) {
+ return build(type, "build");
+ }
+
+ /**
+ * Binds the properties to the target object, and builds the output as the given type, by invoking the build
+ * method (via reflection).
+ *
+ * @param type the type of the output class
+ * @param buildMethod the name of the builder method to invoke
+ */
+ public <T> T build(Class<T> type, String buildMethod) {
+ // first bind
+ bind();
+
+ // then invoke the build method on target via reflection
+ try {
+ Object out = ObjectHelper.invokeMethodSafe(buildMethod, target);
+ return camelContext.getTypeConverter().convertTo(type, out);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeException(e);
+ }
+ }
+
/**
* Binds the properties to the target object, and removes the property that was bound from properties.
*
diff --git a/docs/user-manual/modules/ROOT/pages/property-binding.adoc b/docs/user-manual/modules/ROOT/pages/property-binding.adoc
index 8687eee222c..31d578cebd6 100644
--- a/docs/user-manual/modules/ROOT/pages/property-binding.adoc
+++ b/docs/user-manual/modules/ROOT/pages/property-binding.adoc
@@ -193,6 +193,57 @@ PropertyBindingSupport.build().withCamelContext(context).withTarget(foo)
.bind();
----
+=== Using fluent builder class
+
+When you are in need to configure a bean via _fluent builder class_, such as the following example:
+
+[source,java]
+----
+public class MyDriverBuilder {
+
+ private String url;
+ private String username;
+ private String password;
+
+ public MyDriverBuilder url(String url) {
+ this.url = url;
+ return this;
+ }
+
+ public MyDriverBuilder username(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public MyDriverBuilder password(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public MyDriver build() {
+ return new MyDriver(url, username, password);
+ }
+}
+----
+
+And you want to create an instance of `MyDriver` via the `MyDriverBuilder` class, then this can be done as follows:
+
+[source,java]
+----
+MyDriver driver = PropertyBindingSupport.build()
+ .withCamelContext(context)
+ .withTarget(new MyDriverBuilder())
+ .withFluentBuilder(true)
+ .withProperty("url", "localhost:1234")
+ .withProperty("username", "scott")
+ .withProperty("password", "tiger")
+ .build(MyDriver.class);
+----
+
+Notice how we use the `build(MyDriver.class)` to build the bean via the target class `.withTarget(new MyDriverBuilder())`.
+The build method will by default invoke `build` as the builder method, but you can specify the name, such as `.build(MyDriver.class, "myBuilderMethod");`
+
+
== More details
Property binding is notably used when running Camel in standalone mode with Camel Main, or using Camel Spring Boot, Camel K,