Repository: camel
Updated Branches:
  refs/heads/master 88225c8fc -> 87d4313c4


http://git-wip-us.apache.org/repos/asf/camel/blob/3eeb97ac/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
----------------------------------------------------------------------
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
index 57dd4649d..aff7b16 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
@@ -16,18 +16,15 @@
  */
 package org.apache.camel.maven.packaging;
 
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -42,11 +39,8 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-
 import javax.annotation.Generated;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 import org.apache.camel.maven.packaging.model.ComponentModel;
 import org.apache.camel.maven.packaging.model.ComponentOptionModel;
 import org.apache.camel.maven.packaging.model.DataFormatModel;
@@ -67,8 +61,8 @@ import org.apache.maven.project.MavenProject;
 import org.jboss.forge.roaster.Roaster;
 import org.jboss.forge.roaster.model.JavaType;
 import org.jboss.forge.roaster.model.Type;
-import org.jboss.forge.roaster.model.source.AnnotationSource;
 import org.jboss.forge.roaster.model.source.Import;
+import org.jboss.forge.roaster.model.source.Importer;
 import org.jboss.forge.roaster.model.source.JavaClassSource;
 import org.jboss.forge.roaster.model.source.MethodSource;
 import org.jboss.forge.roaster.model.source.PropertySource;
@@ -76,6 +70,7 @@ import org.jboss.forge.roaster.model.util.Formatter;
 import org.jboss.forge.roaster.model.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
 import org.springframework.boot.autoconfigure.condition.ConditionMessage;
 import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -550,7 +545,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
                 List<String> aliases = 
compModels.stream().map(ComponentModel::getScheme).sorted().collect(Collectors.toList());
 
                 // resolvePropertyPlaceholders is an option which only make 
sense to use if the component has other options
-                boolean hasOptions = 
model.getComponentOptions().stream().anyMatch(o -> 
!o.getName().equals("resolvePropertyPlaceholders"));
+                //boolean hasOptions = 
model.getComponentOptions().stream().anyMatch(o -> 
!o.getName().equals("resolvePropertyPlaceholders"));
 
                 // use springboot as sub package name so the code is not in 
normal
                 // package so the Spring Boot JARs can be optional at runtime
@@ -563,10 +558,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
                     overrideComponentName = 
model.getArtifactId().replace("camel-", "");
                 }
 
-                if (hasOptions) {
-                    createComponentConfigurationSource(pkg, model, 
overrideComponentName);
-                }
-                createComponentAutoConfigurationSource(pkg, model, aliases, 
hasOptions, overrideComponentName);
+                createComponentConfigurationSource(pkg, model, 
overrideComponentName);
+                createComponentAutoConfigurationSource(pkg, model, aliases, 
overrideComponentName);
                 createComponentSpringFactorySource(pkg, model);
             }
         }
@@ -600,8 +593,6 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
                 DataFormatModel model = dfModels.get(0); // They should be 
equivalent
                 List<String> aliases = 
dfModels.stream().map(DataFormatModel::getName).sorted().collect(Collectors.toList());
 
-                boolean hasOptions = !model.getDataFormatOptions().isEmpty();
-
                 // use springboot as sub package name so the code is not in 
normal
                 // package so the Spring Boot JARs can be optional at runtime
                 int pos = model.getJavaType().lastIndexOf(".");
@@ -613,10 +604,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
                     overrideDataFormatName = 
model.getArtifactId().replace("camel-", "");
                 }
 
-                if (hasOptions) {
-                    createDataFormatConfigurationSource(pkg, model, 
overrideDataFormatName);
-                }
-                createDataFormatAutoConfigurationSource(pkg, model, aliases, 
hasOptions, overrideDataFormatName);
+                createDataFormatConfigurationSource(pkg, model, 
overrideDataFormatName);
+                createDataFormatAutoConfigurationSource(pkg, model, aliases, 
overrideDataFormatName);
                 createDataFormatSpringFactorySource(pkg, model);
             }
         }
@@ -650,8 +639,6 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
                 LanguageModel model = dfModels.get(0); // They should be 
equivalent
                 List<String> aliases = 
dfModels.stream().map(LanguageModel::getName).sorted().collect(Collectors.toList());
 
-                boolean hasOptions = !model.getLanguageOptions().isEmpty();
-
                 // use springboot as sub package name so the code is not in 
normal
                 // package so the Spring Boot JARs can be optional at runtime
                 int pos = model.getJavaType().lastIndexOf(".");
@@ -663,10 +650,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
                     overrideLanguageName = 
model.getArtifactId().replace("camel-", "");
                 }
 
-                if (hasOptions) {
-                    createLanguageConfigurationSource(pkg, model, 
overrideLanguageName);
-                }
-                createLanguageAutoConfigurationSource(pkg, model, aliases, 
hasOptions, overrideLanguageName);
+                createLanguageConfigurationSource(pkg, model, 
overrideLanguageName);
+                createLanguageAutoConfigurationSource(pkg, model, aliases, 
overrideLanguageName);
                 createLanguageSpringFactorySource(pkg, model);
             }
         }
