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/20 19:05:27 UTC

[camel] 07/12: CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.

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

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

commit 31cf888d5449a4cef0dbe1d31c9e6b3d8f4946ac
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 20 19:14:57 2019 +0200

    CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.
---
 .../apache/camel/component/as2/AS2Endpoint.java    |  4 ---
 .../camel/component/atmos/AtmosEndpoint.java       |  1 +
 .../apache/camel/support/IntrospectionSupport.java |  2 +-
 .../camel/support/PropertyBindingSupport.java      |  3 +-
 .../EndpointPropertyConfigurerSupport.java         | 10 +++++++
 .../apt/CoreEipAnnotationProcessorHelper.java      |  2 +-
 .../tools/apt/EndpointAnnotationProcessor.java     | 35 ++++++++--------------
 .../apt/EndpointPropertyConfigurerGenerator.java   | 21 +++++++++----
 .../tools/apt/SpringAnnotationProcessorHelper.java |  2 +-
 .../camel/tools/apt/helper/JsonSchemaHelper.java   | 13 ++++++--
 .../camel/tools/apt/model/EndpointOption.java      | 14 ++++++++-
 .../tools/apt/EndpointOptionComparatorTest.java    |  8 ++---
 12 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
index 5a9a8a7..40b39d3 100644
--- a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
+++ b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
@@ -67,10 +67,6 @@ public class AS2Endpoint extends AbstractApiEndpoint<AS2ApiName, AS2Configuratio
         this.configuration = endpointConfiguration;
     }
 
-    public AS2Configuration getAs2Configuration() {
-        return configuration;
-    }
-
     public AS2ClientConnection getAS2ClientConnection() {
         return as2ClientConnection;
     }
diff --git a/components/camel-atmos/src/main/java/org/apache/camel/component/atmos/AtmosEndpoint.java b/components/camel-atmos/src/main/java/org/apache/camel/component/atmos/AtmosEndpoint.java
index c0b7a32..c5b12c1 100644
--- a/components/camel-atmos/src/main/java/org/apache/camel/component/atmos/AtmosEndpoint.java
+++ b/components/camel-atmos/src/main/java/org/apache/camel/component/atmos/AtmosEndpoint.java
@@ -27,6 +27,7 @@ import org.apache.camel.component.atmos.integration.producer.AtmosMoveProducer;
 import org.apache.camel.component.atmos.integration.producer.AtmosPutProducer;
 import org.apache.camel.component.atmos.util.AtmosException;
 import org.apache.camel.component.atmos.util.AtmosOperation;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.support.DefaultEndpoint;
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
index e742c0e..fe0dd72 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
@@ -714,7 +714,7 @@ public final class IntrospectionSupport {
                     } else {
                         // We need to convert it
                         // special for boolean values with string values as we only want to accept "true" or "false"
-                        if (parameterType == Boolean.class || parameterType == boolean.class && ref instanceof String) {
+                        if ((parameterType == Boolean.class || parameterType == boolean.class) && ref instanceof String) {
                             String val = (String) ref;
                             if (!val.equalsIgnoreCase("true") && !val.equalsIgnoreCase("false")) {
                                 throw new IllegalArgumentException("Cannot convert the String value: " + ref + " to type: " + parameterType
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
index a7a8c79..9e328f4 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
@@ -458,7 +458,7 @@ public final class PropertyBindingSupport {
         org.apache.camel.util.ObjectHelper.notNull(properties, "properties");
         boolean rc = false;
 
-        // TODO: quick and dirty to only use configurer
+        // if there is a property configurer then use it to set the properties
         if (configurer != null) {
             Map<String, Consumer<Object>> writeProperties = configurer.getWritePropertyPlaceholderOptions(camelContext);
             for (Iterator<Map.Entry<String, Object>> iter = properties.entrySet().iterator(); iter.hasNext();) {
@@ -466,7 +466,6 @@ public final class PropertyBindingSupport {
                 String key = entry.getKey();
                 Object value = entry.getValue();
                 if (writeProperties.containsKey(key)) {
-                    // TODO: that thing with boolean and from string value true|false (should be in EndpointPropertyConfigurerSupport)
                     writeProperties.get(key).accept(value);
                     if (removeParameter) {
                         iter.remove();
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/component/EndpointPropertyConfigurerSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/component/EndpointPropertyConfigurerSupport.java
index e9e9f6e..55a47e1 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/component/EndpointPropertyConfigurerSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/component/EndpointPropertyConfigurerSupport.java
@@ -35,6 +35,16 @@ public abstract class EndpointPropertyConfigurerSupport implements EndpointPrope
                 }
             }
         }
+
+        // special for boolean values with string values as we only want to accept "true" or "false"
+        if ((type == Boolean.class || type == boolean.class) && value instanceof String) {
+            String text = (String) value;
+            if (!text.equalsIgnoreCase("true") && !text.equalsIgnoreCase("false")) {
+                throw new IllegalArgumentException("Cannot convert the String value: " + value + " to type: " + type
+                        + " as the value is not true or false");
+            }
+        }
+
         return camelContext.getTypeConverter().convertTo(type, value);
     }
 
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessorHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessorHelper.java
index f003530..06b2d79 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessorHelper.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessorHelper.java
@@ -245,7 +245,7 @@ public class CoreEipAnnotationProcessorHelper {
             doc = sanitizeDescription(doc, false);
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), entry.getKind(), entry.isRequired(), entry.getType(), entry.getDefaultValue(), doc,
                                                   entry.isDeprecated(), entry.getDeprecationNote(), false, null, null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(),
-                                                  entry.getOneOfTypes(), entry.isAsPredicate(), null, null, false));
+                                                  entry.getOneOfTypes(), entry.isAsPredicate(), null, null, false, null, null));
         }
         buffer.append("\n  }");
 
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 0e9bccb..fc6f99b 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
@@ -168,7 +168,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
             findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "", parentData);
         }
 
