You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2019/08/24 10:21:14 UTC

[camel] branch master updated: CAMEL-13870: Fix apt using wrong name. And preparing for generating for fast component options.

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


The following commit(s) were added to refs/heads/master by this push:
     new 2919474  CAMEL-13870: Fix apt using wrong name. And preparing for generating for fast component options.
2919474 is described below

commit 291947472afc0dfc5d487d867b21b21c4d6df42e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Aug 24 12:21:00 2019 +0200

    CAMEL-13870: Fix apt using wrong name. And preparing for generating for fast component options.
---
 .../apt/ComponentPropertyConfigurerGenerator.java  | 150 +++++++++++++++++++++
 .../tools/apt/EndpointAnnotationProcessor.java     |  10 +-
 .../camel/tools/apt/helper/JsonSchemaHelper.java   |   6 +-
 .../camel/tools/apt/model/ComponentOption.java     |  14 +-
 4 files changed, 171 insertions(+), 9 deletions(-)

diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java
new file mode 100644
index 0000000..4f9474b
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java
@@ -0,0 +1,150 @@
+/*
+ * 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.tools.apt;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Set;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import javax.tools.FileObject;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import org.apache.camel.tools.apt.helper.IOHelper;
+import org.apache.camel.tools.apt.model.ComponentOption;
+import org.apache.camel.tools.apt.model.EndpointOption;
+
+import static org.apache.camel.tools.apt.AnnotationProcessorHelper.dumpExceptionToErrorFile;
+
+public final class ComponentPropertyConfigurerGenerator {
+
+    private ComponentPropertyConfigurerGenerator() {
+    }
+
+    public static void generateExtendConfigurer(ProcessingEnvironment processingEnv, TypeElement parent,
+                                                String pn, String cn, String fqn) {
+
+        Writer w = null;
+        try {
+            JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn, parent);
+            w = src.openWriter();
+
+            w.write("/* Generated by org.apache.camel:apt */\n");
+            w.write("package " + pn + ";\n");
+            w.write("\n");
+            w.write("import " + parent.getQualifiedName().toString() + ";\n");
+            w.write("\n");
+            w.write("/**\n");
+            w.write(" * Source code generated by org.apache.camel:apt\n");
+            w.write(" */\n");
+            w.write("public class " + cn + " extends " + parent.getSimpleName().toString() + " {\n");
+            w.write("\n");
+            w.write("}\n");
+            w.write("\n");
+        } catch (Exception e) {
+            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to generate source code file: " + fqn + ": " + e.getMessage());
+            dumpExceptionToErrorFile("camel-apt-error.log", "Unable to generate source code file: " + fqn, e);
+        } finally {
+            IOHelper.close(w);
+        }
+    }
+
+    public static void generatePropertyConfigurer(ProcessingEnvironment processingEnv, TypeElement parent,
+                                                  String pn, String cn, String fqn, String en,
+                                                  Set<ComponentOption> options) {
+
+        Writer w = null;
+        try {
+            JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn, parent);
+            w = src.openWriter();
+
+            int size = options.size();
+
+            w.write("/* Generated by org.apache.camel:apt */\n");
+            w.write("package " + pn + ";\n");
+            w.write("\n");
+            w.write("import java.util.HashMap;\n");
+            w.write("import java.util.Map;\n");
+            w.write("\n");
+            w.write("import org.apache.camel.CamelContext;\n");
+            w.write("import org.apache.camel.spi.TriPropertyConfigurer;\n");
+            w.write("import org.apache.camel.support.component.PropertyConfigurerSupport;\n");
+            w.write("import org.apache.camel.util.function.TriConsumer;\n");
+            w.write("\n");
+            w.write("/**\n");
+            w.write(" * Source code generated by org.apache.camel:apt\n");
+            w.write(" */\n");
+            w.write("public class " + cn + " extends PropertyConfigurerSupport implements TriPropertyConfigurer {\n");
+            w.write("\n");
+            w.write("    private static final Map<String, TriConsumer<CamelContext, Object, Object>> WRITES;\n");
+            w.write("    static {\n");
+            w.write("        Map<String, TriConsumer<CamelContext, Object, Object>> map = new HashMap<>(" + size + ");\n");
+            for (ComponentOption option : options) {
+                String getOrSet = option.getName();
+                getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1);
+                String setterLambda = setterLambda(en, getOrSet, option.getType(), option.getConfigurationField());
+                w.write("        map.put(\"" + option.getName() + "\", (camelContext, component, value) -> " + setterLambda + ");\n");
+            }
+            w.write("        WRITES = map;\n");
+            w.write("    }\n");
+            w.write("\n");
+            w.write("    @Override\n");
+            w.write("    public Map<String, TriConsumer<CamelContext, Object, Object>> getWriteOptions(CamelContext camelContext) {\n");
+            w.write("        return WRITES;\n");
+            w.write("    }\n");
+            w.write("\n");
+            w.write("}\n");
+            w.write("\n");
+        } catch (Exception e) {
+            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to generate source code file: " + fqn + ": " + e.getMessage());
+            dumpExceptionToErrorFile("camel-apt-error.log", "Unable to generate source code file: " + fqn, e);
+        } finally {
+            IOHelper.close(w);
+        }
+    }
+
+    private static String setterLambda(String en, String getOrSet, String type, String configurationField) {
+        // type may contain generics so remove those
+        if (type.indexOf('<') != -1) {
+            type = type.substring(0, type.indexOf('<'));
+        }
+        if (configurationField != null) {
+            getOrSet = "get" + Character.toUpperCase(configurationField.charAt(0)) + configurationField.substring(1) + "().set" + getOrSet;
+        } else {
+            getOrSet = "set" + getOrSet;
+        }
+
+        // ((LogEndpoint) endpoint).setGroupSize(property(camelContext, java.lang.Integer.class, value))
+        return String.format("((%s) component).%s(property(camelContext, %s.class, value))", en, getOrSet, type);
+    }
+
+    public static void generateMetaInfConfigurer(ProcessingEnvironment processingEnv, String name, String fqn) {
+        try {
+            FileObject resource = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "",
+                    "META-INF/services/org/apache/camel/configurer/" + name);
+            try (Writer w = resource.openWriter()) {
+                w.append("# Generated by camel annotation processor\n");
+                w.append("class=").append(fqn).append("\n");
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
index 400b03a..8d7d7d6 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
@@ -165,7 +165,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
 
         TypeElement componentClassElement = findTypeElement(processingEnv, roundEnv, componentModel.getJavaType());
         if (componentClassElement != null) {
-            findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "", parentData);
+            findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "", parentData, null, null);
         }
 
         findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "", uriEndpoint.excludeProperties(), parentData, null, null);
