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 2022/03/14 06:11:03 UTC

[camel] branch CAMEL-17571 updated (65a5a1d -> fca78ef)

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

davsclaus pushed a change to branch CAMEL-17571
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 65a5a1d  CAMEL-17571: camel-jbang - Support for quarkus/cdi annotations in custom beans
     new 3a50ddc  CAMEL-17571: camel-jbang - docs
     new 6a206f2  CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.
     new a9276e9  CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.
     new fca78ef  CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../modules/ROOT/pages/camel-jbang.adoc            |  34 +++
 .../BindToRegistryCompilePostProcessor.java        |  56 ----
 .../dsl/support/RouteBuilderLoaderSupport.java     |   4 -
 .../support/TypeConverterCompilePostProcessor.java |  45 ---
 .../dsl/java/joor/JavaRoutesBuilderLoader.java     |  10 +-
 .../camel/main/AnnotationDependencyInjection.java  | 306 +++++++++++++++++++++
 .../java/org/apache/camel/main/KameletMain.java    |   6 +-
 .../camel/main/QuarkusAnnotationSupport.java       | 135 ---------
 .../apache/camel/main/SpringAnnotationSupport.java | 143 ----------
 9 files changed, 348 insertions(+), 391 deletions(-)
 delete mode 100644 dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java
 delete mode 100644 dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java
 create mode 100644 dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
 delete mode 100644 dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/QuarkusAnnotationSupport.java
 delete mode 100644 dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java

[camel] 02/04: CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6a206f2b872f8190e4069db05dc7263f10a2ace5
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Mar 13 14:37:11 2022 +0100

    CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.
---
 .../dsl/support/BindToRegistryCompilePostProcessor.java    |  2 ++
 .../camel/dsl/support/RouteBuilderLoaderSupport.java       |  4 ----
 .../dsl/support/TypeConverterCompilePostProcessor.java     |  2 ++
 .../camel/dsl/java/joor/JavaRoutesBuilderLoader.java       | 10 +++++-----
 .../java/org/apache/camel/main/CamelAnnotationSupport.java | 14 ++++++++++++++
 .../src/main/java/org/apache/camel/main/KameletMain.java   |  3 ++-
 6 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java
index cd1271a..041f45d 100644
--- a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java
+++ b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java
@@ -26,6 +26,8 @@ import org.apache.camel.util.ObjectHelper;
 
 public class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
 
+    // TODO: move to camel-kamelet-main
+
     @Override
     public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
         BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
diff --git a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/RouteBuilderLoaderSupport.java b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/RouteBuilderLoaderSupport.java
index eb0024b..763d9e0 100644
--- a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/RouteBuilderLoaderSupport.java
+++ b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/RouteBuilderLoaderSupport.java
@@ -42,10 +42,6 @@ public abstract class RouteBuilderLoaderSupport extends RoutesBuilderLoaderSuppo
 
     protected RouteBuilderLoaderSupport(String extension) {
         this.extension = extension;
-
-        // out of the box camel based compile post processors
-        addCompilePostProcessor(new TypeConverterCompilePostProcessor());
-        addCompilePostProcessor(new BindToRegistryCompilePostProcessor());
     }
 
     @ManagedAttribute(description = "Supported file extension")