@@ -679,6 +664,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         String name = model.getJavaType().substring(pos + 1);
         name = name.replace("Component", "ComponentConfiguration");
         javaClass.setPackage(packageName).setName(name);
+        
javaClass.extendSuperType(Roaster.create(JavaClassSource.class).setName("ComponentConfigurationPropertiesCommon"));
+        
javaClass.addImport("org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon");
 
         String doc = "Generated by camel-package-maven-plugin - do not edit 
this file!";
         if (!Strings.isBlank(model.getDescription())) {
@@ -1014,9 +1001,9 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         if ("netty4-http".equals(model.getScheme()) || 
"netty-http".equals(model.getScheme())) {
             String name = option.getName();
             if (name.equals("textline") || name.equals("delimiter") || 
name.equals("autoAppendDelimiter") || name.equals("decoderMaxLineLength")
-                    || name.equals("encoding") || 
name.equals("allowDefaultCodec") || name.equals("udpConnectionlessSending") || 
name.equals("networkInterface")
-                    || name.equals("clientMode") || name.equals("reconnect") 
|| name.equals("reconnectInterval") || name.equals("useByteBuf")
-                    || name.equals("udpByteArrayCodec") || 
name.equals("broadcast")) {
+                || name.equals("encoding") || name.equals("allowDefaultCodec") 
|| name.equals("udpConnectionlessSending") || name.equals("networkInterface")
+                || name.equals("clientMode") || name.equals("reconnect") || 
name.equals("reconnectInterval") || name.equals("useByteBuf")
+                || name.equals("udpByteArrayCodec") || 
name.equals("broadcast")) {
                 return true;
             }
         }
@@ -1031,6 +1018,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         String name = model.getJavaType().substring(pos + 1);
         name = name.replace("DataFormat", "DataFormatConfiguration");
         javaClass.setPackage(packageName).setName(name);
+        
javaClass.extendSuperType(Roaster.create(JavaClassSource.class).setName("DataFormatConfigurationPropertiesCommon"));
+        
javaClass.addImport("org.apache.camel.spring.boot.DataFormatConfigurationPropertiesCommon");
 
         String doc = "Generated by camel-package-maven-plugin - do not edit 
this file!";
         if (!Strings.isBlank(model.getDescription())) {
@@ -1094,6 +1083,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         String name = model.getJavaType().substring(pos + 1);
         name = name.replace("Language", "LanguageConfiguration");
         javaClass.setPackage(packageName).setName(name);
+        
javaClass.extendSuperType(Roaster.create(JavaClassSource.class).setName("LanguageConfigurationPropertiesCommon"));
+        
javaClass.addImport("org.apache.camel.spring.boot.LanguageConfigurationPropertiesCommon");
 
         String doc = "Generated by camel-package-maven-plugin - do not edit 
this file!";
         if (!Strings.isBlank(model.getDescription())) {
@@ -1121,8 +1112,8 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
             } else if ("tokenize".equals(model.getName())) {
                 // and skip following as they are not global options
                 if ("token".equals(option.getName()) || 
"endToken".equals(option.getName()) || 
"inheritNamespaceTagName".equals(option.getName())
-                        || "headerName".equals(option.getName()) || 
"regex".equals(option.getName()) || "xml".equals(option.getName())
-                        || "includeTokens".equals(option.getName()) || 
"group".equals(option.getName()) || "skipFirst".equals(option.getName())) {
+                    || "headerName".equals(option.getName()) || 
"regex".equals(option.getName()) || "xml".equals(option.getName())
+                    || "includeTokens".equals(option.getName()) || 
"group".equals(option.getName()) || "skipFirst".equals(option.getName())) {
                     continue;
                 }
             } else if ("xtokenize".equals(model.getName())) {
@@ -1181,7 +1172,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
     }
 
     private void createComponentAutoConfigurationSource(
-            String packageName, ComponentModel model, List<String> 
componentAliases, boolean hasOptions, String overrideComponentName) throws 
MojoFailureException {
+        String packageName, ComponentModel model, List<String> 
componentAliases, String overrideComponentName) throws MojoFailureException {
 
         final JavaClassSource javaClass = 
Roaster.create(JavaClassSource.class);
 
@@ -1193,119 +1184,246 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
 
         String doc = "Generated by camel-package-maven-plugin - do not edit 
this file!";
         javaClass.getJavaDoc().setFullText(doc);
-
+        javaClass.extendSuperType(AllNestedConditions.class);
         javaClass.addAnnotation(Generated.class).setStringValue("value", 
SpringBootAutoConfigurationMojo.class.getName());
         javaClass.addAnnotation(Configuration.class);
-        
javaClass.addAnnotation(ConditionalOnBean.class).setStringValue("type", 
"org.apache.camel.spring.boot.CamelAutoConfiguration");
         javaClass.addAnnotation(Conditional.class).setLiteralValue(name + 
".Condition.class");
-        
javaClass.addAnnotation(AutoConfigureAfter.class).setStringValue("name", 
"org.apache.camel.spring.boot.CamelAutoConfiguration");
+        
javaClass.addAnnotation(AutoConfigureAfter.class).setLiteralValue("CamelAutoConfiguration.class");
 
         String configurationName = name.replace("ComponentAutoConfiguration", 
"ComponentConfiguration");
-        if (hasOptions) {
-            AnnotationSource<JavaClassSource> ann = 
javaClass.addAnnotation(EnableConfigurationProperties.class);
-            ann.setLiteralValue("value", configurationName + ".class");
-
-            javaClass.addImport("java.util.HashMap");
-            javaClass.addImport("java.util.Map");
-            javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
-        }
+        
javaClass.addAnnotation(EnableConfigurationProperties.class).setLiteralValue(
+            "{ ComponentConfigurationProperties.class, " + configurationName + 
".class }"
+        );
 
+        javaClass.addImport(HashMap.class);
+        javaClass.addImport(Map.class);
+        javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
         javaClass.addImport(model.getJavaType());
+        javaClass.addImport(List.class);
+        javaClass.addImport(ConditionalOnBean.class);
+        javaClass.addImport("org.slf4j.Logger");
+        javaClass.addImport("org.slf4j.LoggerFactory");
         javaClass.addImport("org.apache.camel.CamelContext");
+        javaClass.addImport("org.apache.camel.spi.ComponentCustomizer");
+        
javaClass.addImport("org.apache.camel.spring.boot.CamelAutoConfiguration");
+        
javaClass.addImport("org.apache.camel.spring.boot.ComponentConfigurationProperties");
+        
javaClass.addImport("org.apache.camel.spring.boot.util.GroupCondition");
+        javaClass.addImport("org.apache.camel.util.ObjectHelper");
+
+        javaClass.addField()
+            .setPrivate()
+            .setStatic(true)
+            .setFinal(true)
+            .setName("LOGGER")
+            .setType("Logger")
+            .setLiteralInitializer("LoggerFactory.getLogger(" + name + 
".class)");
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("camelContext")
+            .setType("CamelContext")
+            .addAnnotation(Autowired.class);
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("customizers")
+            .setType("List<ComponentCustomizer<" + model.getShortJavaType() + 
">>")
+            .addAnnotation(Autowired.class).setLiteralValue("required", 
"false");
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("globalConfiguration")
+            .setType("ComponentConfigurationProperties")
+            .addAnnotation(Autowired.class);
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("componentConfiguration")
+            .setType(configurationName)
+            .addAnnotation(Autowired.class);
+
+        javaClass.addMethod()
+            .setConstructor(true)
+            .setPublic()
+            .setBody("super(ConfigurationPhase.REGISTER_BEAN);");
+
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("OnCamelContext")
+                .setStatic(true)
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelContext.class")
+                    .getOrigin()
+        );
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("OnCamelAutoConfiguration")
+                .setStatic(true)
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelAutoConfiguration.class")
+                    .getOrigin()
+        );
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("Condition")
+                .setStatic(true)
+                
.extendSuperType(Roaster.create(JavaClassSource.class).setName("GroupCondition"))
+                .addMethod()
+                    .setName("Condition")
+                    .setConstructor(true)
+                    .setPublic()
+                    .setBody("super(\"camel.component\", \"camel.component." + 
(overrideComponentName != null ? overrideComponentName : 
model.getScheme()).toLowerCase(Locale.US) + "\");")
+                    .getOrigin()
+        );
 
         // add method for auto configure
