This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch bind
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8412ba2b4f64b2ae8f280f190b0cc146083c4f4a
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Mon Mar 4 10:01:11 2019 +0100

    CAMEL-13283: Add @BindRegistry annotation to allow to bind beans/classes to 
registry.
---
 .../main/java/org/apache/camel/BindRegistry.java   | 37 ++++++++++++++++++++++
 .../camel/impl/DefaultCamelBeanPostProcessor.java  | 28 ++++++++++++++++
 .../impl/DefaultCamelBeanPostProcessorTest.java    | 13 ++++++++
 .../org/apache/camel/util/ReflectionHelper.java    | 18 +++++++++++
 4 files changed, 96 insertions(+)

diff --git a/core/camel-api/src/main/java/org/apache/camel/BindRegistry.java 
b/core/camel-api/src/main/java/org/apache/camel/BindRegistry.java
new file mode 100644
index 0000000..b2aebca
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/BindRegistry.java
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used for binding a bean to the registry
+ *
+ * If no name is specified then the bean will have its name auto computed 
based on the
+ * field name, or method name where the annotation is configured.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
+public @interface BindRegistry {
+    String name() default "";
+    String context() default "";
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelBeanPostProcessor.java
 
b/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelBeanPostProcessor.java
index 8b77e86..e7dc03f 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelBeanPostProcessor.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelBeanPostProcessor.java
@@ -20,6 +20,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 import org.apache.camel.BeanInject;
+import org.apache.camel.BindRegistry;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.DeferredContextBinding;
@@ -32,6 +33,8 @@ import org.apache.camel.util.ReflectionHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.camel.util.ObjectHelper.isEmpty;
+
 /**
  * A bean post processor which implements the <a 
href="http://camel.apache.org/bean-integration.html";>Bean Integration</a>
  * features in Camel. Features such as the <a 
href="http://camel.apache.org/bean-injection.html";>Bean Injection</a> of 
objects like
@@ -84,6 +87,16 @@ public class DefaultCamelBeanPostProcessor {
         injectFields(bean, beanName);
         injectMethods(bean, beanName);
 
+        // the bean may also need to be registered into the registry
+        BindRegistry bind = bean.getClass().getAnnotation(BindRegistry.class);
+        if (bind != null) {
+            String name = bind.name();
+            if (isEmpty(name)) {
+                name = bean.getClass().getSimpleName();
+            }
+            camelContext.getRegistry().bind(name, bean);
+        }
+
         if (bean instanceof CamelContextAware && canSetCamelContext(bean, 
beanName)) {
             CamelContextAware contextAware = (CamelContextAware)bean;
             DeferredContextBinding deferredBinding = 
bean.getClass().getAnnotation(DeferredContextBinding.class);
@@ -189,10 +202,25 @@ public class DefaultCamelBeanPostProcessor {
                 if (produce != null && 
getPostProcessorHelper().matchContext(produce.context())) {
                     injectField(field, produce.uri(), produce.ref(), 
produce.property(), bean, beanName, produce.binding());
                 }
+
+                BindRegistry bind = field.getAnnotation(BindRegistry.class);
+                if (bind != null && 
getPostProcessorHelper().matchContext(bind.context())) {
+                    bindRegistry(field, bind.name(), bean, beanName);
+                }
             }
         });
     }
 
+    private void bindRegistry(Field field, String name, Object bean, String 
beanName) {
+        if (isEmpty(name)) {
+            name = field.getName();
+        }
+        Object value = ReflectionHelper.getField(field, bean);
+        if (value != null) {
+            camelContext.getRegistry().bind(name, value);
+        }
+    }
+
     public void injectField(Field field, String endpointUri, String 
endpointRef, String endpointProperty,
                                Object bean, String beanName) {
         injectField(field, endpointUri, endpointRef, endpointProperty, bean, 
beanName, true);
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelBeanPostProcessorTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelBeanPostProcessorTest.java
index 006be1a..f6b7ef8 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelBeanPostProcessorTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelBeanPostProcessorTest.java
@@ -15,6 +15,8 @@
  * limitations under the License.
  */
 package org.apache.camel.impl;
+
+import org.apache.camel.BindRegistry;
 import org.apache.camel.Consume;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Produce;
@@ -38,6 +40,14 @@ public class DefaultCamelBeanPostProcessorTest extends 
ContextTestSupport {
         getMockEndpoint("mock:result").expectedMessageCount(1);
         template.sendBody("seda:input", "Hello World");
         assertMockEndpointsSatisfied();
+
+        // should register the beans in the registry via @BindRegistry
+        Object bean = context.getRegistry().lookupByName("myCoolBean");
+        assertNotNull(bean);
+        assertIsInstanceOf(MySerialBean.class, bean);
+        bean = context.getRegistry().lookupByName("FooService");
+        assertNotNull(bean);
+        assertIsInstanceOf(FooService.class, bean);
     }
 
     @Override
@@ -47,12 +57,15 @@ public class DefaultCamelBeanPostProcessorTest extends 
ContextTestSupport {
         postProcessor = new DefaultCamelBeanPostProcessor(context);
     }
 
+    @BindRegistry
     public class FooService {
 
         private String fooEndpoint;
         private String barEndpoint;
         @Produce
         private ProducerTemplate bar;
+        @BindRegistry(name = "myCoolBean")
+        private MySerialBean myBean = new MySerialBean();
 
         public String getFooEndpoint() {
             return fooEndpoint;
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java 
b/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java
index 0a4b8cf..e36aa98 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/ReflectionHelper.java
@@ -157,4 +157,22 @@ public final class ReflectionHelper {
         }
     }
 
+    public static Object getField(Field f, Object instance) {
+        try {
+            boolean oldAccessible = f.isAccessible();
+            boolean shouldSetAccessible = !Modifier.isPublic(f.getModifiers()) 
&& !oldAccessible;
+            if (shouldSetAccessible) {
+                f.setAccessible(true);
+            }
+            Object answer = f.get(instance);
+            if (shouldSetAccessible) {
+                f.setAccessible(oldAccessible);
+            }
+            return answer;
+        } catch (Exception ex) {
+            // ignore
+        }
+        return null;
+    }
+
 }

Reply via email to