-        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "", uriEndpoint.excludeProperties(), parentData);
+        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "", uriEndpoint.excludeProperties(), parentData, null, null);
 
         String json = createParameterJsonSchema(componentModel, componentOptions, endpointPaths, endpointOptions, schemes, parentData);
         writer.println(json);
@@ -268,7 +268,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));
+                false, null, asPredicate, optionalPrefix, prefix, multiValue, null, null));
 
             parentComponentProperties.remove(entry.getName());
         }
@@ -342,7 +342,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "path", 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));
+                false, null, asPredicate, optionalPrefix, prefix, multiValue, null, null));
 
             parentProperties.remove(entry.getName());
         }
@@ -390,7 +390,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "parameter", 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));
+                false, null, asPredicate, optionalPrefix, prefix, multiValue, entry.getNestedTypeName(), entry.getNestedFieldName()));
 
             parentProperties.remove(entry.getName());
         }
@@ -629,7 +629,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
     protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel,
                                        Set<EndpointPath> endpointPaths, Set<EndpointOption> endpointOptions,
                                        TypeElement classElement, String prefix, String excludeProperties,
-                                       Map<String, Object> parentData) {
+                                       Map<String, Object> parentData, String nestedTypeName, String nestedFieldName) {
         Elements elementUtils = processingEnv.getElementUtils();
         while (true) {
             List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
@@ -765,7 +765,11 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
                         if (!isNullOrEmpty(extraPrefix)) {
                             nestedPrefix += extraPrefix;
                         }
-                        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, fieldTypeElement, nestedPrefix, excludeProperties, null);
+                        nestedTypeName = fieldTypeName;
+                        nestedFieldName = fieldElement.getSimpleName().toString();
+                        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, fieldTypeElement, nestedPrefix, excludeProperties, null, nestedTypeName, nestedFieldName);
+                        nestedTypeName = null;
+                        nestedFieldName = null;
                     } else {
                         String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, false);
                         if (isNullOrEmpty(docComment)) {
@@ -810,7 +814,8 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
                         boolean isSecret = secret != null && secret || param.secret();
                         String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                         EndpointOption option = new EndpointOption(name, displayName, fieldTypeName, required, defaultValue, defaultValueNote,
-                                docComment.trim(), paramOptionalPrefix, paramPrefix, multiValue, deprecated, deprecationNote, isSecret, group, label, isEnum, enums);
+                                docComment.trim(), paramOptionalPrefix, paramPrefix, multiValue, deprecated, deprecationNote, isSecret, group, label,
+                                isEnum, enums, nestedTypeName, nestedFieldName);
                         endpointOptions.add(option);
                     }
                 }