-        String body = createComponentBody(model.getShortJavaType(), 
hasOptions);
+        String body = createComponentBody(model.getShortJavaType());
         String methodName = "configure" + model.getShortJavaType();
 
         MethodSource<JavaClassSource> method = javaClass.addMethod()
-                .setName(methodName)
-                .setPublic()
-                .setBody(body)
-                .setReturnType(model.getShortJavaType())
-                .addThrows(Exception.class);
-
-        method.addParameter("CamelContext", "camelContext");
-
-        if (hasOptions) {
-            method.addParameter(configurationName, "configuration");
-        }
+            .setName(methodName)
+            .setPublic()
+            .setBody(body)
+            .setReturnType(model.getShortJavaType())
+            .addThrows(Exception.class);
 
         // Determine all the aliases
         String[] springBeanAliases = componentAliases.stream().map(alias -> 
alias + "-component").toArray(size -> new String[size]);
 
         method.addAnnotation(Lazy.class);
         method.addAnnotation(Bean.class).setStringArrayValue("name", 
springBeanAliases);
-        
method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", 
"CamelContext.class");
-        
method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", 
model.getShortJavaType() + ".class");
-
-        // Generate Condition
-        javaClass.addNestedType(createConditionType(
-            javaClass,
-            "camel.component",
-            (overrideComponentName != null ? overrideComponentName : 
model.getScheme()).toLowerCase(Locale.US)
-        ));
+        
method.addAnnotation(ConditionalOnClass.class).setLiteralValue("CamelContext.class");
+        
method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue(model.getShortJavaType()
 + ".class");
 
         sortImports(javaClass);
 
         String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + 
".java";
         writeSourceIfChanged(javaClass, fileName);