diff --git a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java
index ba3de3b..19028ee 100644
--- a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java
+++ b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java
@@ -24,6 +24,8 @@ import org.apache.camel.spi.TypeConverterRegistry;
 
 public class TypeConverterCompilePostProcessor implements CompilePostProcessor {
 
+    // TODO: move to camel-kamelet-main
+
     @Override
     public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
         if (clazz.getAnnotation(Converter.class) != null) {
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
index b5d2815..c29e54d 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
@@ -54,17 +54,17 @@ public class JavaRoutesBuilderLoader extends RouteBuilderLoaderSupport {
 
             Reflect ref = Reflect.compile(name, content).create();
             Class<?> clazz = ref.type();
-
             Object obj = ref.get();
-            if (obj instanceof RouteBuilder) {
-                return (RouteBuilder) obj;
-            }
 
-            // not a route builder but we support annotation scan to register custom beans, type converters, etc.
+            // support custom annotation scanning post compilation
+            // such as to register custom beans, type converters, etc.
             for (CompilePostProcessor pre : getCompilePostProcessors()) {
                 pre.postCompile(getCamelContext(), name, clazz, obj);
             }
 
+            if (obj instanceof RouteBuilder) {
+                return (RouteBuilder) obj;
+            }
             return null;
         }
     }
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
new file mode 100644
index 0000000..b7c58cc
--- /dev/null
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
@@ -0,0 +1,14 @@
+package org.apache.camel.main;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.dsl.support.BindToRegistryCompilePostProcessor;
+import org.apache.camel.dsl.support.TypeConverterCompilePostProcessor;
+
+public class CamelAnnotationSupport {
+
+    public static void registerCamelSupport(CamelContext context) {
+        context.getRegistry().bind("CamelTypeConverterCompilePostProcessor", new TypeConverterCompilePostProcessor());
+        context.getRegistry().bind("CamelBindToRegistryCompilePostProcessor", new BindToRegistryCompilePostProcessor());
+    }
+
+}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 6b22b88..09a629c 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -163,7 +163,8 @@ public class KameletMain extends MainCommandLineSupport {
         answer.setRegistry(registry);
         // load camel component and custom health-checks
         answer.setLoadHealthChecks(true);
-        // optional spring/quarkus annotation support
+        // optional camel/spring/quarkus annotation support in DSL and Java beans
+        CamelAnnotationSupport.registerCamelSupport(answer);
         SpringAnnotationSupport.registerSpringSupport(answer);
         QuarkusAnnotationSupport.registerQuarkus(answer);
 

[camel] 04/04: CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit fca78eff031a15f1b360931141fa6c9415198a53
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Mar 14 07:08:53 2022 +0100

    CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.
---
 .../camel/main/AnnotationDependencyInjection.java  | 306 +++++++++++++++++++++
 .../apache/camel/main/CamelAnnotationSupport.java  |  76 -----
 .../java/org/apache/camel/main/KameletMain.java    |   7 +-
 .../camel/main/QuarkusAnnotationSupport.java       | 135 ---------
 .../apache/camel/main/SpringAnnotationSupport.java | 143 ----------
 5 files changed, 309 insertions(+), 358 deletions(-)

diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
new file mode 100644
index 0000000..97cc33b
--- /dev/null
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
@@ -0,0 +1,306 @@
+/*
+ * 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 java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.CamelConfiguration;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Configuration;
+import org.apache.camel.Converter;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.NoSuchBeanException;
+import org.apache.camel.TypeConverterExists;
+import org.apache.camel.dsl.support.CompilePostProcessor;
+import org.apache.camel.impl.engine.CamelPostProcessorHelper;
+import org.apache.camel.spi.CamelBeanPostProcessor;
+import org.apache.camel.spi.CamelBeanPostProcessorInjector;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ReflectionHelper;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+/**
+ * To enable camel/spring/quarkus based annotations for dependency injection when loading DSLs.
+ */
+public final class AnnotationDependencyInjection {
+
+    private AnnotationDependencyInjection() {
+    }
+
+    public static void initAnnotationBasedDependencyInjection(CamelContext context) {
+        // camel / common
+        context.getRegistry().bind("CamelTypeConverterCompilePostProcessor", new TypeConverterCompilePostProcessor());
+        context.getRegistry().bind("CamelBindToRegistryCompilePostProcessor", new BindToRegistryCompilePostProcessor());
+
+        // spring
+        context.getRegistry().bind("SpringAnnotationCompilePostProcessor", new SpringAnnotationCompilePostProcessor());
+        context.adapt(ExtendedCamelContext.class).getBeanPostProcessor()
+                .addCamelBeanPostProjectInjector(new SpringBeanPostProcessorInjector(context));
+
+        // quarkus
+        context.getRegistry().bind("QuarkusAnnotationCompilePostProcessor", new QuarkusAnnotationCompilePostProcessor());
+        context.adapt(ExtendedCamelContext.class).getBeanPostProcessor()
+                .addCamelBeanPostProjectInjector(new QuarkusBeanPostProcessorInjector(context));
+    }
+
+    private static class TypeConverterCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+            if (clazz.getAnnotation(Converter.class) != null) {
+                TypeConverterRegistry tcr = camelContext.getTypeConverterRegistry();
+                TypeConverterExists exists = tcr.getTypeConverterExists();
+                LoggingLevel level = tcr.getTypeConverterExistsLoggingLevel();
+                // force type converter to override as we could be re-loading
+                tcr.setTypeConverterExists(TypeConverterExists.Override);
+                tcr.setTypeConverterExistsLoggingLevel(LoggingLevel.OFF);
+                try {
+                    tcr.addTypeConverters(clazz);
+                } finally {
+                    tcr.setTypeConverterExists(exists);
+                    tcr.setTypeConverterExistsLoggingLevel(level);
+                }
+            }
+        }
+
+    }
+
+    private static class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+            BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
+            Configuration cfg = instance.getClass().getAnnotation(Configuration.class);
+            if (bir != null || cfg != null || instance instanceof CamelConfiguration) {
+                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+                if (bir != null && ObjectHelper.isNotEmpty(bir.value())) {
+                    name = bir.value();
+                } else if (cfg != null && ObjectHelper.isNotEmpty(cfg.value())) {
+                    name = cfg.value();
+                }
+                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
+                bpp.setUnbindEnabled(true);
+                try {
+                    // this class is a bean service which needs to be post processed and registered which happens
+                    // automatic by the bean post processor
+                    bpp.postProcessBeforeInitialization(instance, name);
+                    bpp.postProcessAfterInitialization(instance, name);
+                } finally {
+                    bpp.setUnbindEnabled(false);
+                }
+                if (instance instanceof CamelConfiguration) {
+                    ((CamelConfiguration) instance).configure(camelContext);
+                }
+            }
+        }
+
+    }
+
+    private static class SpringAnnotationCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+            // @Component and @Service are the same
+            Component comp = clazz.getAnnotation(Component.class);
+            Service service = clazz.getAnnotation(Service.class);
+            if (comp != null || service != null) {
+                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+                if (comp != null && ObjectHelper.isNotEmpty(comp.value())) {
+                    name = comp.value();
+                } else if (service != null && ObjectHelper.isNotEmpty(service.value())) {
+                    name = service.value();
+                }
+                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
+                bpp.setUnbindEnabled(true);
+                try {
+                    // re-bind the bean to the registry
+                    camelContext.getRegistry().unbind(name);
+                    camelContext.getRegistry().bind(name, instance);
+                    // this class is a bean service which needs to be post processed
+                    bpp.postProcessBeforeInitialization(instance, name);
+                    bpp.postProcessAfterInitialization(instance, name);
+                } finally {
+                    bpp.setUnbindEnabled(false);
+                }
+            }
+        }
+    }
+
+    private static class SpringBeanPostProcessorInjector implements CamelBeanPostProcessorInjector {
+
+        private final CamelContext context;
+        private final CamelPostProcessorHelper helper;
+
+        public SpringBeanPostProcessorInjector(CamelContext context) {
+            this.context = context;
+            this.helper = new CamelPostProcessorHelper(context);
+        }
+
+        @Override
+        public void onFieldInject(Field field, Object bean, String beanName) {
+            Autowired autowired = field.getAnnotation(Autowired.class);
+            if (autowired != null) {
+                String name = null;
+                Qualifier qualifier = field.getAnnotation(Qualifier.class);
+                if (qualifier != null) {
+                    name = qualifier.value();
+                }
+
+                try {
+                    ReflectionHelper.setField(field, bean,
+                            helper.getInjectionBeanValue(field.getType(), name));
+                } catch (NoSuchBeanException e) {
+                    if (autowired.required()) {
+                        throw e;
+                    }
+                    // not required so ignore
+                }
+            }
+            Value value = field.getAnnotation(Value.class);
+            if (value != null) {
+                ReflectionHelper.setField(field, bean,
+                        helper.getInjectionPropertyValue(field.getType(), value.value(), null, null, bean, beanName));
+            }
+        }
+
+        @Override
+        public void onMethodInject(Method method, Object bean, String beanName) {
+            Bean bi = method.getAnnotation(Bean.class);
+            if (bi != null) {
+                Object instance = helper.getInjectionBeanMethodValue(context, method, bean, beanName);
+                if (instance != null) {
+                    String name = method.getName();
+                    if (bi.name() != null && bi.name().length > 0) {
+                        name = bi.name()[0];
+                    }
+                    // to support hot reloading of beans then we need to enable unbind mode in bean post processor
+                    CamelBeanPostProcessor bpp = context.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+                    bpp.setUnbindEnabled(true);
+                    try {
+                        // re-bind the bean to the registry
+                        context.getRegistry().unbind(name);
+                        context.getRegistry().bind(name, instance);
+                    } finally {
+                        bpp.setUnbindEnabled(false);
+                    }
+                }
+            }
+        }
+    }
+
+    private static class QuarkusAnnotationCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+            // @ApplicationScoped and @Singleton are considered the same
+            ApplicationScoped as = clazz.getAnnotation(ApplicationScoped.class);
+            Singleton ss = clazz.getAnnotation(Singleton.class);
+            if (as != null || ss != null) {
+                Named named = clazz.getAnnotation(Named.class);
+                if (named != null) {
+                    name = named.value();
+                }
+                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
+                bpp.setUnbindEnabled(true);
+                try {
+                    // re-bind the bean to the registry
+                    camelContext.getRegistry().unbind(name);
+                    camelContext.getRegistry().bind(name, instance);
+                    // this class is a bean service which needs to be post processed
+                    bpp.postProcessBeforeInitialization(instance, name);
+                    bpp.postProcessAfterInitialization(instance, name);
+                } finally {
+                    bpp.setUnbindEnabled(false);
+                }
+            }
+        }
+    }
+
+    private static class QuarkusBeanPostProcessorInjector implements CamelBeanPostProcessorInjector {
+
+        private final CamelContext context;
+        private final CamelPostProcessorHelper helper;
+
+        public QuarkusBeanPostProcessorInjector(CamelContext context) {
+            this.context = context;
+            this.helper = new CamelPostProcessorHelper(context);
+        }
+
+        @Override
+        public void onFieldInject(Field field, Object bean, String beanName) {
+            Inject inject = field.getAnnotation(Inject.class);
+            if (inject != null) {
+                String name = null;
+                Named named = field.getAnnotation(Named.class);
+                if (named != null) {
+                    name = named.value();
+                }
+
+                ReflectionHelper.setField(field, bean,
+                        helper.getInjectionBeanValue(field.getType(), name));
+            }
+            ConfigProperty cp = field.getAnnotation(ConfigProperty.class);
+            if (cp != null) {
+                ReflectionHelper.setField(field, bean,
+                        helper.getInjectionPropertyValue(field.getType(), cp.name(), cp.defaultValue(), null, bean, beanName));
+            }
+        }
+
+        @Override
+        public void onMethodInject(Method method, Object bean, String beanName) {
+            Produces produces = method.getAnnotation(Produces.class);
+            Named bi = method.getAnnotation(Named.class);
+            if (produces != null || bi != null) {
+                Object instance = helper.getInjectionBeanMethodValue(context, method, bean, beanName);
+                if (instance != null) {
+                    String name = method.getName();
+                    if (bi != null && !bi.value().isBlank()) {
+                        name = bi.value();
+                    }
+                    // to support hot reloading of beans then we need to enable unbind mode in bean post processor
+                    CamelBeanPostProcessor bpp = context.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+                    bpp.setUnbindEnabled(true);
+                    try {
+                        // re-bind the bean to the registry
+                        context.getRegistry().unbind(name);
+                        context.getRegistry().bind(name, instance);
+                    } finally {
+                        bpp.setUnbindEnabled(false);
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
deleted file mode 100644
index e5fb6ab..0000000
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.apache.camel.main;
-
-import org.apache.camel.BindToRegistry;
-import org.apache.camel.CamelConfiguration;
-import org.apache.camel.CamelContext;
-import org.apache.camel.Configuration;
-import org.apache.camel.Converter;
-import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.LoggingLevel;
-import org.apache.camel.TypeConverterExists;
-import org.apache.camel.dsl.support.CompilePostProcessor;
-import org.apache.camel.spi.CamelBeanPostProcessor;
-import org.apache.camel.spi.TypeConverterRegistry;
-import org.apache.camel.util.ObjectHelper;
-
-public class CamelAnnotationSupport {
-
-    public static void registerCamelSupport(CamelContext context) {
-        context.getRegistry().bind("CamelTypeConverterCompilePostProcessor", new TypeConverterCompilePostProcessor());
-        context.getRegistry().bind("CamelBindToRegistryCompilePostProcessor", new BindToRegistryCompilePostProcessor());
-    }
-
-    private static class TypeConverterCompilePostProcessor implements CompilePostProcessor {
-
-        @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
-            if (clazz.getAnnotation(Converter.class) != null) {
-                TypeConverterRegistry tcr = camelContext.getTypeConverterRegistry();
-                TypeConverterExists exists = tcr.getTypeConverterExists();
-                LoggingLevel level = tcr.getTypeConverterExistsLoggingLevel();
-                // force type converter to override as we could be re-loading
-                tcr.setTypeConverterExists(TypeConverterExists.Override);
-                tcr.setTypeConverterExistsLoggingLevel(LoggingLevel.OFF);
-                try {
-                    tcr.addTypeConverters(clazz);
-                } finally {
-                    tcr.setTypeConverterExists(exists);
-                    tcr.setTypeConverterExistsLoggingLevel(level);
-                }
-            }
-        }
-
-    }
-
-    private static class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
-
-        @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
-            BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
-            Configuration cfg = instance.getClass().getAnnotation(Configuration.class);
-            if (bir != null || cfg != null || instance instanceof CamelConfiguration) {
-                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
-                if (bir != null && ObjectHelper.isNotEmpty(bir.value())) {
-                    name = bir.value();
-                } else if (cfg != null && ObjectHelper.isNotEmpty(cfg.value())) {
-                    name = cfg.value();
-                }
-                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
-                bpp.setUnbindEnabled(true);
-                try {
-                    // this class is a bean service which needs to be post processed and registered which happens
-                    // automatic by the bean post processor
-                    bpp.postProcessBeforeInitialization(instance, name);
-                    bpp.postProcessAfterInitialization(instance, name);
-                } finally {
-                    bpp.setUnbindEnabled(false);
-                }
-                if (instance instanceof CamelConfiguration) {
-                    ((CamelConfiguration) instance).configure(camelContext);
-                }
-            }
-        }
-
-    }
-
-}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 09a629c..48a7167 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -31,6 +31,7 @@ import org.apache.camel.startup.jfr.FlightRecorderStartupStepRecorder;
  * A Main class for booting up Camel with Kamelet in standalone mode.
  */
 public class KameletMain extends MainCommandLineSupport {
+
     public static final String DEFAULT_KAMELETS_LOCATION = "classpath:/kamelets,github:apache:camel-kamelets/kamelets";
 
     private static ClassLoader kameletClassLoader;
@@ -163,10 +164,8 @@ public class KameletMain extends MainCommandLineSupport {
         answer.setRegistry(registry);
         // load camel component and custom health-checks
         answer.setLoadHealthChecks(true);
-        // optional camel/spring/quarkus annotation support in DSL and Java beans
-        CamelAnnotationSupport.registerCamelSupport(answer);
-        SpringAnnotationSupport.registerSpringSupport(answer);
-        QuarkusAnnotationSupport.registerQuarkus(answer);
+        // annotation based dependency injection for camel/spring/quarkus annotations in DSLs and Java beans
+        AnnotationDependencyInjection.initAnnotationBasedDependencyInjection(answer);
 
         // embed HTTP server if port is specified
         Object port = getInitialProperties().get("camel.jbang.platform-http.port");
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/QuarkusAnnotationSupport.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/QuarkusAnnotationSupport.java
deleted file mode 100644
index 0ae5455..0000000
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/QuarkusAnnotationSupport.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.Produces;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.dsl.support.CompilePostProcessor;
-import org.apache.camel.impl.engine.CamelPostProcessorHelper;
-import org.apache.camel.spi.CamelBeanPostProcessor;
-import org.apache.camel.spi.CamelBeanPostProcessorInjector;
-import org.apache.camel.util.ReflectionHelper;
-import org.eclipse.microprofile.config.inject.ConfigProperty;
-
-/**
- * To support quarkus based annotations such as @ApplicationScoped, @Singleton, @Inject, @Produces, @ConfigProperty
- */
-public final class QuarkusAnnotationSupport {
-
-    private QuarkusAnnotationSupport() {
-    }
-
-    public static void registerQuarkus(CamelContext context) {
-        context.getRegistry().bind("QuarkusAnnotationCompilePostProcessor", new QuarkusAnnotationCompilePostProcessor());
-        context.adapt(ExtendedCamelContext.class).getBeanPostProcessor()
-                .addCamelBeanPostProjectInjector(new QuarkusBeanPostProcessorInjector(context));
-    }
-
-    private static class QuarkusAnnotationCompilePostProcessor implements CompilePostProcessor {
-
-        @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
-            // @ApplicationScoped and @Singleton are considered the same
-            ApplicationScoped as = clazz.getAnnotation(ApplicationScoped.class);
-            Singleton ss = clazz.getAnnotation(Singleton.class);
-            if (as != null || ss != null) {
-                Named named = clazz.getAnnotation(Named.class);
-                if (named != null) {
-                    name = named.value();
-                }
-                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
-                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
-                bpp.setUnbindEnabled(true);
-                try {
-                    // re-bind the bean to the registry
-                    camelContext.getRegistry().unbind(name);
-                    camelContext.getRegistry().bind(name, instance);
-                    // this class is a bean service which needs to be post processed
-                    bpp.postProcessBeforeInitialization(instance, name);
-                    bpp.postProcessAfterInitialization(instance, name);
-                } finally {
-                    bpp.setUnbindEnabled(false);
-                }
-            }
-        }
-    }
-
-    private static class QuarkusBeanPostProcessorInjector implements CamelBeanPostProcessorInjector {
-
-        private final CamelContext context;
-        private final CamelPostProcessorHelper helper;
-
-        public QuarkusBeanPostProcessorInjector(CamelContext context) {
-            this.context = context;
-            this.helper = new CamelPostProcessorHelper(context);
-        }
-
-        @Override
-        public void onFieldInject(Field field, Object bean, String beanName) {
-            Inject inject = field.getAnnotation(Inject.class);
-            if (inject != null) {
-                String name = null;
-                Named named = field.getAnnotation(Named.class);
-                if (named != null) {
-                    name = named.value();
-                }
-
-                ReflectionHelper.setField(field, bean,
-                        helper.getInjectionBeanValue(field.getType(), name));
-            }
-            ConfigProperty cp = field.getAnnotation(ConfigProperty.class);
-            if (cp != null) {
-                ReflectionHelper.setField(field, bean,
-                        helper.getInjectionPropertyValue(field.getType(), cp.name(), cp.defaultValue(), null, bean, beanName));
-            }
-        }
-
-        @Override
-        public void onMethodInject(Method method, Object bean, String beanName) {
-            Produces produces = method.getAnnotation(Produces.class);
-            Named bi = method.getAnnotation(Named.class);
-            if (produces != null || bi != null) {
-                Object instance = helper.getInjectionBeanMethodValue(context, method, bean, beanName);
-                if (instance != null) {
-                    String name = method.getName();
-                    if (bi != null && !bi.value().isBlank()) {
-                        name = bi.value();
-                    }
-                    // to support hot reloading of beans then we need to enable unbind mode in bean post processor
-                    CamelBeanPostProcessor bpp = context.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
-                    bpp.setUnbindEnabled(true);
-                    try {
-                        // re-bind the bean to the registry
-                        context.getRegistry().unbind(name);
-                        context.getRegistry().bind(name, instance);
-                    } finally {
-                        bpp.setUnbindEnabled(false);
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java
deleted file mode 100644
index 120d963..0000000
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.NoSuchBeanException;
-import org.apache.camel.dsl.support.CompilePostProcessor;
-import org.apache.camel.impl.engine.CamelPostProcessorHelper;
-import org.apache.camel.spi.CamelBeanPostProcessor;
-import org.apache.camel.spi.CamelBeanPostProcessorInjector;
-import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.ReflectionHelper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
-
-/**
- * To support spring based annotations such as @Component/@Service, @Autowired/@Qualifier, @Value, and @Bean.
- */
-public final class SpringAnnotationSupport {
-
-    private SpringAnnotationSupport() {
-    }
-
-    public static void registerSpringSupport(CamelContext context) {
-        context.getRegistry().bind("SpringAnnotationCompilePostProcessor", new SpringAnnotationCompilePostProcessor());
-        context.adapt(ExtendedCamelContext.class).getBeanPostProcessor()
-                .addCamelBeanPostProjectInjector(new SpringBeanPostProcessorInjector(context));
-    }
-
-    private static class SpringAnnotationCompilePostProcessor implements CompilePostProcessor {
-
-        @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
-            // @Component and @Service are the same
-            Component comp = clazz.getAnnotation(Component.class);
-            Service service = clazz.getAnnotation(Service.class);
-            if (comp != null || service != null) {
-                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
-                if (comp != null && ObjectHelper.isNotEmpty(comp.value())) {
-                    name = comp.value();
-                } else if (service != null && ObjectHelper.isNotEmpty(service.value())) {
-                    name = service.value();
-                }
-                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
-                bpp.setUnbindEnabled(true);
-                try {
-                    // re-bind the bean to the registry
-                    camelContext.getRegistry().unbind(name);
-                    camelContext.getRegistry().bind(name, instance);
-                    // this class is a bean service which needs to be post processed
-                    bpp.postProcessBeforeInitialization(instance, name);
-                    bpp.postProcessAfterInitialization(instance, name);
-                } finally {
-                    bpp.setUnbindEnabled(false);
-                }
-            }
-        }
-    }
-
-    private static class SpringBeanPostProcessorInjector implements CamelBeanPostProcessorInjector {
-
-        private final CamelContext context;
-        private final CamelPostProcessorHelper helper;
-
-        public SpringBeanPostProcessorInjector(CamelContext context) {
-            this.context = context;
-            this.helper = new CamelPostProcessorHelper(context);
-        }
-
-        @Override
-        public void onFieldInject(Field field, Object bean, String beanName) {
-            Autowired autowired = field.getAnnotation(Autowired.class);
-            if (autowired != null) {
-                String name = null;
-                Qualifier qualifier = field.getAnnotation(Qualifier.class);
-                if (qualifier != null) {
-                    name = qualifier.value();
-                }
-
-                try {
-                    ReflectionHelper.setField(field, bean,
-                            helper.getInjectionBeanValue(field.getType(), name));
-                } catch (NoSuchBeanException e) {
-                    if (autowired.required()) {
-                        throw e;
-                    }
-                    // not required so ignore
-                }
-            }
-            Value value = field.getAnnotation(Value.class);
-            if (value != null) {
-                ReflectionHelper.setField(field, bean,
-                        helper.getInjectionPropertyValue(field.getType(), value.value(), null, null, bean, beanName));
-            }
-        }
-
-        @Override
-        public void onMethodInject(Method method, Object bean, String beanName) {
-            Bean bi = method.getAnnotation(Bean.class);
-            if (bi != null) {
-                Object instance = helper.getInjectionBeanMethodValue(context, method, bean, beanName);
-                if (instance != null) {
-                    String name = method.getName();
-                    if (bi.name() != null && bi.name().length > 0) {
-                        name = bi.name()[0];
-                    }
-                    // to support hot reloading of beans then we need to enable unbind mode in bean post processor
-                    CamelBeanPostProcessor bpp = context.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
-                    bpp.setUnbindEnabled(true);
-                    try {
-                        // re-bind the bean to the registry
-                        context.getRegistry().unbind(name);
-                        context.getRegistry().bind(name, instance);
-                    } finally {
-                        bpp.setUnbindEnabled(false);
-                    }
-                }
-            }
-        }
-    }
-}

[camel] 03/04: CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a9276e9fef71fc8d1933115088a4e829663fe4d7
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Mar 14 07:02:34 2022 +0100

    CAMEL-17571: camel-dsl - Allow to register custom annotation processors that can do custom logic after a DSL has compiled source into Java object.
---
 .../BindToRegistryCompilePostProcessor.java        | 58 -------------------
 .../support/TypeConverterCompilePostProcessor.java | 47 ---------------
 .../apache/camel/main/CamelAnnotationSupport.java  | 66 +++++++++++++++++++++-
 3 files changed, 64 insertions(+), 107 deletions(-)

diff --git a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java
deleted file mode 100644
index 041f45d..0000000
--- a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/BindToRegistryCompilePostProcessor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.dsl.support;
-
-import org.apache.camel.BindToRegistry;
-import org.apache.camel.CamelConfiguration;
-import org.apache.camel.CamelContext;
-import org.apache.camel.Configuration;
-import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.spi.CamelBeanPostProcessor;
-import org.apache.camel.util.ObjectHelper;
-
-public class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
-
-    // TODO: move to camel-kamelet-main
-
-    @Override
-    public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
-        BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
-        Configuration cfg = instance.getClass().getAnnotation(Configuration.class);
-        if (bir != null || cfg != null || instance instanceof CamelConfiguration) {
-            CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
-            if (bir != null && ObjectHelper.isNotEmpty(bir.value())) {
-                name = bir.value();
-            } else if (cfg != null && ObjectHelper.isNotEmpty(cfg.value())) {
-                name = cfg.value();
-            }
-            // to support hot reloading of beans then we need to enable unbind mode in bean post processor
-            bpp.setUnbindEnabled(true);
-            try {
-                // this class is a bean service which needs to be post processed and registered which happens
-                // automatic by the bean post processor
-                bpp.postProcessBeforeInitialization(instance, name);
-                bpp.postProcessAfterInitialization(instance, name);
-            } finally {
-                bpp.setUnbindEnabled(false);
-            }
-            if (instance instanceof CamelConfiguration) {
-                ((CamelConfiguration) instance).configure(camelContext);
-            }
-        }
-    }
-
-}
diff --git a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java b/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java
deleted file mode 100644
index 19028ee..0000000
--- a/dsl/camel-dsl-support/src/main/java/org/apache/camel/dsl/support/TypeConverterCompilePostProcessor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.dsl.support;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Converter;
-import org.apache.camel.LoggingLevel;
-import org.apache.camel.TypeConverterExists;
-import org.apache.camel.spi.TypeConverterRegistry;
-
-public class TypeConverterCompilePostProcessor implements CompilePostProcessor {
-
-    // TODO: move to camel-kamelet-main
-
-    @Override
-    public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
-        if (clazz.getAnnotation(Converter.class) != null) {
-            TypeConverterRegistry tcr = camelContext.getTypeConverterRegistry();
-            TypeConverterExists exists = tcr.getTypeConverterExists();
-            LoggingLevel level = tcr.getTypeConverterExistsLoggingLevel();
-            // force type converter to override as we could be re-loading
-            tcr.setTypeConverterExists(TypeConverterExists.Override);
-            tcr.setTypeConverterExistsLoggingLevel(LoggingLevel.OFF);
-            try {
-                tcr.addTypeConverters(clazz);
-            } finally {
-                tcr.setTypeConverterExists(exists);
-                tcr.setTypeConverterExistsLoggingLevel(level);
-            }
-        }
-    }
-
-}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
index b7c58cc..e5fb6ab 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CamelAnnotationSupport.java
@@ -1,8 +1,17 @@
 package org.apache.camel.main;
 
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.CamelConfiguration;
 import org.apache.camel.CamelContext;
-import org.apache.camel.dsl.support.BindToRegistryCompilePostProcessor;
-import org.apache.camel.dsl.support.TypeConverterCompilePostProcessor;
+import org.apache.camel.Configuration;
+import org.apache.camel.Converter;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.TypeConverterExists;
+import org.apache.camel.dsl.support.CompilePostProcessor;
+import org.apache.camel.spi.CamelBeanPostProcessor;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.util.ObjectHelper;
 
 public class CamelAnnotationSupport {
 
@@ -11,4 +20,57 @@ public class CamelAnnotationSupport {
         context.getRegistry().bind("CamelBindToRegistryCompilePostProcessor", new BindToRegistryCompilePostProcessor());
     }
 
+    private static class TypeConverterCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+            if (clazz.getAnnotation(Converter.class) != null) {
+                TypeConverterRegistry tcr = camelContext.getTypeConverterRegistry();
+                TypeConverterExists exists = tcr.getTypeConverterExists();
+                LoggingLevel level = tcr.getTypeConverterExistsLoggingLevel();
+                // force type converter to override as we could be re-loading
+                tcr.setTypeConverterExists(TypeConverterExists.Override);
+                tcr.setTypeConverterExistsLoggingLevel(LoggingLevel.OFF);
+                try {
+                    tcr.addTypeConverters(clazz);
+                } finally {
+                    tcr.setTypeConverterExists(exists);
+                    tcr.setTypeConverterExistsLoggingLevel(level);
+                }
+            }
+        }
+
+    }
+
+    private static class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, Object instance) throws Exception {
+            BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
+            Configuration cfg = instance.getClass().getAnnotation(Configuration.class);
+            if (bir != null || cfg != null || instance instanceof CamelConfiguration) {
+                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+                if (bir != null && ObjectHelper.isNotEmpty(bir.value())) {
+                    name = bir.value();
+                } else if (cfg != null && ObjectHelper.isNotEmpty(cfg.value())) {
+                    name = cfg.value();
+                }
+                // to support hot reloading of beans then we need to enable unbind mode in bean post processor
+                bpp.setUnbindEnabled(true);
+                try {
+                    // this class is a bean service which needs to be post processed and registered which happens
+                    // automatic by the bean post processor
+                    bpp.postProcessBeforeInitialization(instance, name);
+                    bpp.postProcessAfterInitialization(instance, name);
+                } finally {
+                    bpp.setUnbindEnabled(false);
+                }
+                if (instance instanceof CamelConfiguration) {
+                    ((CamelConfiguration) instance).configure(camelContext);
+                }
+            }
+        }
+
+    }
+
 }

[camel] 01/04: CAMEL-17571: camel-jbang - docs

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3a50ddc48c4b8e9708ee356f244dcfa973f94ad2
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Mar 13 10:58:51 2022 +0100

    CAMEL-17571: camel-jbang - docs
---
 .../modules/ROOT/pages/camel-jbang.adoc            | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 4a58944..3f13e26 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -238,6 +238,40 @@ curl http://localhost:8080/hello
 Hello World%
 ----
 
+=== Dependency Injection in Java classes
+
+When running Camel applications with camel-jbang, then the runtime is `camel-main` based. This means
+there is no Spring Boot, or Quarkus available. However, we have added support for using annotation
+based dependency injection in Java classes.
+
+==== Using Camel dependency injection
+
+You can use the following Camel annotations (they work on all runtimes):
+
+- `@BindToRegistry` on class level to create an instance of the class and register in the xref:registry.adoc[Registry].
+- `@BeanInject` to dependency inject a bean on a class field.
+- `@PropertyInject` to inject a xref:using-propertyplaceholder.adoc[property placeholder]. Such as a property defined in `application.properties`.
+- `@BindToRegistry` on a method to create a bean by invoking the method.
+- `@Converter` on class level to auto-register the xref:type-converter.adoc[type converters] from the class.
+
+==== Using Spring Boot dependency injection
+
+You can use the following Spring Boot annotations:
+
+- `@Component` or `@Service` on class level to create an instance of the class and register in the xref:registry.adoc[Registry].
+- `@Autowired` to dependency inject an bean on a class field. `@Qualifier` can be used to specify the bean id.
+- `@Value` to inject a xref:using-propertyplaceholder.adoc[property placeholder]. Such as a property defined in `application.properties`.
+- `@Bean` on a method to create a bean by invoking the method.
+
+==== Using Quarkus injection
+
+You can use the following Quarkus annotations:
+
+- `@ApplicationScoped` or `@Single` on class level to create an instance of the class and register in the xref:registry.adoc[Registry]. `@Named` can be used to specify the bean id.
+- `@Inject` to dependency inject an bean on a class field. `@Named` can be used to specify the bean id.
+- `@ConfigProperty` to inject a xref:using-propertyplaceholder.adoc[property placeholder]. Such as a property defined in `application.properties`.
+- `@Produces` on a method to create a bean by invoking the method. `@Named` can be used to specify the bean id.
+
 === Debugging
 
 You can debug both camel@apache/camel and your integration scripts by making use of the `--debug` flag provided by JBang: