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 2020/09/28 06:18:37 UTC

[camel] 01/04: CAMEL-15579: Optimize generated configurer to use static block for getAllOptions

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 a855f993e400a17972126026c9dba4a1010b5b22
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Sep 28 06:58:10 2020 +0200

    CAMEL-15579: Optimize generated configurer to use static block for getAllOptions
---
 .../apache/camel/tooling/model/Comparators.java    |  4 +
 .../packaging/AbstractGenerateConfigurerMojo.java  |  2 +-
 .../maven/packaging/AbstractGeneratorMojo.java     |  2 +-
 .../packaging/EndpointSchemaGeneratorMojo.java     |  9 ++-
 .../packaging/EndpointUriFactoryGenerator.java     |  1 -
 .../packaging/PropertyConfigurerGenerator.java     | 93 ++++++++++++++++++----
 6 files changed, 89 insertions(+), 22 deletions(-)

diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Comparators.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Comparators.java
index 8879c4c..0adc40d 100644
--- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Comparators.java
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Comparators.java
@@ -30,4 +30,8 @@ public final class Comparators {
     public static Comparator<ApiMethodModel> apiMethodModelModelComparator() {
         return (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName());
     }
+
+    public static Comparator<ComponentModel.ApiOptionModel> apiOptionModelComparator() {
+        return (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName());
+    }
 }
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java
index 4ad7875..449f1e4 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java
@@ -383,7 +383,7 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
 
         StringWriter sw = new StringWriter();
         PropertyConfigurerGenerator.generatePropertyConfigurer(pn, cn, en, pfqn, psn,
-                false, false, options, sw);
+                false, false, options, null, sw);
 
         String source = sw.toString();
 
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
index 5bca3e3..75c8c2a 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
@@ -172,7 +172,7 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
             } catch (ClassNotFoundException e) {
                 int dotIndex = loadClassName.lastIndexOf('.');
                 if (dotIndex == -1) {
-                    throw new IllegalArgumentException(org);
+                    throw new NoClassDefFoundError(org);
                 } else {
                     loadClassName = loadClassName.substring(0, dotIndex) + "$" + loadClassName.substring(dotIndex + 1);
                 }
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
index 7dc9603..c6ffe06 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
@@ -443,7 +443,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         generatePropertyConfigurer(packageName, className, fqClassName, componentClassName,
                 pfqn, psn,
                 componentModel.getScheme() + "-component", hasSuper, true,
-                options);
+                options, componentModel);
     }
 
     private void generateEndpointConfigurer(
@@ -492,7 +492,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         generatePropertyConfigurer(packageName, className, fqClassName, endpointClassName,
                 pfqn, psn,
                 componentModel.getScheme() + "-endpoint", hasSuper, false,
-                options);
+                options, componentModel);
     }
 
     protected ComponentModel findComponentProperties(
@@ -1216,10 +1216,11 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
     protected void generatePropertyConfigurer(
             String pn, String cn, String fqn, String en,
             String pfqn, String psn, String scheme, boolean hasSuper, boolean component,
-            Collection<? extends BaseOptionModel> options) {
+            Collection<? extends BaseOptionModel> options, ComponentModel model) {
 
         try (Writer w = new StringWriter()) {
-            PropertyConfigurerGenerator.generatePropertyConfigurer(pn, cn, en, pfqn, psn, hasSuper, component, options, w);
+            PropertyConfigurerGenerator.generatePropertyConfigurer(pn, cn, en, pfqn, psn, hasSuper, component, options, model,
+                    w);
             updateResource(sourcesOutputDir.toPath(), fqn.replace('.', '/') + ".java", w.toString());
         } catch (Exception e) {
             throw new RuntimeException("Unable to generate source code file: " + fqn + ": " + e.getMessage(), e);
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointUriFactoryGenerator.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointUriFactoryGenerator.java
index e35bfb7..3103aa3 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointUriFactoryGenerator.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointUriFactoryGenerator.java
@@ -61,7 +61,6 @@ public final class EndpointUriFactoryGenerator {
         w.write("    private static final Set<String> PROPERTY_NAMES;\n");
         w.write(generatePropertyNames(model));
         w.write("\n");
-        w.write("\n");
         w.write("    @Override\n");
         w.write("    public boolean isEnabled(String scheme) {\n");
         if (alternative == null) {
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PropertyConfigurerGenerator.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PropertyConfigurerGenerator.java
index c9d0fee..0c53345 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PropertyConfigurerGenerator.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PropertyConfigurerGenerator.java
@@ -22,9 +22,12 @@ import java.util.Collection;
 import java.util.Comparator;
 import java.util.LinkedHashSet;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
 
 import org.apache.camel.tooling.model.BaseOptionModel;
+import org.apache.camel.tooling.model.Comparators;
+import org.apache.camel.tooling.model.ComponentModel;
 
 public final class PropertyConfigurerGenerator {
 
@@ -34,7 +37,7 @@ public final class PropertyConfigurerGenerator {
     public static void generatePropertyConfigurer(
             String pn, String cn, String en,
             String pfqn, String psn, boolean hasSuper, boolean component,
-            Collection<? extends BaseOptionModel> options, Writer w)
+            Collection<? extends BaseOptionModel> options, ComponentModel model, Writer w)
             throws IOException {
 
         w.write("/* " + AbstractGeneratorMojo.GENERATED_MSG + " */\n");
@@ -55,6 +58,15 @@ public final class PropertyConfigurerGenerator {
         w.write("public class " + cn + " extends " + psn
                 + " implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {\n");
         w.write("\n");
+
+        // if from component model then we can not optimize this and use a static block
+        if (model != null) {
+            // static block for all options which is immutable information
+            w.write("    private static final Map<String, Object> ALL_OPTIONS;\n");
+            w.write(generateAllOptions(component, model));
+            w.write("\n");
+        }
+
         if (!options.isEmpty() || !hasSuper) {
 
             // sort options A..Z so they always have same order
@@ -98,23 +110,28 @@ public final class PropertyConfigurerGenerator {
             w.write("\n");
             w.write("    @Override\n");
             w.write("    public Map<String, Object> getAllOptions(Object target) {\n");
-            if (hasSuper) {
-                w.write("        Map<String, Object> answer = super.getAllOptions(target);\n");
+            if (model != null) {
+                w.write("        return ALL_OPTIONS;\n");
+                w.write("    }\n");
             } else {
-                w.write("        Map<String, Object> answer = new CaseInsensitiveMap();\n");
-            }
-            if (!options.isEmpty() || !hasSuper) {
-                for (BaseOptionModel option : options) {
-                    // type may contain generics so remove those
-                    String type = option.getJavaType();
-                    if (type.indexOf('<') != -1) {
-                        type = type.substring(0, type.indexOf('<'));
+                if (hasSuper) {
+                    w.write("        Map<String, Object> answer = super.getAllOptions(target);\n");
+                } else {
+                    w.write("        Map<String, Object> answer = new CaseInsensitiveMap();\n");
+                }
+                if (!options.isEmpty() || !hasSuper) {
+                    for (BaseOptionModel option : options) {
+                        // type may contain generics so remove those
+                        String type = option.getJavaType();
+                        if (type.indexOf('<') != -1) {
+                            type = type.substring(0, type.indexOf('<'));
+                        }
+                        type = type.replace('$', '.');
+                        w.write(String.format("        answer.put(\"%s\", %s.class);\n", option.getName(), type));
                     }
-                    type = type.replace('$', '.');
-                    w.write(String.format("        answer.put(\"%s\", %s.class);\n", option.getName(), type));
+                    w.write("        return answer;\n");
+                    w.write("    }\n");
                 }
-                w.write("        return answer;\n");
-                w.write("    }\n");
             }
 
             // generate API for getting a property
@@ -177,6 +194,52 @@ public final class PropertyConfigurerGenerator {
         w.write("\n");
     }
 
+    private static String generateAllOptions(boolean component, ComponentModel model) {
+        // use sorted set so the code is always generated the same way
+        Set<ComponentModel.ApiOptionModel> apis
+                = new TreeSet<>(Comparators.apiOptionModelComparator());
+        if (!component && model.isApi()) {
+            // gather all the option names from the api (they can be duplicated as the same name can be used by multiple methods)
+            model.getApiOptions().forEach(a -> a.getMethods().forEach(m -> apis.addAll(m.getOptions())));
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append("    static {\n");
+        sb.append("        Map<String, Object> map = new CaseInsensitiveMap();\n");
+        if (component) {
+            for (ComponentModel.ComponentOptionModel option : model.getComponentOptions()) {
+                // type may contain generics so remove those
+                String type = option.getJavaType();
+                if (type.indexOf('<') != -1) {
+                    type = type.substring(0, type.indexOf('<'));
+                }
+                type = type.replace('$', '.');
+                sb.append(String.format("        map.put(\"%s\", %s.class);\n", option.getName(), type));
+            }
+        } else {
+            for (ComponentModel.EndpointOptionModel option : model.getEndpointOptions()) {
+                // type may contain generics so remove those
+                String type = option.getJavaType();
+                if (type.indexOf('<') != -1) {
+                    type = type.substring(0, type.indexOf('<'));
+                }
+                type = type.replace('$', '.');
+                sb.append(String.format("        map.put(\"%s\", %s.class);\n", option.getName(), type));
+            }
+            for (ComponentModel.ApiOptionModel apiOption : apis) {
+                // type may contain generics so remove those
+                String type = apiOption.getJavaType();
+                if (type.indexOf('<') != -1) {
+                    type = type.substring(0, type.indexOf('<'));
+                }
+                type = type.replace('$', '.');
+                sb.append(String.format("        map.put(\"%s\", %s.class);\n", apiOption.getName(), type));
+            }
+        }
+        sb.append("        ALL_OPTIONS = map;\n");
+        sb.append("    }\n");
+        return sb.toString();
+    }
+
     private static Set<BaseOptionModel> findConfigurations(Collection<? extends BaseOptionModel> options) {
         final Set<String> found = new LinkedHashSet<>();
         final Set<BaseOptionModel> answer = new LinkedHashSet<>();