@@ -843,22 +848,6 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
         return false;
     }
 
-    private static Map<String, String> parseAsMap(String data) {
-        Map<String, String> answer = new HashMap<>();
-        String[] lines = data.split("\n");
-        for (String line : lines) {
-            if (!line.isEmpty()) {
-                int idx = line.indexOf('=');
-                String key = line.substring(0, idx);
-                String value = line.substring(idx + 1);
-                // remove ending line break for the values
-                value = value.trim().replaceAll("\n", "");
-                answer.put(key.trim(), value);
-            }
-        }
-        return answer;
-    }
-
     private static boolean secureAlias(String scheme, String alias) {
         if (scheme.equals(alias)) {
             return false;
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java
index 0d969d5..c46c178 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java
@@ -78,8 +78,8 @@ public final class EndpointPropertyConfigurerGenerator {
             for (EndpointOption option : options) {
                 String getOrSet = option.getName();
                 getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1);
-                String getterLambda = getterLambda(getOrSet, option.getName(), option.getType());
-                String setterLambda = setterLambda(getOrSet, option.getName(), option.getType());
+                String getterLambda = getterLambda(getOrSet, option.getName(), option.getType(), option.getNestedFieldName());
+                String setterLambda = setterLambda(getOrSet, option.getName(), option.getType(), option.getNestedFieldName());
                 w.write("        readPlaceholders.put(\"" + option.getName() + "\", " + getterLambda + ");\n");
                 w.write("        writePlaceholders.put(\"" + option.getName() + "\", " + setterLambda + ");\n");
             }
@@ -106,19 +106,28 @@ public final class EndpointPropertyConfigurerGenerator {
         }
     }
 
-    private static String getterLambda(String getOrSet, String name, String type) {
+    private static String getterLambda(String getOrSet, String name, String type, String nestedFieldName) {
+        String nested = "";
+        if (nestedFieldName != null) {
+            nested = "get" + Character.toUpperCase(nestedFieldName.charAt(0)) + nestedFieldName.substring(1) + "().";
+        }
         String getPrefix = "boolean".equals(type) ? "is" : "get";
-        return "endpoint::" + getPrefix + getOrSet;
+        return "() -> endpoint." + nested + "" + getPrefix + getOrSet + "()";
     }
 
-    private static String setterLambda(String getOrSet, String name, String type) {
+    private static String setterLambda(String getOrSet, String name, String type, String nestedFieldName) {
         // type may contain generics so remove those
         if (type.indexOf('<') != -1) {
             type = type.substring(0, type.indexOf('<'));
         }
+        if (nestedFieldName != null) {
+            getOrSet = "get" + Character.toUpperCase(nestedFieldName.charAt(0)) + nestedFieldName.substring(1) + "().set" + getOrSet;
+        } else {
+            getOrSet = "set" + getOrSet;
+        }
 
         StringBuilder sb = new StringBuilder();
-        sb.append("o -> endpoint.set").append(getOrSet).append("(property(camelContext, ").append(type).append(".class, o))");
+        sb.append("o -> endpoint.").append(getOrSet).append("(property(camelContext, ").append(type).append(".class, o))");
         return sb.toString();
     }
 
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/SpringAnnotationProcessorHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/SpringAnnotationProcessorHelper.java
index 3706c68..fff0004 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/SpringAnnotationProcessorHelper.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/SpringAnnotationProcessorHelper.java
@@ -139,7 +139,7 @@ public class SpringAnnotationProcessorHelper {
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), entry.getKind(), entry.isRequired(), entry.getType(), entry.getDefaultValue(), doc,
                                                   entry.isDeprecated(), entry.getDeprecationNote(), false, null, null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(),
-                                                  entry.getOneOfTypes(), entry.isAsPredicate(), null, null, false));
+                                                  entry.getOneOfTypes(), entry.isAsPredicate(), null, null, false, null, null));
         }
         buffer.append("\n  }");
 
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 f2c7ef2..3f6822b 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
@@ -42,7 +42,8 @@ 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) {
+                                boolean oneOfType, Set<String> oneOffTypes, boolean asPredicate, String optionalPrefix, String prefix, boolean multiValue,
+                                String nestedTypeName, String nestedFieldName) {
         String typeName = JsonSchemaHelper.getType(type, enumType);
 
         StringBuilder sb = new StringBuilder();
@@ -153,6 +154,15 @@ public final class JsonSchemaHelper {
             }
         }
 