@@ -185,7 +185,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
             EndpointPropertyConfigurerGenerator.generateExtendConfigurer(processingEnv, parent, pn, cn, fqn);
             EndpointPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-endpoint", fqn);
         } else if (uriEndpoint.generateConfigurer() && !endpointOptions.isEmpty()) {
-            TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.support.component.EndpointPropertyConfigurerSupport");
+            TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.spi.TriPropertyConfigurer");
             String fqen = classElement.getQualifiedName().toString();
             String pn = fqen.substring(0, fqen.lastIndexOf('.'));
             String en = classElement.getSimpleName().toString();
@@ -279,7 +279,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "property", required, entry.getType(), defaultValue, doc,
                 entry.isDeprecated(), entry.getDeprecationNote(), entry.isSecret(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(),
-                false, null, asPredicate, optionalPrefix, prefix, multiValue, null, null));
+                false, null, asPredicate, optionalPrefix, prefix, multiValue, entry.getConfigurationClass(), entry.getConfigurationField()));
 
             parentComponentProperties.remove(entry.getName());
         }
@@ -508,7 +508,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
 
     protected void findComponentClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel,
                                                 Set<ComponentOption> componentOptions, TypeElement classElement, String prefix,
-                                                Map<String, Object> parentData) {
+                                                Map<String, Object> parentData, String nestedTypeName, String nestedFieldName) {
         Elements elementUtils = processingEnv.getElementUtils();
         while (true) {
             Metadata componentAnnotation = classElement.getAnnotation(Metadata.class);
@@ -616,7 +616,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
 
                 String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                 ComponentOption option = new ComponentOption(name, displayName, fieldTypeName, required, defaultValue, defaultValueNote,
-                        docComment.trim(), deprecated, deprecationNote, secret, group, label, isEnum, enums);
+                        docComment.trim(), deprecated, deprecationNote, secret, group, label, isEnum, enums, nestedTypeName, nestedFieldName);
                 componentOptions.add(option);
             }
 
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
index cda387c..b4619ff 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
@@ -43,7 +43,7 @@ public final class JsonSchemaHelper {
     public static String toJson(String name, String displayName, String kind, Boolean required, String type, String defaultValue, String description,
                                 Boolean deprecated, String deprecationNote, Boolean secret, String group, String label, boolean enumType, Set<String> enums,
                                 boolean oneOfType, Set<String> oneOffTypes, boolean asPredicate, String optionalPrefix, String prefix, boolean multiValue,
-                                String configurationClass, String configurtationField) {
+                                String configurationClass, String configurationField) {
         String typeName = JsonSchemaHelper.getType(type, enumType);
 
         StringBuilder sb = new StringBuilder();
@@ -158,9 +158,9 @@ public final class JsonSchemaHelper {
             sb.append(", \"configurationClass\": ");
             sb.append(Strings.doubleQuote(configurationClass));
         }
-        if (!Strings.isNullOrEmpty(configurtationField)) {
+        if (!Strings.isNullOrEmpty(configurationField)) {
             sb.append(", \"configurationField\": ");
-            sb.append(Strings.doubleQuote(configurtationField));
+            sb.append(Strings.doubleQuote(configurationField));
         }
 
         if (!Strings.isNullOrEmpty(description)) {
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java
index f2b3a53..537594b 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java
@@ -36,10 +36,12 @@ public final class ComponentOption {
     private String label;
     private boolean enumType;
     private Set<String> enums;
+    private String configurationClass;
+    private String configurationField;
 
     public ComponentOption(String name, String displayName, String type, boolean required, String defaultValue, String defaultValueNote,
                            String documentation, boolean deprecated, String deprecationNote, boolean secret, String group, String label,
-                           boolean enumType, Set<String> enums) {
+                           boolean enumType, Set<String> enums, String configurationClass, String nestedFieldName) {
         this.name = name;
         this.displayName = displayName;
         this.type = type;
@@ -54,6 +56,8 @@ public final class ComponentOption {
         this.label = label;
         this.enumType = enumType;
         this.enums = enums;
+        this.configurationClass = configurationClass;
+        this.configurationField = nestedFieldName;
     }
 
     public String getName() {
@@ -115,6 +119,14 @@ public final class ComponentOption {
         return enums;
     }
 
+    public String getConfigurationClass() {
+        return configurationClass;
+    }
+
+    public String getConfigurationField() {
+        return configurationField;
+    }
+
     public String getGroup() {
         return group;
     }