-        writeAdditionalSpringMetaData(
-            "camel",
-            "component",
-            (overrideComponentName != null ? overrideComponentName : 
model.getScheme()).toLowerCase(Locale.US));
     }
 
     private void createDataFormatAutoConfigurationSource(
-            String packageName, DataFormatModel model, List<String> 
dataFormatAliases, boolean hasOptions, String overrideDataFormatName) throws 
MojoFailureException {
+        String packageName, DataFormatModel model, List<String> 
dataFormatAliases, String overrideDataFormatName) throws MojoFailureException {
 
         final JavaClassSource javaClass = 
Roaster.create(JavaClassSource.class);
 
         int pos = model.getJavaType().lastIndexOf(".");
         String name = model.getJavaType().substring(pos + 1);
-        name = name.replace("DataFormat", "DataFormatAutoConfiguration");      
  
+        name = name.replace("DataFormat", "DataFormatAutoConfiguration");
 
         javaClass.setPackage(packageName).setName(name);
 
         String doc = "Generated by camel-package-maven-plugin - do not edit 
this file!";
         javaClass.getJavaDoc().setFullText(doc);
-
+        javaClass.extendSuperType(AllNestedConditions.class);
         javaClass.addAnnotation(Generated.class).setStringValue("value", 
SpringBootAutoConfigurationMojo.class.getName());
         javaClass.addAnnotation(Configuration.class);
-        
javaClass.addAnnotation(ConditionalOnBean.class).setStringValue("type", 
"org.apache.camel.spring.boot.CamelAutoConfiguration");
         javaClass.addAnnotation(Conditional.class).setLiteralValue(name + 
".Condition.class");
         
javaClass.addAnnotation(AutoConfigureAfter.class).setStringValue("name", 
"org.apache.camel.spring.boot.CamelAutoConfiguration");
 
         String configurationName = name.replace("DataFormatAutoConfiguration", 
"DataFormatConfiguration");
-        if (hasOptions) {
-            AnnotationSource<JavaClassSource> ann = 
javaClass.addAnnotation(EnableConfigurationProperties.class);
-            ann.setLiteralValue("value", configurationName + ".class");
-
-            javaClass.addImport("java.util.HashMap");
-            javaClass.addImport("java.util.Map");
-            javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
-        }
+        
javaClass.addAnnotation(EnableConfigurationProperties.class).setLiteralValue(
+            "{ DataFormatConfigurationProperties.class, " + configurationName 
+ ".class }"
+        );
 
-        javaClass.addImport("org.apache.camel.CamelContextAware");
+        javaClass.addImport(HashMap.class);
+        javaClass.addImport(Map.class);
+        javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
         javaClass.addImport(model.getJavaType());
+        javaClass.addImport(List.class);
+        javaClass.addImport(ConditionalOnBean.class);
+        javaClass.addImport("org.slf4j.Logger");
+        javaClass.addImport("org.slf4j.LoggerFactory");
         javaClass.addImport("org.apache.camel.CamelContext");
+        javaClass.addImport("org.apache.camel.CamelContextAware");
+        
javaClass.addImport("org.apache.camel.spring.boot.CamelAutoConfiguration");
+        
javaClass.addImport("org.apache.camel.spring.boot.DataFormatConfigurationProperties");
+        
javaClass.addImport("org.apache.camel.spring.boot.util.GroupCondition");
+        javaClass.addImport("org.apache.camel.util.ObjectHelper");
         javaClass.addImport("org.apache.camel.RuntimeCamelException");
         javaClass.addImport("org.apache.camel.spi.DataFormat");
+        javaClass.addImport("org.apache.camel.spi.DataFormatCustomizer");
         javaClass.addImport("org.apache.camel.spi.DataFormatFactory");
 
-        String body = createDataFormatBody(model.getShortJavaType(), 
hasOptions);
-        String methodName = "configure" + model.getShortJavaType() + "Factory";
+        javaClass.addField()
+            .setPrivate()
+            .setStatic(true)
+            .setFinal(true)
+            .setName("LOGGER")
+            .setType("Logger")
+            .setLiteralInitializer("LoggerFactory.getLogger(" + name + 
".class)");
 
-        MethodSource<JavaClassSource> method = javaClass.addMethod()
-                .setName(methodName)
-                .setPublic()
-                .setBody(body)
-                .setReturnType("org.apache.camel.spi.DataFormatFactory");
+        javaClass.addField()
+            .setPrivate()
+            .setName("camelContext")
+            .setType("CamelContext")
+            .addAnnotation(Autowired.class);
 
-        method.addParameter("CamelContext", "camelContext").setFinal(true);
+        javaClass.addField()
+            .setPrivate()
+            .setName("customizers")
+            .setType("List<DataFormatCustomizer<" + model.getShortJavaType() + 
">>")
+            .addAnnotation(Autowired.class)
+                .setLiteralValue("required", "false");
 
-        if (hasOptions) {
-            method.addParameter(configurationName, 
"configuration").setFinal(true);
-        }
+        javaClass.addField()
+            .setPrivate()
+            .setName("globalConfiguration")
+            .setType("DataFormatConfigurationProperties")
+            .addAnnotation(Autowired.class);
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("dataformatConfiguration")
+            .setType(configurationName)
+            .addAnnotation(Autowired.class);
+
+        javaClass.addMethod()
+            .setConstructor(true)
+            .setPublic()
+            .setBody("super(ConfigurationPhase.REGISTER_BEAN);");
+
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("OnCamelContext")
+                .setStatic(true)
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelContext.class")
+                    .getOrigin()
+        );
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("OnCamelAutoConfiguration")
+                .setStatic(true)
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelAutoConfiguration.class")
+                    .getOrigin()
+        );
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("Condition")
+                .setStatic(true)
+                
.extendSuperType(Roaster.create(JavaClassSource.class).setName("GroupCondition"))
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelAutoConfiguration.class")
+                    .getOrigin()
+                .addMethod()
+                    .setName("Condition")
+                    .setConstructor(true)
+                    .setPublic()
+                    .setBody("super(\"camel.dataformat\", \"camel.dataformat." 
+ (overrideDataFormatName != null ? overrideDataFormatName : 
model.getName()).toLowerCase(Locale.US) + "\");")
+                    .getOrigin()
+        );
+
+
+        String body = createDataFormatBody(model.getShortJavaType());
+        String methodName = "configure" + model.getShortJavaType() + "Factory";
+
+        MethodSource<JavaClassSource> method = javaClass.addMethod()
+            .setName(methodName)
+            .setPublic()
+            .setBody(body)
+            .setReturnType("org.apache.camel.spi.DataFormatFactory")
+            .addThrows(Exception.class);
 
         // Determine all the aliases
         // adding the '-dataformat' suffix to prevent collision with component 
