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 2019/05/23 19:30:54 UTC
[camel] 08/18: CAMEL-13557: Add property binding support to make it
convenient to configure components and whatnot.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch 13557
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 5ac8ff8a4f600d65d009afb5687f2aeb8990bc8a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu May 23 07:54:29 2019 +0200
CAMEL-13557: Add property binding support to make it convenient to configure components and whatnot.
---
.../org/apache/camel/PropertyBindingException.java | 46 +++++++++
.../camel/support/PropertyBindingSupportTest.java | 19 ++++
.../camel/support/PropertyBindingSupport.java | 114 ++++++++++++---------
3 files changed, 131 insertions(+), 48 deletions(-)
diff --git a/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java b/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java
new file mode 100644
index 0000000..ed6e61b
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * Error binding property to a bean.
+ */
+public class PropertyBindingException extends RuntimeCamelException {
+
+ private final Object target;
+ private final String propertyName;
+
+ public PropertyBindingException(Object target, String propertyName) {
+ super("No such property: " + propertyName + " on bean: " + target);
+ this.target = target;
+ this.propertyName = propertyName;
+ }
+
+ public PropertyBindingException(Object target, String propertyName, Exception e) {
+ super("Error binding property: " + propertyName + " on bean: " + target, e);
+ this.target = target;
+ this.propertyName = propertyName;
+ }
+
+ public Object getTarget() {
+ return target;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
index e6e4245..b3f32c7 100644
--- a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java
@@ -22,6 +22,7 @@ import java.util.Properties;
import org.apache.camel.CamelContext;
import org.apache.camel.ContextTestSupport;
+import org.apache.camel.PropertyBindingException;
import org.junit.Test;
/**
@@ -142,6 +143,24 @@ public class PropertyBindingSupportTest extends ContextTestSupport {
assertEquals(null, foo.getBar().getWork().getName());
}
+ @Test
+ public void testMandatory() throws Exception {
+ Foo foo = new Foo();
+
+ PropertyBindingSupport.bindMandatoryProperty(context, foo, "name", "James");
+
+ boolean bound = PropertyBindingSupport.bindProperty(context, foo, "bar.myAge", "33");
+ assertFalse(bound);
+
+ try {
+ PropertyBindingSupport.bindMandatoryProperty(context, foo, "bar.myAge", "33");
+ fail("Should have thrown exception");
+ } catch (PropertyBindingException e) {
+ assertEquals("bar.myAge", e.getPropertyName());
+ assertSame(foo, e.getTarget());
+ }
+ }
+
public static class Foo {
private String name;
private Bar bar = new Bar();
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 1577b14..5d06df4 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
@@ -1,13 +1,13 @@
-/**
+/*
* 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+ *
+ * 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.
@@ -21,7 +21,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.camel.CamelContext;
-import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.PropertyBindingException;
import static org.apache.camel.support.IntrospectionSupport.findSetterMethods;
import static org.apache.camel.support.IntrospectionSupport.getOrElseProperty;
@@ -41,7 +41,7 @@ import static org.apache.camel.support.IntrospectionSupport.getOrElseProperty;
public final class PropertyBindingSupport {
// TODO: Add support for auto binding to singleton instance by type from registry (boolean on|off)
- // TODO: Better exception message if something goes wrong (output target, name of property etc)
+ // TODO: Add support for Map/List
private PropertyBindingSupport() {
}
@@ -52,12 +52,12 @@ public final class PropertyBindingSupport {
* @param camelContext the camel context
* @param target the target object
* @param properties the properties
- * @return true if one or more properties was bound, false otherwise
+ * @return true if all the properties was bound, false otherwise
*/
- public static boolean bindProperties(CamelContext camelContext, Object target, Map<String, Object> properties) throws Exception {
- boolean answer = false;
+ public static boolean bindProperties(CamelContext camelContext, Object target, Map<String, Object> properties) {
+ boolean answer = true;
for (Map.Entry<String, Object> entry : properties.entrySet()) {
- answer |= bindProperty(camelContext, target, entry.getKey(), entry.getValue());
+ answer &= bindProperty(camelContext, target, entry.getKey(), entry.getValue());
}
return answer;
}
@@ -71,15 +71,40 @@ public final class PropertyBindingSupport {
* @param value value of property
* @return true if property was bound, false otherwise
*/
- public static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value) throws Exception {
- if (target != null && name != null) {
- return setProperty(camelContext, target, name, value);
- } else {
- return false;
+ public static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value) {
+ try {
+ if (target != null && name != null) {
+ return setProperty(camelContext, target, name, value);
+ }
+ } catch (Exception e) {
+ throw new PropertyBindingException(target, name, e);
}
+
+ return false;
}
- private static boolean setProperty(CamelContext context, Object target, String name, Object value) {
+ /**
+ * Binds the mandatory property to the target object (will fail if not set/bound).
+ *
+ * @param camelContext the camel context
+ * @param target the target object
+ * @param name name of property
+ * @param value value of property
+ */
+ public static void bindMandatoryProperty(CamelContext camelContext, Object target, String name, Object value) {
+ try {
+ if (target != null && name != null) {
+ boolean bound = setProperty(camelContext, target, name, value);
+ if (!bound) {
+ throw new PropertyBindingException(target, name);
+ }
+ }
+ } catch (Exception e) {
+ throw new PropertyBindingException(target, name, e);
+ }
+ }
+
+ private static boolean setProperty(CamelContext context, Object target, String name, Object value) throws Exception {
Class<?> clazz = target.getClass();
String refName = null;
@@ -120,43 +145,36 @@ public final class PropertyBindingSupport {
}
}
// okay we found a nested property, then lets change to use that
- try {
- target = newTarget;
- name = parts[parts.length - 1];
- if (value instanceof String) {
- if (value.toString().startsWith("class:")) {
- // its a new class to be created
- String className = value.toString().substring(6);
- Class<?> type = context.getClassResolver().resolveMandatoryClass(className);
- if (type != null) {
- value = context.getInjector().newInstance(type);
- }
- } else if (value.toString().startsWith("#type:")) {
- // its reference by type, so lookup the actual value and use it if there is only one instance in the registry
- String typeName = value.toString().substring(6);
- Class<?> type = context.getClassResolver().resolveMandatoryClass(typeName);
- if (type != null) {
- Set<?> types = context.getRegistry().findByType(type);
- if (types.size() == 1) {
- value = types.iterator().next();
- }
- }
- } else if (EndpointHelper.isReferenceParameter(value.toString())) {
- // okay its a reference so swap to lookup this which is already supported in IntrospectionSupport
- refName = value.toString();
- value = null;
+ target = newTarget;
+ name = parts[parts.length - 1];
+ }
+
+ if (value instanceof String) {
+ if (value.toString().startsWith("class:")) {
+ // its a new class to be created
+ String className = value.toString().substring(6);
+ Class<?> type = context.getClassResolver().resolveMandatoryClass(className);
+ if (type != null) {
+ value = context.getInjector().newInstance(type);
+ }
+ } else if (value.toString().startsWith("#type:")) {
+ // its reference by type, so lookup the actual value and use it if there is only one instance in the registry
+ String typeName = value.toString().substring(6);
+ Class<?> type = context.getClassResolver().resolveMandatoryClass(typeName);
+ if (type != null) {
+ Set<?> types = context.getRegistry().findByType(type);
+ if (types.size() == 1) {
+ value = types.iterator().next();
}
}
- } catch (Exception e) {
- throw RuntimeCamelException.wrapRuntimeException(e);
+ } else if (EndpointHelper.isReferenceParameter(value.toString())) {
+ // okay its a reference so swap to lookup this which is already supported in IntrospectionSupport
+ refName = value.toString();
+ value = null;
}
}
- try {
- return IntrospectionSupport.setProperty(context, context.getTypeConverter(), target, name, value, refName, true);
- } catch (Exception e) {
- throw RuntimeCamelException.wrapRuntimeException(e);
- }
+ return IntrospectionSupport.setProperty(context, context.getTypeConverter(), target, name, value, refName, true);
}
}