This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit ad777d1796768fa2ef30785de81e4b16074edbbf Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Apr 8 12:30:47 2020 +0200 CAMEL-14864: Be able to generate configurer for any pojo. WIP --- .../main/java/org/apache/camel/spi/Configurer.java | 46 +++++++++++++ .../maven/packaging/GenerateComponentMojo.java | 2 + ...igurerMojo.java => GenerateConfigurerMojo.java} | 79 +++++++++++++++++----- .../apache/camel/maven/packaging/GenerateMojo.java | 2 + .../camel/maven/packaging/MainConfigurerMojo.java | 1 + 5 files changed, 114 insertions(+), 16 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java b/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java new file mode 100644 index 0000000..72aeabe --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.spi; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * An annotation used to mark classes to indicate code capable + * of configuring its options via a getter/setters that can be called + * via Camels {@link org.apache.camel.spi.PropertyConfigurer}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Target({ElementType.TYPE}) +public @interface Configurer { + + /** + * Whether to let the Camel compiler plugin to generate java source code + * for fast configuration. + */ + boolean generateConfigurer() default true; + + /** + * Whether this configurer is read-only (can only use getters) + */ + boolean readOnly() default false; + +} diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java index 49ca731..7077cdd 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java @@ -40,6 +40,8 @@ public class GenerateComponentMojo extends AbstractGenerateMojo { invoke(TypeConverterLoaderGeneratorMojo.class); // generate-spi invoke(SpiGeneratorMojo.class); + // generate-configurer + invoke(GenerateConfigurerMojo.class); // generate-endpoint-schema invoke(EndpointSchemaGeneratorMojo.class); // prepare-components diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateConfigurerMojo.java similarity index 64% copy from tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java copy to tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateConfigurerMojo.java index 434d627..55f7265 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateConfigurerMojo.java @@ -18,12 +18,18 @@ package org.apache.camel.maven.packaging; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.apache.camel.tooling.model.BaseOptionModel; import org.apache.maven.plugin.MojoExecutionException; @@ -31,26 +37,28 @@ import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationTarget; +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Index; +import org.jboss.jandex.IndexReader; import org.springframework.util.ReflectionUtils; /** - * Generate configurer classes for camel-main. + * Generate configurer classes from @Configuer annotated classes. */ -@Mojo(name = "generate-main-configurer", threadSafe = true, defaultPhase = LifecyclePhase.PROCESS_CLASSES) -public class MainConfigurerMojo extends AbstractGeneratorMojo { +@Mojo(name = "generate-configurer", threadSafe = true, defaultPhase = LifecyclePhase.PROCESS_CLASSES) +public class GenerateConfigurerMojo extends AbstractGeneratorMojo { - private static final String[] CLASS_NAMES = new String[]{ - "org.apache.camel.main.MainConfigurationProperties", - "org.apache.camel.main.HystrixConfigurationProperties", - "org.apache.camel.main.Resilience4jConfigurationProperties", - "org.apache.camel.main.RestConfigurationProperties", - "org.apache.camel.ExtendedCamelContext"}; + public static final DotName CONFIGURER = DotName.createSimple("org.apache.camel.spi.Configurer"); /** * The output directory for generated java source code */ @Parameter(defaultValue = "${project.basedir}/src/generated/java") - protected File srcOutDir; + protected File sourcesOutputDir; @Parameter(defaultValue = "${project.basedir}/src/generated/resources") protected File resourcesOutputDir; @@ -66,8 +74,18 @@ public class MainConfigurerMojo extends AbstractGeneratorMojo { } } + public GenerateConfigurerMojo() { + } + @Override public void execute() throws MojoExecutionException, MojoFailureException { + if (sourcesOutputDir == null) { + sourcesOutputDir = new File(project.getBasedir(), "src/generated/java"); + } + if (resourcesOutputDir == null) { + resourcesOutputDir = new File(project.getBasedir(), "src/generated/resources"); + } + List<String> cp = new ArrayList<>(); cp.add(0, project.getBuild().getOutputDirectory()); project.getDependencyArtifacts().forEach(a -> { @@ -77,7 +95,28 @@ public class MainConfigurerMojo extends AbstractGeneratorMojo { }); projectClassLoader = DynamicClassLoader.createDynamicClassLoader(cp); - for (String fqn : CLASS_NAMES) { + Path output = Paths.get(project.getBuild().getOutputDirectory()); + Index index; + try (InputStream is = Files.newInputStream(output.resolve("META-INF/jandex.idx"))) { + index = new IndexReader(is).read(); + } catch (IOException e) { + throw new MojoExecutionException("IOException: " + e.getMessage(), e); + } + + Set<String> classes = new LinkedHashSet<>(); + + // discover all classes annotated with @Configurer + List<AnnotationInstance> annotations = index.getAnnotations(CONFIGURER); + annotations.stream() + .filter(annotation -> annotation.target().kind() == AnnotationTarget.Kind.CLASS) + .filter(annotation -> annotation.target().asClass().nestingType() == ClassInfo.NestingType.TOP_LEVEL) + .filter(annotation -> asBooleanDefaultTrue(annotation, "generateConfigurer")) + .forEach(annotation -> { + String currentClass = annotation.target().asClass().name().toString(); + classes.add(currentClass); + }); + + for (String fqn : classes) { try { List<Option> options = processClass(fqn); generateConfigurer(fqn, options); @@ -120,8 +159,9 @@ public class MainConfigurerMojo extends AbstractGeneratorMojo { } private void generateConfigurer(String name, List<Option> options) throws IOException { - String pn = "org.apache.camel.main"; - String cn = name.substring(name.lastIndexOf('.') + 1) + "Configurer"; + int pos = name.lastIndexOf('.'); + String pn = name.substring(0, pos); + String cn = name.substring(pos + 1) + "Configurer"; String en = name; String pfqn = name; String psn = "org.apache.camel.support.component.PropertyConfigurerSupport"; @@ -132,15 +172,17 @@ public class MainConfigurerMojo extends AbstractGeneratorMojo { String source = sw.toString(); String fileName = pn.replace('.', '/') + "/" + cn + ".java"; - boolean updated = updateResource(srcOutDir.toPath(), fileName, source); + sourcesOutputDir.mkdirs(); + boolean updated = updateResource(sourcesOutputDir.toPath(), fileName, source); if (updated) { getLog().info("Updated " + fileName); } } private void generateMetaInfConfigurer(String name) { - String pn = "org.apache.camel.main"; - String en = name.substring(name.lastIndexOf('.') + 1); + int pos = name.lastIndexOf('.'); + String pn = name.substring(0, pos); + String en = name.substring(pos + 1); try (Writer w = new StringWriter()) { w.append("# " + GENERATED_MSG + "\n"); w.append("class=").append(pn).append(".").append(en).append("Configurer").append("\n"); @@ -150,4 +192,9 @@ public class MainConfigurerMojo extends AbstractGeneratorMojo { } } + private static boolean asBooleanDefaultTrue(AnnotationInstance ai, String name) { + AnnotationValue av = ai.value(name); + return av == null || av.asBoolean(); + } + } diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java index dba8ac7..65303b5 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java @@ -46,6 +46,8 @@ public class GenerateMojo extends AbstractGenerateMojo { invoke(EndpointSchemaGeneratorMojo.class); // prepare-components invoke(PrepareComponentMojo.class); + // generate-configurer + invoke(GenerateConfigurerMojo.class); // prepare-main invoke(PrepareCamelMainMojo.class); // generate-xml-parser diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java index 434d627..533b7d9 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MainConfigurerMojo.java @@ -37,6 +37,7 @@ import org.springframework.util.ReflectionUtils; * Generate configurer classes for camel-main. */ @Mojo(name = "generate-main-configurer", threadSafe = true, defaultPhase = LifecyclePhase.PROCESS_CLASSES) +@Deprecated public class MainConfigurerMojo extends AbstractGeneratorMojo { private static final String[] CLASS_NAMES = new String[]{