+        if (!Strings.isNullOrEmpty(nestedTypeName)) {
+            sb.append(", \"nestedTypeName\": ");
+            sb.append(Strings.doubleQuote(nestedTypeName));
+        }
+        if (!Strings.isNullOrEmpty(nestedFieldName)) {
+            sb.append(", \"nestedFieldName\": ");
+            sb.append(Strings.doubleQuote(nestedFieldName));
+        }
+
         if (!Strings.isNullOrEmpty(description)) {
             sb.append(", \"description\": ");
             String text = sanitizeDescription(description, false);
@@ -202,7 +212,6 @@ public final class JsonSchemaHelper {
      * @return  the json schema primitive type, or <tt>null</tt> if not a primitive
      */
     public static String getPrimitiveType(String name) {
-
         // special for byte[] or Object[] as its common to use
         if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
             return "string";
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java
index 3bffc22..c8e6113 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java
@@ -39,11 +39,13 @@ public final class EndpointOption {
     private String label;
     private boolean enumType;
     private Set<String> enums;
+    private String nestedTypeName;
+    private String nestedFieldName;
 
     public EndpointOption(String name, String displayName, String type, boolean required, String defaultValue, String defaultValueNote,
                           String documentation, String optionalPrefix, String prefix, boolean multiValue,
                           boolean deprecated, String deprecationNote, boolean secret, String group, String label,
-                          boolean enumType, Set<String> enums) {
+                          boolean enumType, Set<String> enums, String nestedTypeName, String nestedFieldName) {
         this.name = name;
         this.displayName = displayName;
         this.type = type;
@@ -61,6 +63,8 @@ public final class EndpointOption {
         this.label = label;
         this.enumType = enumType;
         this.enums = enums;
+        this.nestedTypeName = nestedTypeName;
+        this.nestedFieldName = nestedFieldName;
     }
 
     public String getName() {
@@ -133,6 +137,14 @@ public final class EndpointOption {
         return enums;
     }
 
+    public String getNestedTypeName() {
+        return nestedTypeName;
+    }
+
+    public String getNestedFieldName() {
+        return nestedFieldName;
+    }
+
     public String getGroup() {
         return group;
     }
diff --git a/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java b/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java
index 13f43aa..adcf03b 100644
--- a/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java
+++ b/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java
@@ -40,13 +40,13 @@ public class EndpointOptionComparatorTest {
         String group4 = EndpointHelper.labelAsGroupName(label4, false, false);
 
         EndpointOption op1 = new EndpointOption("first", "First", "string", true, "", "", "blah", null, null, false,
-            false, null, false, group1, label1, false, null);
+            false, null, false, group1, label1, false, null, null, null);
         EndpointOption op2 = new EndpointOption("synchronous", "Synchronous", "string", true, "", "", "blah", null, null, false,
-            false, null, false, group2, label2, false, null);
+            false, null, false, group2, label2, false, null, null, null);
         EndpointOption op3 = new EndpointOption("second", "Second", "string", true, "", "", "blah", null, null, false,
-            false, null, false, group3, label3, false, null);
+            false, null, false, group3, label3, false, null, null, null);
         EndpointOption op4 = new EndpointOption("country", "Country", "string", true, "", "", "blah", null, null, false,
-            false, null, false, group4, label4, false, null);
+            false, null, false, group4, label4, false, null, null, null);
 
         List<EndpointOption> list = new ArrayList<>();
         list.add(op1);