names
@@ -1315,25 +1433,14 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         
method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", 
"CamelContext.class");
         
method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", 
model.getShortJavaType() + ".class");
 
-        // Generate Condition
-        javaClass.addNestedType(createConditionType(
-            javaClass,
-            "camel.dataformat",
-            (overrideDataFormatName != null ? overrideDataFormatName : 
model.getName()).toLowerCase(Locale.US)
-        ));
-
         sortImports(javaClass);
 
         String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + 
".java";
         writeSourceIfChanged(javaClass, fileName);
-        writeAdditionalSpringMetaData(
-            "camel",
-            "dataformat",
-            (overrideDataFormatName != null ? overrideDataFormatName : 
model.getName()).toLowerCase(Locale.US));
     }
 
     private void createLanguageAutoConfigurationSource(
-            String packageName, LanguageModel model, List<String> 
languageAliases, boolean hasOptions, String overrideLanguageName) throws 
MojoFailureException {
+        String packageName, LanguageModel model, List<String> languageAliases, 
String overrideLanguageName) throws MojoFailureException {
 
         final JavaClassSource javaClass = 
Roaster.create(JavaClassSource.class);
 
@@ -1345,39 +1452,111 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
 
         String doc = "Generated by camel-package-maven-plugin - do not edit 
this file!";
         javaClass.getJavaDoc().setFullText(doc);
-
+        javaClass.extendSuperType(AllNestedConditions.class);
         javaClass.addAnnotation(Generated.class).setStringValue("value", 
SpringBootAutoConfigurationMojo.class.getName());
         javaClass.addAnnotation(Configuration.class);
-        
javaClass.addAnnotation(ConditionalOnBean.class).setStringValue("type", 
"org.apache.camel.spring.boot.CamelAutoConfiguration");
         javaClass.addAnnotation(Conditional.class).setLiteralValue(name + 
".Condition.class");
-        
javaClass.addAnnotation(AutoConfigureAfter.class).setStringValue("name", 
"org.apache.camel.spring.boot.CamelAutoConfiguration");
+        
javaClass.addAnnotation(AutoConfigureAfter.class).setLiteralValue("CamelAutoConfiguration.class");
 
         String configurationName = name.replace("LanguageAutoConfiguration", 
"LanguageConfiguration");
-        if (hasOptions) {
-            AnnotationSource<JavaClassSource> ann = 
javaClass.addAnnotation(EnableConfigurationProperties.class);
-            ann.setLiteralValue("value", configurationName + ".class");
-
-            javaClass.addImport("java.util.HashMap");
-            javaClass.addImport("java.util.Map");
-            javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
-        }
+        
javaClass.addAnnotation(EnableConfigurationProperties.class).setLiteralValue(
+            "{ LanguageConfigurationProperties.class, " + configurationName + 
".class }"
+        );
+        javaClass.addImport(HashMap.class);
+        javaClass.addImport(Map.class);
+        javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
 
-        javaClass.addImport("org.apache.camel.CamelContextAware");
         javaClass.addImport(model.getJavaType());
+        javaClass.addImport(List.class);
+        javaClass.addImport(ConditionalOnBean.class);
+        javaClass.addImport("org.slf4j.Logger");
+        javaClass.addImport("org.slf4j.LoggerFactory");
         javaClass.addImport("org.apache.camel.CamelContext");
+        javaClass.addImport("org.apache.camel.CamelContextAware");
+        
javaClass.addImport("org.apache.camel.spring.boot.CamelAutoConfiguration");
+        
javaClass.addImport("org.apache.camel.spring.boot.LanguageConfigurationProperties");
+        
javaClass.addImport("org.apache.camel.spring.boot.util.GroupCondition");
+        javaClass.addImport("org.apache.camel.util.ObjectHelper");
+        javaClass.addImport("org.apache.camel.spi.LanguageCustomizer");
+
+        javaClass.addField()
+            .setPrivate()
+            .setStatic(true)
+            .setFinal(true)
+            .setName("LOGGER")
+            .setType("Logger")
+            .setLiteralInitializer("LoggerFactory.getLogger(" + name + 
".class)");
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("camelContext")
+            .setType("CamelContext")
+            .addAnnotation(Autowired.class);
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("customizers")
+            .setType("List<LanguageCustomizer<" + model.getShortJavaType() + 
">>")
+            .addAnnotation(Autowired.class).setLiteralValue("required", 
"false");
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("globalConfiguration")
+            .setType("LanguageConfigurationProperties")
+            .addAnnotation(Autowired.class);
+
+        javaClass.addField()
+            .setPrivate()
+            .setName("languageConfiguration")
+            .setType(configurationName)
+            .addAnnotation(Autowired.class);
+
+        javaClass.addMethod()
+            .setConstructor(true)
+            .setPublic()
+            .setBody("super(ConfigurationPhase.REGISTER_BEAN);");
 
-        String body = createLanguageBody(model.getShortJavaType(), hasOptions);
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("OnCamelContext")
+                .setStatic(true)
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelContext.class")
+                    .getOrigin()
+        );
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("OnCamelAutoConfiguration")
+                .setStatic(true)
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelAutoConfiguration.class")
+                    .getOrigin()
+        );
+        javaClass.addNestedType(
+            Roaster.create(JavaClassSource.class)
+                .setName("Condition")
+                .setStatic(true)
+                
.extendSuperType(Roaster.create(JavaClassSource.class).setName("GroupCondition"))
+                .addAnnotation(ConditionalOnBean.class)
+                    .setLiteralValue("CamelAutoConfiguration.class")
+                    .getOrigin()
+                .addMethod()
+                    .setName("Condition")
+                    .setConstructor(true)
+                    .setPublic()
+                    .setBody("super(\"camel.component\", \"camel.component." + 
(overrideLanguageName != null ? overrideLanguageName : 
model.getName()).toLowerCase(Locale.US) + "\");")
+                    .getOrigin()
+        );
+
+        String body = createLanguageBody(model.getShortJavaType());
         String methodName = "configure" + model.getShortJavaType();
 
         MethodSource<JavaClassSource> method = javaClass.addMethod()
-                .setName(methodName)
-                .setPublic()
-                .setBody(body)
-                .setReturnType(model.getShortJavaType())
-                .addThrows(Exception.class);
-
-        method.addParameter("CamelContext", "camelContext");
-        method.addParameter(configurationName, "configuration");
+            .setName(methodName)
+            .setPublic()
+            .setBody(body)
+            .setReturnType(model.getShortJavaType())
+            .addThrows(Exception.class);
 
         // Determine all the aliases
         // adding the '-language' suffix to prevent collision with component 
names
@@ -1388,21 +1567,10 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         
method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", 
"CamelContext.class");
         
method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", 
model.getShortJavaType() + ".class");
 
-        // Generate Condition
-        javaClass.addNestedType(createConditionType(
-            javaClass,
-            "camel.language",
-            (overrideLanguageName != null ? overrideLanguageName : 
model.getName()).toLowerCase(Locale.US)
-        ));
-
         sortImports(javaClass);
 
         String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + 
".java";
         writeSourceIfChanged(javaClass, fileName);
-        writeAdditionalSpringMetaData(
-            "camel",
-            "language",
-            (overrideLanguageName != null ? overrideLanguageName : 
model.getName()).toLowerCase(Locale.US));
     }
 
     private void createComponentSpringFactorySource(String packageName, 
ComponentModel model) throws MojoFailureException {
@@ -1429,40 +1597,48 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         writeComponentSpringFactorySource(packageName, name);
     }
 
-    private static String createComponentBody(String shortJavaType, boolean 
hasOptions) {
+    private static String createComponentBody(String shortJavaType) {
         StringBuilder sb = new StringBuilder();
         sb.append(shortJavaType).append(" component = new 
").append(shortJavaType).append("();").append("\n");
         sb.append("component.setCamelContext(camelContext);\n");
         sb.append("\n");
-        if (hasOptions) {
-            sb.append("Map<String, Object> parameters = new HashMap<>();\n");
-            sb.append("IntrospectionSupport.getProperties(configuration, 
parameters, null, false);\n");
-            sb.append("\n");
-            sb.append("for (Map.Entry<String, Object> entry : 
parameters.entrySet()) {\n");
-            sb.append("    Object value = entry.getValue();\n");
-            sb.append("    Class<?> paramClass = value.getClass();\n");
-            sb.append("    if 
(paramClass.getName().endsWith(\"NestedConfiguration\")) {\n");
-            sb.append("        Class nestedClass = null;\n");
-            sb.append("        try {\n");
-            sb.append("            nestedClass = (Class) 
paramClass.getDeclaredField(\"CAMEL_NESTED_CLASS\").get(null);\n");
-            sb.append("            HashMap<String, Object> nestedParameters = 
new HashMap<>();\n");
-            sb.append("            IntrospectionSupport.getProperties(value, 
nestedParameters, null, false);\n");
-            sb.append("            Object nestedProperty = 
nestedClass.newInstance();\n");
-            sb.append("            
IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), nestedProperty, nestedParameters);\n");
-            sb.append("            entry.setValue(nestedProperty);\n");
-            sb.append("        } catch (NoSuchFieldException e) {\n");
-            sb.append("            // ignore, class must not be a nested 
configuration class after all\n");
-            sb.append("        }\n");
-            sb.append("    }\n");
-            sb.append("}\n");
-            sb.append("IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), component, parameters);\n");
-        }
+        sb.append("Map<String, Object> parameters = new HashMap<>();\n");
+        sb.append("IntrospectionSupport.getProperties(componentConfiguration, 
parameters, null, false);\n");
+        sb.append("\n");
+        sb.append("for (Map.Entry<String, Object> entry : 
parameters.entrySet()) {\n");
+        sb.append("    Object value = entry.getValue();\n");
+        sb.append("    Class<?> paramClass = value.getClass();\n");
+        sb.append("    if 
(paramClass.getName().endsWith(\"NestedConfiguration\")) {\n");
+        sb.append("        Class nestedClass = null;\n");
+        sb.append("        try {\n");
+        sb.append("            nestedClass = (Class) 
paramClass.getDeclaredField(\"CAMEL_NESTED_CLASS\").get(null);\n");
+        sb.append("            HashMap<String, Object> nestedParameters = new 
HashMap<>();\n");
+        sb.append("            IntrospectionSupport.getProperties(value, 
nestedParameters, null, false);\n");
+        sb.append("            Object nestedProperty = 
nestedClass.newInstance();\n");
+        sb.append("            
IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), nestedProperty, nestedParameters);\n");
+        sb.append("            entry.setValue(nestedProperty);\n");
+        sb.append("        } catch (NoSuchFieldException e) {\n");
+        sb.append("            // ignore, class must not be a nested 
configuration class after all\n");
+        sb.append("        }\n");
+        sb.append("    }\n");
+        sb.append("}\n");
+        sb.append("IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), component, parameters);\n");
+        sb.append("\n");
+        sb.append("boolean useConfigurers = 
globalConfiguration.getConfigurer().isEnabled() && 
componentConfiguration.getConfigurer().isEnabled();\n");
+        sb.append("\n");
+        sb.append("if (useConfigurers && ObjectHelper.isNotEmpty(customizers)) 
{\n");
+        sb.append("    for 
(ComponentCustomizer<").append(shortJavaType).append("> configurer : 
customizers) {\n");
+        sb.append("        LOGGER.debug(\"Configure component {}, with 
configurer {}\", component, configurer);\n");
+        sb.append("        configurer.customize(component);\n");
+        sb.append("    }\n");
+        sb.append("}\n");
         sb.append("\n");
         sb.append("return component;");
+
         return sb.toString();
     }
 
-    private static String createDataFormatBody(String shortJavaType, boolean 
hasOptions) {
+    private static String createDataFormatBody(String shortJavaType) {
         StringBuilder sb = new StringBuilder();
         sb.append("return new DataFormatFactory() {\n");
         sb.append("    public DataFormat newInstance() {\n");
@@ -1473,16 +1649,23 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         sb.append("                
contextAware.setCamelContext(camelContext);\n");
         sb.append("            }\n");
         sb.append("        }\n");
-        if (hasOptions) {
-            sb.append("\n");
-            sb.append("        try {\n");
-            sb.append("            Map<String, Object> parameters = new 
HashMap<>();\n");
-            sb.append("            
IntrospectionSupport.getProperties(configuration, parameters, null, false);\n");
-            sb.append("            
IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), dataformat, parameters);\n");
-            sb.append("        } catch (Exception e) {\n");
-            sb.append("            throw new RuntimeCamelException(e);\n");
-            sb.append("        }\n");
-        }
+        sb.append("\n");
+        sb.append("        try {\n");
+        sb.append("            Map<String, Object> parameters = new 
HashMap<>();\n");
+        sb.append("            
IntrospectionSupport.getProperties(dataformatConfiguration, parameters, null, 
false);\n");
+        sb.append("            
IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), dataformat, parameters);\n");
+        sb.append("        } catch (Exception e) {\n");
+        sb.append("            throw new RuntimeCamelException(e);\n");
+        sb.append("        }\n");
+        sb.append("\n");
+        sb.append("boolean useConfigurers = 
globalConfiguration.getConfigurer().isEnabled() && 
dataformatConfiguration.getConfigurer().isEnabled();\n");
+        sb.append("\n");
+        sb.append("if (useConfigurers && ObjectHelper.isNotEmpty(customizers)) 
{\n");
+        sb.append("    for 
(DataFormatCustomizer<").append(shortJavaType).append("> configurer : 
customizers) {\n");
+        sb.append("        LOGGER.debug(\"Configure dataformat {}, with 
configurer {}\", dataformat, configurer);\n");
+        sb.append("        configurer.customize(dataformat);\n");
+        sb.append("    }\n");
+        sb.append("}\n");
         sb.append("\n");
         sb.append("        return dataformat;\n");
         sb.append("    }\n");
@@ -1490,7 +1673,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         return sb.toString();
     }
 
-    private static String createLanguageBody(String shortJavaType, boolean 
hasOptions) {
+    private static String createLanguageBody(String shortJavaType) {
         StringBuilder sb = new StringBuilder();
         sb.append(shortJavaType).append(" language = new 
").append(shortJavaType).append("();").append("\n");
         sb.append("if 
(CamelContextAware.class.isAssignableFrom(").append(shortJavaType).append(".class))
 {\n");
@@ -1499,21 +1682,27 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         sb.append("        contextAware.setCamelContext(camelContext);\n");
         sb.append("    }\n");
         sb.append("}\n");
-        if (hasOptions) {
-            sb.append("\n");
-            sb.append("Map<String, Object> parameters = new HashMap<>();\n");
-            sb.append("IntrospectionSupport.getProperties(configuration, 
parameters, null, false);\n");
-            sb.append("\n");
-            sb.append("IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), language, parameters);\n");
-        }
+        sb.append("\n");
+        sb.append("Map<String, Object> parameters = new HashMap<>();\n");
+        sb.append("IntrospectionSupport.getProperties(languageConfiguration, 
parameters, null, false);\n");
+        sb.append("IntrospectionSupport.setProperties(camelContext, 
camelContext.getTypeConverter(), language, parameters);\n");
+        sb.append("\n");
+        sb.append("boolean useConfigurers = 
globalConfiguration.getConfigurer().isEnabled() && 
languageConfiguration.getConfigurer().isEnabled();\n");
+        sb.append("\n");
+        sb.append("if (useConfigurers && ObjectHelper.isNotEmpty(customizers)) 
{\n");
+        sb.append("    for 
(LanguageCustomizer<").append(shortJavaType).append("> configurer : 
customizers) {\n");
+        sb.append("        LOGGER.debug(\"Configure language {}, with 
configurer {}\", language, configurer);\n");
+        sb.append("        configurer.customize(language);\n");
+        sb.append("    }\n");
+        sb.append("}\n");
         sb.append("\n");
         sb.append("return language;");
         return sb.toString();
     }
 
-    private static void sortImports(JavaClassSource javaClass) {
+    private static void sortImports(Importer importer) {
         // sort imports
-        List<Import> imports = javaClass.getImports();
+        List<Import> imports = importer.getImports();
 
         // sort imports
         List<String> names = new ArrayList<>();
@@ -1548,21 +1737,14 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
 
         // remove all imports first
         for (String name : names) {
-            javaClass.removeImport(name);
+            importer.removeImport(name);
         }
         // and add them back in correct order
         for (String name : names) {
-            javaClass.addImport(name);
+            importer.addImport(name);
         }
     }
 
-    private static String sourceToString(JavaClassSource javaClass) {
-        String code = Formatter.format(javaClass);
-        // convert tabs to 4 spaces
-        code = code.replaceAll("\\t", "    ");
-        return code;
-    }
-
     private static String loadModelJson(Set<File> jsonFiles, String modelName) 
{
         try {
             for (File file : jsonFiles) {
@@ -1874,6 +2056,13 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
     }
 
     private void writeSourceIfChanged(JavaClassSource source, String fileName) 
throws MojoFailureException {
+        writeSourceIfChanged(source.toString(), fileName);
+    }
+
+    private void writeSourceIfChanged(String source, String fileName) throws 
MojoFailureException {
+
+        source = Formatter.format(source);
+        source = source.replaceAll("\\t", "    ");
 
         File target = new File(SpringBootHelper.starterSrcDir(baseDir, 
project.getArtifactId()), fileName);
 
@@ -1882,7 +2071,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         try {
             InputStream is = 
getClass().getClassLoader().getResourceAsStream("license-header-java.txt");
             String header = loadText(is);
-            String code = sourceToString(source);
+            String code = source;
             code = header + code;
             getLog().debug("Source code generated:\n" + code);
 
@@ -1974,6 +2163,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         }
     }
 
+    /*
     private void writeAdditionalSpringMetaData(String prefix, String type, 
String name) throws MojoFailureException {
         String fullQualifiedName = prefix + "." + type + "." + name + "." + 
"enabled";
         String fileName = 
"META-INF/additional-spring-configuration-metadata.json";
@@ -2019,6 +2209,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
             throw new MojoFailureException("IOError with file " + target, e);
         }
     }
+    */
 
     private void deleteFileOnMainArtifact(File starterFile) {
         if (!DELETE_FILES_ON_MAIN_ARTIFACTS) {
@@ -2048,7 +2239,7 @@ public class SpringBootAutoConfigurationMojo extends 
AbstractMojo {
         condition.extendSuperType(SpringBootCondition.class);
         condition.setPublic();
         condition.setStatic(true);
-        
+
         condition.addAnnotation(Generated.class).setStringValue("value", 
SpringBootAutoConfigurationMojo.class.getName());
 
         String fullQualifiedType = prefix.endsWith(".") ? prefix +  type : 
prefix + "." + type;

Reply via email to