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/13 06:25:02 UTC

[camel] branch CAMEL-13850 created (now bf0fbee)

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

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


      at bf0fbee  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

This branch includes the following new commits:

     new b7071c8  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new 568a2d6  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new 3ed3172  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new 54a77dc  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new dd6f554  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new 758ff0b  Regen
     new 34f2b3d  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new 94564a5  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
     new bf0fbee  CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[camel] 04/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 54a77dc1196b74f2b97e8d9b93e740baaf1a1473
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 12 22:08:43 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../model/DefinitionPropertiesProviderHelper.java  | 47 -------------
 .../DefinitionPropertyPlaceholderConfigurable.java |  5 +-
 .../apt/CoreEipAnnotationProcessorHelper.java      | 77 +++++++++++++++++++---
 .../camel/tools/apt/ModelAnnotationProcessor.java  | 62 +++++++++++++----
 .../tools/apt/SpringAnnotationProcessorHelper.java |  3 +-
 5 files changed, 122 insertions(+), 72 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
deleted file mode 100644
index 86cb92e..0000000
--- a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.model;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-
-import org.apache.camel.model.placeholder.FromDefinitionPropertyPlaceholderProvider;
-import org.apache.camel.model.placeholder.LogDefinitionPropertyPlaceholderProvider;
-import org.apache.camel.model.placeholder.ToDefinitionPropertyPlaceholderProvider;
-
-public class DefinitionPropertiesProviderHelper {
-
-    private static final Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> MAP;
-    static {
-        Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> map = new HashMap<>();
-        map.put(FromDefinition.class, FromDefinitionPropertyPlaceholderProvider::new);
-        map.put(LogDefinition.class, LogDefinitionPropertyPlaceholderProvider::new);
-        map.put(ToDefinition.class, ToDefinitionPropertyPlaceholderProvider::new);
-        MAP = map;
-    }
-
-    public static Optional<DefinitionPropertyPlaceholderConfigurable> provider(Object definition) {
-        Function<Object, DefinitionPropertyPlaceholderConfigurable> func = MAP.get(definition.getClass());
-        if (func != null) {
-            return Optional.of(func.apply(definition));
-        }
-        return Optional.empty();
-    }
-
-}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
index 9c82f6b..8d5758c 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
@@ -21,6 +21,7 @@ import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.model.placeholder.DefinitionPropertiesPlaceholderProviderHelper;
 
 /**
  * To be used for configuring property placeholder options on the EIP models.
@@ -34,7 +35,7 @@ public interface DefinitionPropertyPlaceholderConfigurable {
      * @return key/values of options
      */
     default Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        DefinitionPropertyPlaceholderConfigurable aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
+        DefinitionPropertyPlaceholderConfigurable aware = DefinitionPropertiesPlaceholderProviderHelper.provider(this).orElse(null);
         return aware != null ? aware.getReadPropertyPlaceholderOptions(camelContext) : null;
     }
 
@@ -43,7 +44,7 @@ public interface DefinitionPropertyPlaceholderConfigurable {
      * This will be all the string based options.
      */
     default Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        DefinitionPropertyPlaceholderConfigurable aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
+        DefinitionPropertyPlaceholderConfigurable aware = DefinitionPropertiesPlaceholderProviderHelper.provider(this).orElse(null);
         return aware != null ? aware.getWritePropertyPlaceholderOptions(camelContext) : null;
     }
 
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 edb48d7..fc00956 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
@@ -18,13 +18,13 @@ package org.apache.camel.tools.apt;
 
 import java.io.PrintWriter;
 import java.io.Writer;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 import javax.annotation.processing.ProcessingEnvironment;
@@ -92,7 +92,8 @@ public class CoreEipAnnotationProcessorHelper {
 
     private boolean skipUnwanted = true;
 
-    protected void processModelClass(final ProcessingEnvironment processingEnv, final RoundEnvironment roundEnv, final TypeElement classElement) {
+    protected void processModelClass(final ProcessingEnvironment processingEnv, final RoundEnvironment roundEnv,
+                                     final TypeElement classElement, Set<String> propertyPlaceholderDefinitions, final boolean last) {
         final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
         String packageName = javaTypeName.substring(0, javaTypeName.lastIndexOf("."));
 
@@ -128,13 +129,20 @@ public class CoreEipAnnotationProcessorHelper {
             fileName = name + ".json";
         }
 
-        // write json schema
-        processFile(processingEnv, packageName, fileName, writer -> writeJSonSchemeDocumentation(processingEnv, writer, roundEnv, classElement, rootElement, javaTypeName, name));
-    }
+        // write json schema and property placeholder provider
+        processFile(processingEnv, packageName, fileName, writer -> writeJSonSchemeDocumentation(processingEnv, writer,
+                roundEnv, classElement, rootElement, javaTypeName, name, propertyPlaceholderDefinitions));
 
+        // if last then generate
+        if (last) {
+            // lets sort themfirst
+            writePropertyPlaceholderDefinitionsHelper(processingEnv, roundEnv, propertyPlaceholderDefinitions);
+        }
+    }
 
+    // TODO: rename this 
     protected void writeJSonSchemeDocumentation(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
-                                                XmlRootElement rootElement, String javaTypeName, String modelName) {
+                                                XmlRootElement rootElement, String javaTypeName, String modelName, Set<String> propertyPlaceholderDefinitions) {
         // gather eip information
         EipModel eipModel = findEipModelProperties(processingEnv, roundEnv, classElement, javaTypeName, modelName);
 
@@ -152,11 +160,11 @@ public class CoreEipAnnotationProcessorHelper {
         writer.println(json);
 
         // write property placeholder source code
-        writePropertyPlaceholderProviderSource(processingEnv, writer, roundEnv, classElement, eipModel, eipOptions);
+        writePropertyPlaceholderProviderSource(processingEnv, writer, roundEnv, classElement, eipModel, eipOptions, propertyPlaceholderDefinitions);
     }
 
     protected void writePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
-                                                          EipModel eipModel, Set<EipOption> options) {
+                                                          EipModel eipModel, Set<EipOption> options, Set<String> propertyPlaceholderDefinitions) {
 
         // the following are valid class elements which we want to generate
         boolean rest = classElement.getQualifiedName().toString().startsWith("org.apache.camel.model.rest");
@@ -175,6 +183,7 @@ public class CoreEipAnnotationProcessorHelper {
         String fqn = "org.apache.camel.model.placeholder." + cn;
 
         doWritePropertyPlaceholderProviderSource(processingEnv, parent, def, fqnDef, cn, fqn, options);
+        propertyPlaceholderDefinitions.add(fqnDef);
 
         // we also need to generate from when we generate route as from can also configure property placeholders
         if ("RouteDefinition".equals(def)) {
@@ -188,6 +197,7 @@ public class CoreEipAnnotationProcessorHelper {
             options.add(new EipOption("uri", null, null, "java.lang.String", false, null, null, false, null, false, null, false, null, false));
 
             doWritePropertyPlaceholderProviderSource(processingEnv, parent, def, fqnDef, cn, fqn, options);
+            propertyPlaceholderDefinitions.add(fqnDef);
         }
     }
 
@@ -301,6 +311,57 @@ public class CoreEipAnnotationProcessorHelper {
         return option.getName();
     }
 
+    private void writePropertyPlaceholderDefinitionsHelper(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv,
+                                                           Set<String> propertyPlaceholderDefinitions) {
+        Writer w = null;
+        try {
+            JavaFileObject src = processingEnv.getFiler().createSourceFile("org.apache.camel.model.placeholder.DefinitionPropertiesPlaceholderProviderHelper");
+            w = src.openWriter();
+
+            w.write("/* Generated by camel-apt */\n");
+            w.write("package org.apache.camel.model.placeholder;\n");
+            w.write("\n");
+            w.write("import java.util.HashMap;\n");
+            w.write("import java.util.Map;\n");
+            w.write("import java.util.Optional;\n");
+            w.write("import java.util.function.Function;\n");
+            w.write("import java.util.function.Supplier;\n");
+            w.write("\n");
+            w.write("import org.apache.camel.model.DefinitionPropertyPlaceholderConfigurable;\n");
+            for (String def : propertyPlaceholderDefinitions) {
+                w.write("import " + def + ";\n");
+            }
+            w.write("\n");
+            w.write("public class DefinitionPropertiesPlaceholderProviderHelper {\n");
+            w.write("\n");
+            w.write("    private static final Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> MAP;\n");
+            w.write("    static {\n");
+            w.write("        Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> map = new HashMap<>();\n");
+            for (String def : propertyPlaceholderDefinitions) {
+                String cn = def.substring(def.lastIndexOf('.') + 1);
+                w.write("        map.put(" + cn + ".class, " + cn + "PropertyPlaceholderProvider::new);\n");
+            }
+            w.write("        MAP = map;\n");
+            w.write("    }\n");
+            w.write("\n");
+            w.write("    public static Optional<DefinitionPropertyPlaceholderConfigurable> provider(Object definition) {\n");
+            w.write("        Function<Object, DefinitionPropertyPlaceholderConfigurable> func = MAP.get(definition.getClass());\n");
+            w.write("        if (func != null) {\n");
+            w.write("            return Optional.of(func.apply(definition));\n");
+            w.write("        }\n");
+            w.write("        return Optional.empty();\n");
+            w.write("    }\n");
+            w.write("\n");
+            w.write("}\n");
+            w.write("\n");
+        } catch (Exception e) {
+            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to process annotated elements in " + getClass().getSimpleName() + ": " + e.getMessage());
+            dumpExceptionToErrorFile("camel-apt-error.log", "Error processing annotation in " + getClass().getSimpleName(), e);
+        } finally {
+            IOHelper.close(w);
+        }
+    }
+
     public String createParameterJsonSchema(EipModel eipModel, Set<EipOption> options) {
         StringBuilder buffer = new StringBuilder("{");
         // eip model
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelAnnotationProcessor.java
index 211f42b..5d1e380 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelAnnotationProcessor.java
@@ -16,8 +16,13 @@
  */
 package org.apache.camel.tools.apt;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
-
+import java.util.TreeSet;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 import javax.annotation.processing.RoundEnvironment;
 import javax.annotation.processing.SupportedAnnotationTypes;
 import javax.lang.model.element.Element;
@@ -38,19 +43,48 @@ public class ModelAnnotationProcessor extends AbstractCamelAnnotationProcessor {
     @Override
     protected void doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception {
         Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(XmlRootElement.class);
-        for (Element element : elements) {
-            if (element instanceof TypeElement) {
-                TypeElement classElement = (TypeElement) element;
-
-                final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
-                boolean core = javaTypeName.startsWith("org.apache.camel.model");
-                boolean spring = javaTypeName.startsWith("org.apache.camel.spring") || javaTypeName.startsWith("org.apache.camel.core.xml");
-                if (core) {
-                    coreProcessor.processModelClass(processingEnv, roundEnv, classElement);
-                } else if (spring) {
-                    springProcessor.processModelClass(processingEnv, roundEnv, classElement);
-                }
-            }
+
+        Set<? extends Element> coreElements = elements.stream()
+                .filter(new Predicate<Element>() {
+                    @Override
+                    public boolean test(Element element) {
+                        if (element instanceof TypeElement) {
+                            TypeElement classElement = (TypeElement) element;
+
+                            final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
+                            return javaTypeName.startsWith("org.apache.camel.model");
+                        }
+                        return false;
+                    }
+                }).collect(Collectors.toSet());
+
+        Set<? extends Element> springElements = elements.stream()
+                .filter(new Predicate<Element>() {
+                    @Override
+                    public boolean test(Element element) {
+                        if (element instanceof TypeElement) {
+                            TypeElement classElement = (TypeElement) element;
+
+                            final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
+                            return javaTypeName.startsWith("org.apache.camel.spring") || javaTypeName.startsWith("org.apache.camel.core.xml");
+                        }
+                        return false;
+                    }
+                }).collect(Collectors.toSet());
+
+        // we want them to be sorted
+        Set<String> propertyPlaceholderDefinitions = new TreeSet<>(String::compareToIgnoreCase);
+
+        Iterator it = coreElements.iterator();
+        while (it.hasNext()) {
+            TypeElement classElement = (TypeElement) it.next();
+            coreProcessor.processModelClass(processingEnv, roundEnv, classElement, propertyPlaceholderDefinitions, !it.hasNext());
+        }
+
+        it = springElements.iterator();
+        while (it.hasNext()) {
+            TypeElement classElement = (TypeElement) it.next();
+            springProcessor.processModelClass(processingEnv, roundEnv, classElement, !it.hasNext());
         }
     }
 
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 2300352..75f3110 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
@@ -56,7 +56,8 @@ import static org.apache.camel.tools.apt.helper.Strings.safeNull;
  */
 public class SpringAnnotationProcessorHelper {
 
-    protected void processModelClass(final ProcessingEnvironment processingEnv, final RoundEnvironment roundEnv, final TypeElement classElement) {
+    protected void processModelClass(final ProcessingEnvironment processingEnv, final RoundEnvironment roundEnv,
+                                     final TypeElement classElement, final boolean last) {
         final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
         String packageName = javaTypeName.substring(0, javaTypeName.lastIndexOf("."));
 


[camel] 02/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 568a2d60a7ebcaab689d83aa52486a474d45b0ea
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 12 15:02:46 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../model/DefinitionPropertiesProviderHelper.java  | 43 +++++++++++++++++
 .../org/apache/camel/model/FromDefinition.java     | 18 +------
 .../model/FromDefinitionPropertiesProvider.java    | 50 +++++++++++++++++++
 .../java/org/apache/camel/model/LogDefinition.java | 29 +----------
 .../model/LogDefinitionPropertiesProvider.java     | 56 ++++++++++++++++++++++
 .../camel/model/OptionalIdentifiedDefinition.java  |  2 +-
 .../camel/model/ProcessorDefinitionHelper.java     |  1 +
 .../camel/model/PropertyPlaceholderAware.java      | 12 ++++-
 ...re.java => ToDefinitionPropertiesProvider.java} | 34 ++++++++-----
 9 files changed, 186 insertions(+), 59 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
new file mode 100644
index 0000000..7da3ffd
--- /dev/null
+++ b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
@@ -0,0 +1,43 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.model;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+public class DefinitionPropertiesProviderHelper {
+
+    private static final Map<Class, Function<Object, PropertyPlaceholderAware>> MAP;
+    static {
+        Map<Class, Function<Object, PropertyPlaceholderAware>> map = new HashMap<>();
+        map.put(FromDefinition.class, FromDefinitionPropertiesProvider::new);
+        map.put(LogDefinition.class, LogDefinitionPropertiesProvider::new);
+        map.put(ToDefinition.class, ToDefinitionPropertiesProvider::new);
+        MAP = map;
+    }
+
+    public static Optional<PropertyPlaceholderAware> provider(Object definition) {
+        Function<Object, PropertyPlaceholderAware> func = MAP.get(definition.getClass());
+        if (func != null) {
+            return Optional.of(func.apply(definition));
+        }
+        return Optional.empty();
+    }
+
+}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java
index 6d61c6d..fb4d762 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java
@@ -37,7 +37,7 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "eip,endpoint,routing")
 @XmlRootElement(name = "from")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition> implements PropertyPlaceholderAware, EndpointRequiredDefinition {
+public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition> implements EndpointRequiredDefinition {
     @XmlAttribute @Metadata(required = true)
     private String uri;
     @XmlTransient
@@ -45,14 +45,7 @@ public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition>
     @XmlTransient
     private EndpointConsumerBuilder endpointConsumerBuilder;
 
-    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
-    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
-
     public FromDefinition() {
-        readPlaceholders.put("id", this::getId);
-        readPlaceholders.put("uri", this::getUri);
-        writePlaceholders.put("id", this::setId);
-        writePlaceholders.put("uri", this::setUri);
     }
 
     public FromDefinition(String uri) {
@@ -150,13 +143,4 @@ public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition>
         this.uri = null;
     }
 
-    @Override
-    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        return readPlaceholders;
-    }
-
-    @Override
-    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        return writePlaceholders;
-    }
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinitionPropertiesProvider.java b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinitionPropertiesProvider.java
new file mode 100644
index 0000000..5953f84
--- /dev/null
+++ b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinitionPropertiesProvider.java
@@ -0,0 +1,50 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.model;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.apache.camel.CamelContext;
+
+public class FromDefinitionPropertiesProvider implements PropertyPlaceholderAware {
+
+    private final FromDefinition definition;
+    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
+    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
+
+    public FromDefinitionPropertiesProvider(Object obj) {
+        this.definition = (FromDefinition) obj;
+
+        readPlaceholders.put("id", definition::getId);
+        readPlaceholders.put("uri", definition::getUri);
+        writePlaceholders.put("id", definition::setId);
+        writePlaceholders.put("uri", definition::setUri);
+    }
+
+    @Override
+    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
+        return readPlaceholders;
+    }
+
+    @Override
+    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        return writePlaceholders;
+    }
+}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
index 62281e5..fb84545 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
@@ -16,17 +16,12 @@
  */
 package org.apache.camel.model;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
-import org.apache.camel.CamelContext;
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.spi.Metadata;
 import org.slf4j.Logger;
@@ -37,7 +32,7 @@ import org.slf4j.Logger;
 @Metadata(label = "eip,configuration")
 @XmlRootElement(name = "log")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class LogDefinition extends NoOutputDefinition<LogDefinition> implements PropertyPlaceholderAware {
+public class LogDefinition extends NoOutputDefinition<LogDefinition> {
 
     @XmlAttribute(required = true)
     private String message;
@@ -52,20 +47,7 @@ public class LogDefinition extends NoOutputDefinition<LogDefinition> implements
     @XmlTransient
     private Logger logger;
 
-    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
-    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
-
     public LogDefinition() {
-        readPlaceholders.put("id", this::getId);
-        readPlaceholders.put("message", this::getMessage);
-        readPlaceholders.put("logName", this::getLogName);
-        readPlaceholders.put("marker", this::getMarker);
-        readPlaceholders.put("loggerRef", this::getLoggerRef);
-        writePlaceholders.put("id", this::setId);
-        writePlaceholders.put("message", this::setMessage);
-        writePlaceholders.put("logName", this::setLogName);
-        writePlaceholders.put("marker", this::setMarker);
-        writePlaceholders.put("loggerRef", this::setLoggerRef);
     }
 
     public LogDefinition(String message) {
@@ -156,13 +138,4 @@ public class LogDefinition extends NoOutputDefinition<LogDefinition> implements
         this.logger = logger;
     }
 
-    @Override
-    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        return readPlaceholders;
-    }
-
-    @Override
-    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        return writePlaceholders;
-    }
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinitionPropertiesProvider.java b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinitionPropertiesProvider.java
new file mode 100644
index 0000000..a60ffa8
--- /dev/null
+++ b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinitionPropertiesProvider.java
@@ -0,0 +1,56 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.model;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.apache.camel.CamelContext;
+
+public class LogDefinitionPropertiesProvider implements PropertyPlaceholderAware {
+
+    private final LogDefinition definition;
+    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
+    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
+
+    public LogDefinitionPropertiesProvider(Object obj) {
+        this.definition = (LogDefinition) obj;
+
+        readPlaceholders.put("id", definition::getId);
+        readPlaceholders.put("message", definition::getMessage);
+        readPlaceholders.put("logName", definition::getLogName);
+        readPlaceholders.put("marker", definition::getMarker);
+        readPlaceholders.put("loggerRef", definition::getLoggerRef);
+        writePlaceholders.put("id", definition::setId);
+        writePlaceholders.put("message", definition::setMessage);
+        writePlaceholders.put("logName", definition::setLogName);
+        writePlaceholders.put("marker", definition::setMarker);
+        writePlaceholders.put("loggerRef", definition::setLoggerRef);
+    }
+
+    @Override
+    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
+        return readPlaceholders;
+    }
+
+    @Override
+    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        return writePlaceholders;
+    }
+}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java
index dd0c216..5f520f5 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java
@@ -31,7 +31,7 @@ import org.apache.camel.spi.NodeIdFactory;
 @XmlType(name = "optionalIdentifiedDefinition")
 @XmlAccessorType(XmlAccessType.PROPERTY)
 // must use XmlAccessType.PROPERTY which is required by camel-spring / camel-blueprint for their namespace parsers
-public abstract class OptionalIdentifiedDefinition<T extends OptionalIdentifiedDefinition<T>> implements NamedNode {
+public abstract class OptionalIdentifiedDefinition<T extends OptionalIdentifiedDefinition<T>> implements NamedNode, PropertyPlaceholderAware {
 
     private String id;
     private Boolean customId;
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
index 280965b..ff809f6 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
@@ -721,6 +721,7 @@ public final class ProcessorDefinitionHelper {
             if (LOG.isTraceEnabled()) {
                 LOG.trace("There are {} properties on: {}", readProperties.size(), definition);
             }
+
             // lookup and resolve properties for String based properties
             for (Map.Entry<String, Supplier<String>> entry : readProperties.entrySet()) {
                 String name = entry.getKey();
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java b/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
index 9bc6b4a..c4fb8b7 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
@@ -22,6 +22,7 @@ import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
 
+// TODO: Rename interface
 public interface PropertyPlaceholderAware {
 
     /**
@@ -29,10 +30,17 @@ public interface PropertyPlaceholderAware {
      *
      * @return key/values of options
      */
-    Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext);
+    default Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
+        PropertyPlaceholderAware aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
+        return aware != null ? aware.getReadPropertyPlaceholderOptions(camelContext) : null;
+    }
 
     /**
      * To update an existing property using the function with the ket/value and returning the changed value
      */
-    Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext);
+    default Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        PropertyPlaceholderAware aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
+        return aware != null ? aware.getWritePropertyPlaceholderOptions(camelContext) : null;
+    }
+
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinitionPropertiesProvider.java
similarity index 50%
copy from core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
copy to core/camel-core/src/main/java/org/apache/camel/model/ToDefinitionPropertiesProvider.java
index 9bc6b4a..e0e64a5 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinitionPropertiesProvider.java
@@ -16,23 +16,35 @@
  */
 package org.apache.camel.model;
 
+import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
 
-public interface PropertyPlaceholderAware {
+public class ToDefinitionPropertiesProvider implements PropertyPlaceholderAware {
 
-    /**
-     * Gets the options on the model definition which supports property placeholders and can be resolved.
-     *
-     * @return key/values of options
-     */
-    Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext);
+    private final ToDefinition definition;
+    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
+    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
 
-    /**
-     * To update an existing property using the function with the ket/value and returning the changed value
-     */
-    Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext);
+    public ToDefinitionPropertiesProvider(Object obj) {
+        this.definition = (ToDefinition) obj;
+
+        readPlaceholders.put("id", definition::getId);
+        readPlaceholders.put("uri", definition::getUri);
+        writePlaceholders.put("id", definition::setId);
+        writePlaceholders.put("uri", definition::setUri);
+    }
+
+    @Override
+    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
+        return readPlaceholders;
+    }
+
+    @Override
+    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        return writePlaceholders;
+    }
 }


[camel] 05/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit dd6f55404c9a92e0157bfde363dde2f93ea24ff5
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 12 22:31:52 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../apache/camel/model/DataFormatDefinition.java   |  2 +-
 .../camel/model/ProcessorDefinitionHelper.java     |  6 ++-
 .../java/org/apache/camel/model/ToDefinition.java  | 51 +---------------------
 .../camel/model/language/ExpressionDefinition.java |  3 +-
 4 files changed, 8 insertions(+), 54 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/DataFormatDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/DataFormatDefinition.java
index c7f3452..f36fb68 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/DataFormatDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/DataFormatDefinition.java
@@ -35,7 +35,7 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "dataformat,transformation")
 @XmlType(name = "dataFormat")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class DataFormatDefinition extends IdentifiedType implements OtherAttributesAware {
+public class DataFormatDefinition extends IdentifiedType implements OtherAttributesAware, DefinitionPropertyPlaceholderConfigurable {
     @XmlTransient
     private DataFormat dataFormat;
     @XmlTransient
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
index b57f51a..169dc3d 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
@@ -626,7 +626,7 @@ public final class ProcessorDefinitionHelper {
     }
 
     private static void addRestoreAction(Map<String, Consumer<String>> writeProperties, final Map<String, String> properties) {
-        if (properties.isEmpty()) {
+        if (properties == null || properties.isEmpty()) {
             return;
         }
 
@@ -685,7 +685,7 @@ public final class ProcessorDefinitionHelper {
         Map<String, Supplier<String>> readProperties = ppa.getReadPropertyPlaceholderOptions(camelContext);
         Map<String, Consumer<String>> writeProperties = ppa.getWritePropertyPlaceholderOptions(camelContext);
 
-        if (!readProperties.isEmpty()) {
+        if (readProperties != null && !readProperties.isEmpty()) {
             if (LOG.isTraceEnabled()) {
                 LOG.trace("There are {} properties on: {}", readProperties.size(), definition);
             }
@@ -718,6 +718,8 @@ public final class ProcessorDefinitionHelper {
      */
     public static void resolveKnownConstantFields(CamelContext camelContext, Object definition) throws Exception {
         LOG.trace("Resolving known fields for: {}", definition);
+
+        // TODO: implement this
 /*
         // find all String getter/setter
         Map<String, Object> properties = new HashMap<>();
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
index 10b61d8..4204727 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
@@ -16,21 +16,15 @@
  */
 package org.apache.camel.model;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.builder.EndpointProducerBuilder;
 import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.PropertiesComponent;
 
 /**
  * Sends the message to a static endpoint
@@ -38,18 +32,11 @@ import org.apache.camel.spi.PropertiesComponent;
 @Metadata(label = "eip,endpoint,routing")
 @XmlRootElement(name = "to")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class ToDefinition extends SendDefinition<ToDefinition> implements DefinitionPropertyPlaceholderConfigurable {
+public class ToDefinition extends SendDefinition<ToDefinition> {
     @XmlAttribute
     private ExchangePattern pattern;
 
-    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
-    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
-
     public ToDefinition() {
-        readPlaceholders.put("id", this::getId);
-        readPlaceholders.put("uri", this::getUri);
-        writePlaceholders.put("id", this::setId);
-        writePlaceholders.put("uri", this::setUri);
     }
 
     public ToDefinition(String uri) {
@@ -104,41 +91,5 @@ public class ToDefinition extends SendDefinition<ToDefinition> implements Defini
         this.pattern = pattern;
     }
 
-    @Override
-    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(final CamelContext camelContext) {
-        if (getOtherAttributes() != null && !getOtherAttributes().isEmpty()) {
-            final Map<String, Supplier<String>> answer = new HashMap<>(readPlaceholders);
-            getOtherAttributes().forEach((k, v) -> {
-                if (Constants.PLACEHOLDER_QNAME.equals(k.getNamespaceURI())) {
-                    if (v instanceof String) {
-                        // enforce a properties component to be created if none existed
-                        camelContext.getPropertiesComponent(true);
-
-                        // value must be enclosed with placeholder tokens
-                        String s = (String) v;
-                        String prefixToken = PropertiesComponent.PREFIX_TOKEN;
-                        String suffixToken = PropertiesComponent.SUFFIX_TOKEN;
-
-                        if (!s.startsWith(prefixToken)) {
-                            s = prefixToken + s;
-                        }
-                        if (!s.endsWith(suffixToken)) {
-                            s = s + suffixToken;
-                        }
-                        final String value = s;
-                        answer.put(k.getLocalPart(), () -> value);
-                    }
-                }
-            });
-            return answer;
-        } else {
-            return readPlaceholders;
-        }
-    }
-
-    @Override
-    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        return writePlaceholders;
-    }
 }
 
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
index 66fda0a..4e8fb41 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
@@ -38,6 +38,7 @@ import org.apache.camel.Expression;
 import org.apache.camel.ExpressionFactory;
 import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.Predicate;
+import org.apache.camel.model.DefinitionPropertyPlaceholderConfigurable;
 import org.apache.camel.model.OtherAttributesAware;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.Metadata;
@@ -55,7 +56,7 @@ import org.apache.camel.util.ObjectHelper;
 @XmlRootElement
 @XmlType(name = "expression") // must be named expression
 @XmlAccessorType(XmlAccessType.FIELD)
-public class ExpressionDefinition implements Expression, Predicate, OtherAttributesAware, ExpressionFactory {
+public class ExpressionDefinition implements Expression, Predicate, OtherAttributesAware, ExpressionFactory, DefinitionPropertyPlaceholderConfigurable {
     @XmlAttribute
     @XmlID
     private String id;


[camel] 01/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b7071c82f4ff06dd19779ee295dcf00964fc97ae
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 12 07:18:47 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../org/apache/camel/model/FromDefinition.java     |  26 ++++-
 .../java/org/apache/camel/model/LogDefinition.java |  31 +++++-
 .../camel/model/ProcessorDefinitionHelper.java     | 111 ++++++++++-----------
 .../camel/model/PropertyPlaceholderAware.java      |  38 +++++++
 .../java/org/apache/camel/model/ToDefinition.java  |  56 ++++++++++-
 ...ockTest.java => SimpleMockPlaceholderTest.java} |  23 ++++-
 .../org/apache/camel/processor/SimpleMockTest.java |   2 -
 .../camel/support/PropertyPlaceholdersHelper.java  |   2 +
 8 files changed, 221 insertions(+), 68 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java
index e1faba2..6d61c6d 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinition.java
@@ -16,12 +16,17 @@
  */
 package org.apache.camel.model;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.builder.EndpointConsumerBuilder;
 import org.apache.camel.spi.Metadata;
@@ -32,7 +37,7 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "eip,endpoint,routing")
 @XmlRootElement(name = "from")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition> implements EndpointRequiredDefinition {
+public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition> implements PropertyPlaceholderAware, EndpointRequiredDefinition {
     @XmlAttribute @Metadata(required = true)
     private String uri;
     @XmlTransient
@@ -40,18 +45,28 @@ public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition>
     @XmlTransient
     private EndpointConsumerBuilder endpointConsumerBuilder;
 
+    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
+    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
+
     public FromDefinition() {
+        readPlaceholders.put("id", this::getId);
+        readPlaceholders.put("uri", this::getUri);
+        writePlaceholders.put("id", this::setId);
+        writePlaceholders.put("uri", this::setUri);
     }
 
     public FromDefinition(String uri) {
+        this();
         setUri(uri);
     }
 
     public FromDefinition(Endpoint endpoint) {
+        this();
         setEndpoint(endpoint);
     }
 
     public FromDefinition(EndpointConsumerBuilder endpointConsumerBuilder) {
+        this();
         setEndpointConsumerBuilder(endpointConsumerBuilder);
     }
 
@@ -135,4 +150,13 @@ public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition>
         this.uri = null;
     }
 
+    @Override
+    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
+        return readPlaceholders;
+    }
+
+    @Override
+    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        return writePlaceholders;
+    }
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
index c8e1b0a..62281e5 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
@@ -16,12 +16,17 @@
  */
 package org.apache.camel.model;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.spi.Metadata;
 import org.slf4j.Logger;
@@ -32,7 +37,7 @@ import org.slf4j.Logger;
 @Metadata(label = "eip,configuration")
 @XmlRootElement(name = "log")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class LogDefinition extends NoOutputDefinition<LogDefinition> {
+public class LogDefinition extends NoOutputDefinition<LogDefinition> implements PropertyPlaceholderAware {
 
     @XmlAttribute(required = true)
     private String message;
@@ -47,10 +52,24 @@ public class LogDefinition extends NoOutputDefinition<LogDefinition> {
     @XmlTransient
     private Logger logger;
 
+    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
+    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
+
     public LogDefinition() {
+        readPlaceholders.put("id", this::getId);
+        readPlaceholders.put("message", this::getMessage);
+        readPlaceholders.put("logName", this::getLogName);
+        readPlaceholders.put("marker", this::getMarker);
+        readPlaceholders.put("loggerRef", this::getLoggerRef);
+        writePlaceholders.put("id", this::setId);
+        writePlaceholders.put("message", this::setMessage);
+        writePlaceholders.put("logName", this::setLogName);
+        writePlaceholders.put("marker", this::setMarker);
+        writePlaceholders.put("loggerRef", this::setLoggerRef);
     }
 
     public LogDefinition(String message) {
+        this();
         this.message = message;
     }
 
@@ -136,4 +155,14 @@ public class LogDefinition extends NoOutputDefinition<LogDefinition> {
     public void setLogger(Logger logger) {
         this.logger = logger;
     }
+
+    @Override
+    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
+        return readPlaceholders;
+    }
+
+    @Override
+    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        return writePlaceholders;
+    }
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
index 420a7af..280965b 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
@@ -22,9 +22,12 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 import javax.xml.namespace.QName;
 
 import org.apache.camel.CamelContext;
@@ -628,10 +631,31 @@ public final class ProcessorDefinitionHelper {
         return rc;
     }
 
-    private static void addRestoreAction(final Object target, final Map<String, Object> properties) {
-        addRestoreAction(null, target, properties);
+    private static void addRestoreAction(Map<String, Consumer<String>> writeProperties, final Map<String, String> properties) {
+        if (properties.isEmpty()) {
+            return;
+        }
+
+        RestoreAction restoreAction = CURRENT_RESTORE_ACTION.get();
+        if (restoreAction == null) {
+            return;
+        }
+
+        restoreAction.actions.add(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    properties.forEach((k, v) -> {
+                        writeProperties.get(k).accept(v);
+                    });
+                } catch (Exception e) {
+                    LOG.warn("Cannot restore definition properties. This exception is ignored.", e);
+                }
+            }
+        });
     }
-    
+
+    @Deprecated
     private static void addRestoreAction(final CamelContext context, final Object target, final Map<String, Object> properties) {
         if (properties.isEmpty()) {
             return;
@@ -681,70 +705,37 @@ public final class ProcessorDefinitionHelper {
     public static void resolvePropertyPlaceholders(CamelContext camelContext, Object definition) throws Exception {
         LOG.trace("Resolving property placeholders for: {}", definition);
 
+        // only do this for models that supports property placeholders
+        if (!(definition instanceof PropertyPlaceholderAware)) {
+            return;
+        }
+
+        PropertyPlaceholderAware ppa = (PropertyPlaceholderAware) definition;
+
         // find all getter/setter which we can use for property placeholders
-        Map<String, Object> properties = new HashMap<>();
-        IntrospectionSupport.getProperties(definition, properties, null);
+        Map<String, String> changedProperties = new HashMap<>();
+        Map<String, Supplier<String>> readProperties = ppa.getReadPropertyPlaceholderOptions(camelContext);
+        Map<String, Consumer<String>> writeProperties = ppa.getWritePropertyPlaceholderOptions(camelContext);
 
-        OtherAttributesAware other = null;
-        if (definition instanceof OtherAttributesAware) {
-            other = (OtherAttributesAware) definition;
-        }
-        // include additional properties which have the Camel placeholder QName
-        // and when the definition parameter is this (otherAttributes belong to this)
-        if (other != null && other.getOtherAttributes() != null) {
-            for (QName key : other.getOtherAttributes().keySet()) {
-                if (Constants.PLACEHOLDER_QNAME.equals(key.getNamespaceURI())) {
-                    String local = key.getLocalPart();
-                    Object value = other.getOtherAttributes().get(key);
-                    if (value instanceof String) {
-                        // enforce a properties component to be created if none existed
-                        camelContext.getPropertiesComponent(true);
-
-                        // value must be enclosed with placeholder tokens
-                        String s = (String) value;
-                        String prefixToken = PropertiesComponent.PREFIX_TOKEN;
-                        String suffixToken = PropertiesComponent.SUFFIX_TOKEN;
-
-                        if (!s.startsWith(prefixToken)) {
-                            s = prefixToken + s;
-                        }
-                        if (!s.endsWith(suffixToken)) {
-                            s = s + suffixToken;
-                        }
-                        value = s;
-                    }
-                    properties.put(local, value);
-                }
+        if (!readProperties.isEmpty()) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("There are {} properties on: {}", readProperties.size(), definition);
             }
-        }
-
-        Map<String, Object> changedProperties = new HashMap<>();
-        if (!properties.isEmpty()) {
-            LOG.trace("There are {} properties on: {}", properties.size(), definition);
             // lookup and resolve properties for String based properties
-            for (Map.Entry<String, Object> entry : properties.entrySet()) {
-                // the name is always a String
+            for (Map.Entry<String, Supplier<String>> entry : readProperties.entrySet()) {
                 String name = entry.getKey();
-                Object value = entry.getValue();
-                if (value instanceof String) {
-                    // value must be a String, as a String is the key for a property placeholder
-                    String text = (String) value;
-                    text = camelContext.resolvePropertyPlaceholders(text);
-                    if (text != value) {
-                        // invoke setter as the text has changed
-                        boolean changed = IntrospectionSupport.setProperty(camelContext.getTypeConverter(), definition, name, text);
-                        if (!changed) {
-                            throw new IllegalArgumentException("No setter to set property: " + name + " to: " + text + " on: " + definition);
-                        }
-                        changedProperties.put(name, value);
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("Changed property [{}] from: {} to: {}", name, value, text);
-                        }
+                String value = entry.getValue().get();
+                String text = camelContext.resolvePropertyPlaceholders(value);
+                if (!Objects.equals(text, value)) {
+                    writeProperties.get(name).accept(text);
+                    changedProperties.put(name, value);
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Changed property [{}] from: {} to: {}", name, value, text);
                     }
                 }
             }
         }
-        addRestoreAction(camelContext, definition, changedProperties);
+        addRestoreAction(writeProperties, changedProperties);
     }
 
     /**
@@ -758,7 +749,7 @@ public final class ProcessorDefinitionHelper {
      */
     public static void resolveKnownConstantFields(CamelContext camelContext, Object definition) throws Exception {
         LOG.trace("Resolving known fields for: {}", definition);
-
+/*
         // find all String getter/setter
         Map<String, Object> properties = new HashMap<>();
         IntrospectionSupport.getProperties(definition, properties, null);
@@ -793,7 +784,7 @@ public final class ProcessorDefinitionHelper {
                 }
             }
         }
-        addRestoreAction(definition, changedProperties);
+        addRestoreAction(camelContext, definition, changedProperties);*/
     }
 
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java b/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
new file mode 100644
index 0000000..9bc6b4a
--- /dev/null
+++ b/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
@@ -0,0 +1,38 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.model;
+
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.apache.camel.CamelContext;
+
+public interface PropertyPlaceholderAware {
+
+    /**
+     * Gets the options on the model definition which supports property placeholders and can be resolved.
+     *
+     * @return key/values of options
+     */
+    Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext);
+
+    /**
+     * To update an existing property using the function with the ket/value and returning the changed value
+     */
+    Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext);
+}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
index 78828ad..3a0ba35 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
@@ -16,15 +16,22 @@
  */
 package org.apache.camel.model;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.builder.EndpointProducerBuilder;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.PropertiesComponent;
 
 /**
  * Sends the message to a static endpoint
@@ -32,22 +39,32 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "eip,endpoint,routing")
 @XmlRootElement(name = "to")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class ToDefinition extends SendDefinition<ToDefinition> {
+public class ToDefinition extends SendDefinition<ToDefinition> implements PropertyPlaceholderAware {
     @XmlAttribute
     private ExchangePattern pattern;
 
+    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
+    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
+
     public ToDefinition() {
+        readPlaceholders.put("id", this::getId);
+        readPlaceholders.put("uri", this::getUri);
+        writePlaceholders.put("id", this::setId);
+        writePlaceholders.put("uri", this::setUri);
     }
 
     public ToDefinition(String uri) {
+        this();
         setUri(uri);
     }
 
     public ToDefinition(Endpoint endpoint) {
+        this();
         setEndpoint(endpoint);
     }
 
     public ToDefinition(EndpointProducerBuilder endpointDefinition) {
+        this();
         setEndpointProducerBuilder(endpointDefinition);
     }
 
@@ -88,4 +105,41 @@ public class ToDefinition extends SendDefinition<ToDefinition> {
         this.pattern = pattern;
     }
 
+    @Override
+    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(final CamelContext camelContext) {
+        if (getOtherAttributes() != null && !getOtherAttributes().isEmpty()) {
+            final Map<String, Supplier<String>> answer = new HashMap<>(readPlaceholders);
+            getOtherAttributes().forEach((k, v) -> {
+                if (Constants.PLACEHOLDER_QNAME.equals(k.getNamespaceURI())) {
+                    if (v instanceof String) {
+                        // enforce a properties component to be created if none existed
+                        camelContext.getPropertiesComponent(true);
+
+                        // value must be enclosed with placeholder tokens
+                        String s = (String) v;
+                        String prefixToken = PropertiesComponent.PREFIX_TOKEN;
+                        String suffixToken = PropertiesComponent.SUFFIX_TOKEN;
+
+                        if (!s.startsWith(prefixToken)) {
+                            s = prefixToken + s;
+                        }
+                        if (!s.endsWith(suffixToken)) {
+                            s = s + suffixToken;
+                        }
+                        final String value = s;
+                        answer.put(k.getLocalPart(), () -> value);
+                    }
+                }
+            });
+            return answer;
+        } else {
+            return readPlaceholders;
+        }
+    }
+
+    @Override
+    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
+        return writePlaceholders;
+    }
 }
+
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockPlaceholderTest.java
similarity index 71%
copy from core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java
copy to core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockPlaceholderTest.java
index b8bd72d..dd8b986 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockPlaceholderTest.java
@@ -16,14 +16,31 @@
  */
 package org.apache.camel.processor;
 
-import java.util.stream.Stream;
+import java.util.Properties;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.properties.PropertiesComponent;
 import org.junit.Test;
 
-public class SimpleMockTest extends ContextTestSupport {
+public class SimpleMockPlaceholderTest extends ContextTestSupport {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        Properties myProp = new Properties();
+        myProp.put("foo", "log:foo");
+        myProp.put("end", "result");
+
+        PropertiesComponent pc = new PropertiesComponent();
+        pc.setInitialProperties(myProp);
+        context.addComponent("properties", pc);
+
+        return context;
+    }
 
     @Test
     public void testSimple() throws Exception {
@@ -51,7 +68,7 @@ public class SimpleMockTest extends ContextTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:start").to("log:foo").to("log:bar").to("mock:result");
+                from("direct:start").to("{{foo}}").to("log:bar").to("mock:{{end}}");
             }
         };
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java
index b8bd72d..015a692 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/SimpleMockTest.java
@@ -16,8 +16,6 @@
  */
 package org.apache.camel.processor;
 
-import java.util.stream.Stream;
-
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyPlaceholdersHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyPlaceholdersHelper.java
index c895914..84e44e9 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyPlaceholdersHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyPlaceholdersHelper.java
@@ -45,6 +45,8 @@ public final class PropertyPlaceholdersHelper {
     public static void resolvePropertyPlaceholders(CamelContext camelContext, Object object) throws Exception {
         LOG.trace("Resolving property placeholders for: {}", object);
 
+        // TODO: Like ProcessorDefinitionHelper we want to avoid reflection
+
         // find all getter/setter which we can use for property placeholders
         Map<String, Object> properties = new HashMap<>();
         IntrospectionSupport.getProperties(object, properties, null);


[camel] 09/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bf0fbee471c26c340daf3a94d9e3613ff32d8c8e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 13 08:24:33 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../org/apache/camel/reifier/ProcessorReifier.java |  4 +-
 .../apt/CoreEipAnnotationProcessorHelper.java      | 51 ++++++++++++----------
 2 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java b/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
index 460443e..5298219 100644
--- a/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
+++ b/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
@@ -113,7 +113,9 @@ public abstract class ProcessorReifier<T extends ProcessorDefinition<?>> {
 
     private static final Map<Class<?>, Function<ProcessorDefinition<?>, ProcessorReifier<? extends ProcessorDefinition<?>>>> PROCESSORS;
     static {
-        Map<Class<?>, Function<ProcessorDefinition<?>, ProcessorReifier<? extends ProcessorDefinition<?>>>> map = new HashMap<>();
+        // NOTE: if adding a new class then update the initial capacity of the HashMap
+        Map<Class<?>, Function<ProcessorDefinition<?>, ProcessorReifier<? extends ProcessorDefinition<?>>>> map
+                = new HashMap<>(65);
         map.put(AggregateDefinition.class, AggregateReifier::new);
         map.put(BeanDefinition.class, BeanReifier::new);
         map.put(CatchDefinition.class, CatchReifier::new);
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 fc00956..6b49614 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
@@ -18,7 +18,6 @@ package org.apache.camel.tools.apt;
 
 import java.io.PrintWriter;
 import java.io.Writer;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -46,7 +45,6 @@ import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
 import org.apache.camel.spi.AsPredicate;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.tools.apt.helper.IOHelper;
@@ -54,7 +52,6 @@ import org.apache.camel.tools.apt.helper.JsonSchemaHelper;
 import org.apache.camel.tools.apt.helper.Strings;
 
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.dumpExceptionToErrorFile;
-import static org.apache.camel.tools.apt.AnnotationProcessorHelper.error;
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.findJavaDoc;
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement;
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElementChildren;
@@ -68,7 +65,9 @@ import static org.apache.camel.tools.apt.helper.Strings.safeNull;
 
 /**
  * Process all camel-core's model classes (EIPs and DSL) and generate json
- * schema documentation
+ * schema documentation and for some models java source code is generated
+ * which allows for faster property placeholder resolution at runtime; without the
+ * overhead of using reflections.
  */
 public class CoreEipAnnotationProcessorHelper {
 
@@ -130,19 +129,18 @@ public class CoreEipAnnotationProcessorHelper {
         }
 
         // write json schema and property placeholder provider
-        processFile(processingEnv, packageName, fileName, writer -> writeJSonSchemeDocumentation(processingEnv, writer,
+        processFile(processingEnv, packageName, fileName, writer -> writeJSonSchemeAndPropertyPlaceholderProvider(processingEnv, writer,
                 roundEnv, classElement, rootElement, javaTypeName, name, propertyPlaceholderDefinitions));
 
-        // if last then generate
+        // if last then generate source code for helper that contains all the generated property placeholder providers
+        // (this allows fast property placeholders at runtime without reflection overhead)
         if (last) {
-            // lets sort themfirst
             writePropertyPlaceholderDefinitionsHelper(processingEnv, roundEnv, propertyPlaceholderDefinitions);
         }
     }
 
-    // TODO: rename this 
-    protected void writeJSonSchemeDocumentation(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
-                                                XmlRootElement rootElement, String javaTypeName, String modelName, Set<String> propertyPlaceholderDefinitions) {
+    protected void writeJSonSchemeAndPropertyPlaceholderProvider(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
+                                                                 XmlRootElement rootElement, String javaTypeName, String modelName, Set<String> propertyPlaceholderDefinitions) {
         // gather eip information
         EipModel eipModel = findEipModelProperties(processingEnv, roundEnv, classElement, javaTypeName, modelName);
 
@@ -156,17 +154,19 @@ public class CoreEipAnnotationProcessorHelper {
         eipModel.setInput(hasInput(processingEnv, roundEnv, classElement));
         eipModel.setOutput(hasOutput(eipModel, eipOptions));
 
+        // write json schema file
         String json = createParameterJsonSchema(eipModel, eipOptions);
         writer.println(json);
 
-        // write property placeholder source code
-        writePropertyPlaceholderProviderSource(processingEnv, writer, roundEnv, classElement, eipModel, eipOptions, propertyPlaceholderDefinitions);
+        // generate property placeholder provider java source code
+        generatePropertyPlaceholderProviderSource(processingEnv, writer, roundEnv, classElement, eipModel, eipOptions, propertyPlaceholderDefinitions);
     }
 
-    protected void writePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
-                                                          EipModel eipModel, Set<EipOption> options, Set<String> propertyPlaceholderDefinitions) {
+    protected void generatePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
+                                                             EipModel eipModel, Set<EipOption> options, Set<String> propertyPlaceholderDefinitions) {
 
-        // the following are valid class elements which we want to generate
+        // not ever model classes support property placeholders as this has been limited to mainly Camel routes
+        // so filter out unwanted models
         boolean rest = classElement.getQualifiedName().toString().startsWith("org.apache.camel.model.rest");
         boolean processor = hasSuperClass(processingEnv, roundEnv, classElement, "org.apache.camel.model.ProcessorDefinition");
         boolean language = hasSuperClass(processingEnv, roundEnv, classElement, "org.apache.camel.model.language.ExpressionDefinition");
@@ -238,7 +238,7 @@ public class CoreEipAnnotationProcessorHelper {
             for (EipOption option : options) {
                 if ("java.lang.String".equals(option.getType())) {
                     found = true;
-                    String getOrSet = sanitizeOptionName(def, option);
+                    String getOrSet = sanitizePropertyPlaceholderOptionName(def, option);
                     getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1);
                     w.write("        readPlaceholders.put(\"" + option.getName() + "\", definition::get" + getOrSet + ");\n");
                     w.write("        writePlaceholders.put(\"" + option.getName() + "\", definition::set" + getOrSet + ");\n");
@@ -270,8 +270,11 @@ public class CoreEipAnnotationProcessorHelper {
         }
     }
 
-    public String sanitizeOptionName(String def, EipOption option) {
-        // some elements have different setter/getter names vs the xml dsl
+    /**
+     * Some models have different setter/getter names vs the xml name (eg as defined in @XmlAttribute).
+     * So we need to correct this using this method.
+     */
+    public String sanitizePropertyPlaceholderOptionName(String def, EipOption option) {
         if ("SimpleExpression".equals(def) || "JsonPathExpression".equals(def)) {
             if ("resultType".equals(option.getName())) {
                 return "resultTypeName";
@@ -336,7 +339,7 @@ public class CoreEipAnnotationProcessorHelper {
             w.write("\n");
             w.write("    private static final Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> MAP;\n");
             w.write("    static {\n");
-            w.write("        Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> map = new HashMap<>();\n");
+            w.write("        Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> map = new HashMap<>(" + propertyPlaceholderDefinitions.size() + ");\n");
             for (String def : propertyPlaceholderDefinitions) {
                 String cn = def.substring(def.lastIndexOf('.') + 1);
                 w.write("        map.put(" + cn + ".class, " + cn + "PropertyPlaceholderProvider::new);\n");
@@ -1501,19 +1504,19 @@ public class CoreEipAnnotationProcessorHelper {
 
         @Override
         public int compare(EipOption o1, EipOption o2) {
-            int weigth = weigth(o1);
-            int weigth2 = weigth(o2);
+            int weight = weight(o1);
+            int weight2 = weight(o2);
 
-            if (weigth == weigth2) {
+            if (weight == weight2) {
                 // keep the current order
                 return 1;
             } else {
                 // sort according to weight
-                return weigth2 - weigth;
+                return weight2 - weight;
             }
         }
 
-        private int weigth(EipOption o) {
+        private int weight(EipOption o) {
             String name = o.getName();
 
             // these should be first


[camel] 07/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 34f2b3de091fc865678b695276f050616ac23933
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 13 06:03:50 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../DefinitionPropertyPlaceholderConfigurable.java |  2 +
 .../camel/model/ProcessorDefinitionHelper.java     | 62 ++++++++++++++++++++++
 .../OptionalPropertiesDslInvalidSyntaxTest.java    |  7 ++-
 3 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
index 8d5758c..16520e3 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
@@ -16,12 +16,14 @@
  */
 package org.apache.camel.model;
 
+import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.model.placeholder.DefinitionPropertiesPlaceholderProviderHelper;
+import org.apache.camel.spi.PropertiesComponent;
 
 /**
  * To be used for configuring property placeholder options on the EIP models.
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
index 169dc3d..439ffbe 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
@@ -29,10 +29,16 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
+import javax.xml.namespace.QName;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.NamedNode;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.ExecutorServiceManager;
+import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.RouteContext;
+import org.apache.camel.support.IntrospectionSupport;
+import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -670,6 +676,7 @@ public final class ProcessorDefinitionHelper {
      * @see org.apache.camel.CamelContext#resolvePropertyPlaceholders(String)
      * @see org.apache.camel.component.properties.PropertiesComponent
      */
+    @SuppressWarnings("unchecked")
     public static void resolvePropertyPlaceholders(CamelContext camelContext, Object definition) throws Exception {
         LOG.trace("Resolving property placeholders for: {}", definition);
 
@@ -685,6 +692,61 @@ public final class ProcessorDefinitionHelper {
         Map<String, Supplier<String>> readProperties = ppa.getReadPropertyPlaceholderOptions(camelContext);
         Map<String, Consumer<String>> writeProperties = ppa.getWritePropertyPlaceholderOptions(camelContext);
 
+        // processor's may have additional placeholder properties (can typically be used by the XML DSL to
+        // allow to configure using placeholders for properties that are not xs:string types)
+        if (definition instanceof ProcessorDefinition) {
+            ProcessorDefinition pd = (ProcessorDefinition) definition;
+
+            if (pd.getOtherAttributes() != null && !pd.getOtherAttributes().isEmpty()) {
+                Map<String, Supplier<String>> extraRead = new HashMap<>();
+                if (readProperties != null && !readProperties.isEmpty()) {
+                    extraRead.putAll(readProperties);
+                }
+                Map<String, Consumer<String>> extraWrite = new HashMap<>();
+                if (writeProperties != null && !writeProperties.isEmpty()) {
+                    extraWrite.putAll(writeProperties);
+                }
+
+                Map<QName, Object> other = pd.getOtherAttributes();
+                other.forEach((k, v) -> {
+                    if (Constants.PLACEHOLDER_QNAME.equals(k.getNamespaceURI())) {
+                        if (v instanceof String) {
+                            // enforce a properties component to be created if none existed
+                            camelContext.getPropertiesComponent(true);
+
+                            // value must be enclosed with placeholder tokens
+                            String s = (String) v;
+                            String prefixToken = PropertiesComponent.PREFIX_TOKEN;
+                            String suffixToken = PropertiesComponent.SUFFIX_TOKEN;
+
+                            if (!s.startsWith(prefixToken)) {
+                                s = prefixToken + s;
+                            }
+                            if (!s.endsWith(suffixToken)) {
+                                s = s + suffixToken;
+                            }
+                            final String value = s;
+                            extraRead.put(k.getLocalPart(), () -> value);
+                            extraWrite.put(k.getLocalPart(), text -> {
+                                try {
+                                    PropertyBindingSupport.build()
+                                            .withCamelContext(camelContext)
+                                            .withTarget(definition)
+                                            .withMandatory(true)
+                                            .withProperty(k.getLocalPart(), text)
+                                            .bind();
+                                } catch (Exception e) {
+                                    throw RuntimeCamelException.wrapRuntimeException(e);
+                                }
+                            });
+                        }
+                    }
+                });
+                readProperties = extraRead;
+                writeProperties = extraWrite;
+            }
+        }
+
         if (readProperties != null && !readProperties.isEmpty()) {
             if (LOG.isTraceEnabled()) {
                 LOG.trace("There are {} properties on: {}", readProperties.size(), definition);
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/properties/OptionalPropertiesDslInvalidSyntaxTest.java b/core/camel-core/src/test/java/org/apache/camel/component/properties/OptionalPropertiesDslInvalidSyntaxTest.java
index e22b671..301e668 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/properties/OptionalPropertiesDslInvalidSyntaxTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/properties/OptionalPropertiesDslInvalidSyntaxTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.properties;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.PropertyBindingException;
 import org.apache.camel.builder.RouteBuilder;
 import org.junit.Test;
 
@@ -59,8 +60,10 @@ public class OptionalPropertiesDslInvalidSyntaxTest extends ContextTestSupport {
             context.start();
             fail("Should have thrown exception");
         } catch (Exception e) {
-            IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
-            assertEquals("No setter to set property: xxx to: true on: Multicast[[To[mock:a], ThrowException[java.lang.IllegalAccessException], To[mock:b]]]", cause.getMessage());
+            PropertyBindingException cause = assertIsInstanceOf(PropertyBindingException.class, e.getCause());
+            assertEquals("xxx", cause.getPropertyName());
+            assertEquals("true", cause.getValue());
+            assertTrue(cause.getMessage().startsWith("Error binding property (xxx=true) with name: xxx on bean: Multicast"));
         }
     }
 


[camel] 03/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3ed317216d9de5b1acdda1c81504638c8371e0c2
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 12 18:00:21 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../model/DefinitionPropertiesProviderHelper.java  |  18 ++-
 ...DefinitionPropertyPlaceholderConfigurable.java} |  14 +-
 .../model/FromDefinitionPropertiesProvider.java    |  50 -------
 .../model/LogDefinitionPropertiesProvider.java     |  56 --------
 .../camel/model/OptionalIdentifiedDefinition.java  |   2 +-
 .../camel/model/ProcessorDefinitionHelper.java     |  36 +----
 .../java/org/apache/camel/model/ToDefinition.java  |   3 +-
 .../model/ToDefinitionPropertiesProvider.java      |  50 -------
 .../apt/CoreEipAnnotationProcessorHelper.java      | 158 +++++++++++++++++++++
 9 files changed, 182 insertions(+), 205 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
index 7da3ffd..86cb92e 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertiesProviderHelper.java
@@ -21,19 +21,23 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.function.Function;
 
+import org.apache.camel.model.placeholder.FromDefinitionPropertyPlaceholderProvider;
+import org.apache.camel.model.placeholder.LogDefinitionPropertyPlaceholderProvider;
+import org.apache.camel.model.placeholder.ToDefinitionPropertyPlaceholderProvider;
+
 public class DefinitionPropertiesProviderHelper {
 
-    private static final Map<Class, Function<Object, PropertyPlaceholderAware>> MAP;
+    private static final Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> MAP;
     static {
-        Map<Class, Function<Object, PropertyPlaceholderAware>> map = new HashMap<>();
-        map.put(FromDefinition.class, FromDefinitionPropertiesProvider::new);
-        map.put(LogDefinition.class, LogDefinitionPropertiesProvider::new);
-        map.put(ToDefinition.class, ToDefinitionPropertiesProvider::new);
+        Map<Class, Function<Object, DefinitionPropertyPlaceholderConfigurable>> map = new HashMap<>();
+        map.put(FromDefinition.class, FromDefinitionPropertyPlaceholderProvider::new);
+        map.put(LogDefinition.class, LogDefinitionPropertyPlaceholderProvider::new);
+        map.put(ToDefinition.class, ToDefinitionPropertyPlaceholderProvider::new);
         MAP = map;
     }
 
-    public static Optional<PropertyPlaceholderAware> provider(Object definition) {
-        Function<Object, PropertyPlaceholderAware> func = MAP.get(definition.getClass());
+    public static Optional<DefinitionPropertyPlaceholderConfigurable> provider(Object definition) {
+        Function<Object, DefinitionPropertyPlaceholderConfigurable> func = MAP.get(definition.getClass());
         if (func != null) {
             return Optional.of(func.apply(definition));
         }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
similarity index 75%
rename from core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
rename to core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
index c4fb8b7..9c82f6b 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/PropertyPlaceholderAware.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/DefinitionPropertyPlaceholderConfigurable.java
@@ -22,24 +22,28 @@ import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
 
-// TODO: Rename interface
-public interface PropertyPlaceholderAware {
+/**
+ * To be used for configuring property placeholder options on the EIP models.
+ */
+public interface DefinitionPropertyPlaceholderConfigurable {
 
     /**
      * Gets the options on the model definition which supports property placeholders and can be resolved.
+     * This will be all the string based options.
      *
      * @return key/values of options
      */
     default Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        PropertyPlaceholderAware aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
+        DefinitionPropertyPlaceholderConfigurable aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
         return aware != null ? aware.getReadPropertyPlaceholderOptions(camelContext) : null;
     }
 
     /**
-     * To update an existing property using the function with the ket/value and returning the changed value
+     * To update an existing property using the function with the key/value and returning the changed value
+     * This will be all the string based options.
      */
     default Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        PropertyPlaceholderAware aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
+        DefinitionPropertyPlaceholderConfigurable aware = DefinitionPropertiesProviderHelper.provider(this).orElse(null);
         return aware != null ? aware.getWritePropertyPlaceholderOptions(camelContext) : null;
     }
 
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinitionPropertiesProvider.java b/core/camel-core/src/main/java/org/apache/camel/model/FromDefinitionPropertiesProvider.java
deleted file mode 100644
index 5953f84..0000000
--- a/core/camel-core/src/main/java/org/apache/camel/model/FromDefinitionPropertiesProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.model;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-import org.apache.camel.CamelContext;
-
-public class FromDefinitionPropertiesProvider implements PropertyPlaceholderAware {
-
-    private final FromDefinition definition;
-    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
-    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
-
-    public FromDefinitionPropertiesProvider(Object obj) {
-        this.definition = (FromDefinition) obj;
-
-        readPlaceholders.put("id", definition::getId);
-        readPlaceholders.put("uri", definition::getUri);
-        writePlaceholders.put("id", definition::setId);
-        writePlaceholders.put("uri", definition::setUri);
-    }
-
-    @Override
-    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        return readPlaceholders;
-    }
-
-    @Override
-    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        return writePlaceholders;
-    }
-}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinitionPropertiesProvider.java b/core/camel-core/src/main/java/org/apache/camel/model/LogDefinitionPropertiesProvider.java
deleted file mode 100644
index a60ffa8..0000000
--- a/core/camel-core/src/main/java/org/apache/camel/model/LogDefinitionPropertiesProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.model;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-import org.apache.camel.CamelContext;
-
-public class LogDefinitionPropertiesProvider implements PropertyPlaceholderAware {
-
-    private final LogDefinition definition;
-    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
-    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
-
-    public LogDefinitionPropertiesProvider(Object obj) {
-        this.definition = (LogDefinition) obj;
-
-        readPlaceholders.put("id", definition::getId);
-        readPlaceholders.put("message", definition::getMessage);
-        readPlaceholders.put("logName", definition::getLogName);
-        readPlaceholders.put("marker", definition::getMarker);
-        readPlaceholders.put("loggerRef", definition::getLoggerRef);
-        writePlaceholders.put("id", definition::setId);
-        writePlaceholders.put("message", definition::setMessage);
-        writePlaceholders.put("logName", definition::setLogName);
-        writePlaceholders.put("marker", definition::setMarker);
-        writePlaceholders.put("loggerRef", definition::setLoggerRef);
-    }
-
-    @Override
-    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        return readPlaceholders;
-    }
-
-    @Override
-    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        return writePlaceholders;
-    }
-}
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java
index 5f520f5..9ca6bff 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/OptionalIdentifiedDefinition.java
@@ -31,7 +31,7 @@ import org.apache.camel.spi.NodeIdFactory;
 @XmlType(name = "optionalIdentifiedDefinition")
 @XmlAccessorType(XmlAccessType.PROPERTY)
 // must use XmlAccessType.PROPERTY which is required by camel-spring / camel-blueprint for their namespace parsers
-public abstract class OptionalIdentifiedDefinition<T extends OptionalIdentifiedDefinition<T>> implements NamedNode, PropertyPlaceholderAware {
+public abstract class OptionalIdentifiedDefinition<T extends OptionalIdentifiedDefinition<T>> implements NamedNode, DefinitionPropertyPlaceholderConfigurable {
 
     private String id;
     private Boolean customId;
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
index ff809f6..b57f51a 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
@@ -28,18 +28,12 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
-import javax.xml.namespace.QName;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
 import org.apache.camel.NamedNode;
 import org.apache.camel.spi.ExecutorServiceManager;
-import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.RouteContext;
-import org.apache.camel.support.IntrospectionSupport;
-import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -655,32 +649,6 @@ public final class ProcessorDefinitionHelper {
         });
     }
 
-    @Deprecated
-    private static void addRestoreAction(final CamelContext context, final Object target, final Map<String, Object> properties) {
-        if (properties.isEmpty()) {
-            return;
-        }
-
-        RestoreAction restoreAction = CURRENT_RESTORE_ACTION.get();
-        if (restoreAction == null) {
-            return;
-        }
-
-        restoreAction.actions.add(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    // do not use property placeholders as we want to preserve the text as-is when we restore
-                    PropertyBindingSupport.build()
-                            .withPlaceholder(false).withNesting(false).withReference(false)
-                            .bind(context, target, properties);
-                } catch (Exception e) {
-                    LOG.warn("Cannot restore definition properties. This exception is ignored.", e);
-                }
-            }
-        });
-    }
-
     public static void addPropertyPlaceholdersChangeRevertAction(Runnable action) {
         RestoreAction restoreAction = CURRENT_RESTORE_ACTION.get();
         if (restoreAction == null) {
@@ -706,11 +674,11 @@ public final class ProcessorDefinitionHelper {
         LOG.trace("Resolving property placeholders for: {}", definition);
 
         // only do this for models that supports property placeholders
-        if (!(definition instanceof PropertyPlaceholderAware)) {
+        if (!(definition instanceof DefinitionPropertyPlaceholderConfigurable)) {
             return;
         }
 
-        PropertyPlaceholderAware ppa = (PropertyPlaceholderAware) definition;
+        DefinitionPropertyPlaceholderConfigurable ppa = (DefinitionPropertyPlaceholderConfigurable) definition;
 
         // find all getter/setter which we can use for property placeholders
         Map<String, String> changedProperties = new HashMap<>();
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
index 3a0ba35..10b61d8 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinition.java
@@ -18,7 +18,6 @@ package org.apache.camel.model;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
@@ -39,7 +38,7 @@ import org.apache.camel.spi.PropertiesComponent;
 @Metadata(label = "eip,endpoint,routing")
 @XmlRootElement(name = "to")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class ToDefinition extends SendDefinition<ToDefinition> implements PropertyPlaceholderAware {
+public class ToDefinition extends SendDefinition<ToDefinition> implements DefinitionPropertyPlaceholderConfigurable {
     @XmlAttribute
     private ExchangePattern pattern;
 
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinitionPropertiesProvider.java b/core/camel-core/src/main/java/org/apache/camel/model/ToDefinitionPropertiesProvider.java
deleted file mode 100644
index e0e64a5..0000000
--- a/core/camel-core/src/main/java/org/apache/camel/model/ToDefinitionPropertiesProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.model;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-import org.apache.camel.CamelContext;
-
-public class ToDefinitionPropertiesProvider implements PropertyPlaceholderAware {
-
-    private final ToDefinition definition;
-    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();
-    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();
-
-    public ToDefinitionPropertiesProvider(Object obj) {
-        this.definition = (ToDefinition) obj;
-
-        readPlaceholders.put("id", definition::getId);
-        readPlaceholders.put("uri", definition::getUri);
-        writePlaceholders.put("id", definition::setId);
-        writePlaceholders.put("uri", definition::setUri);
-    }
-
-    @Override
-    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {
-        return readPlaceholders;
-    }
-
-    @Override
-    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {
-        return writePlaceholders;
-    }
-}
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 df08f15..edb48d7 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
@@ -17,12 +17,14 @@
 package org.apache.camel.tools.apt;
 
 import java.io.PrintWriter;
+import java.io.Writer;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 import javax.annotation.processing.ProcessingEnvironment;
@@ -34,6 +36,8 @@ import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.ElementFilter;
 import javax.lang.model.util.Elements;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementRef;
@@ -42,11 +46,15 @@ import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
+import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
 import org.apache.camel.spi.AsPredicate;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.tools.apt.helper.IOHelper;
 import org.apache.camel.tools.apt.helper.JsonSchemaHelper;
 import org.apache.camel.tools.apt.helper.Strings;
 
+import static org.apache.camel.tools.apt.AnnotationProcessorHelper.dumpExceptionToErrorFile;
+import static org.apache.camel.tools.apt.AnnotationProcessorHelper.error;
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.findJavaDoc;
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement;
 import static org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElementChildren;
@@ -124,6 +132,7 @@ public class CoreEipAnnotationProcessorHelper {
         processFile(processingEnv, packageName, fileName, writer -> writeJSonSchemeDocumentation(processingEnv, writer, roundEnv, classElement, rootElement, javaTypeName, name));
     }
 
+
     protected void writeJSonSchemeDocumentation(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
                                                 XmlRootElement rootElement, String javaTypeName, String modelName) {
         // gather eip information
@@ -141,6 +150,155 @@ public class CoreEipAnnotationProcessorHelper {
 
         String json = createParameterJsonSchema(eipModel, eipOptions);
         writer.println(json);
+
+        // write property placeholder source code
+        writePropertyPlaceholderProviderSource(processingEnv, writer, roundEnv, classElement, eipModel, eipOptions);
+    }
+
+    protected void writePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement,
+                                                          EipModel eipModel, Set<EipOption> options) {
+
+        // the following are valid class elements which we want to generate
+        boolean rest = classElement.getQualifiedName().toString().startsWith("org.apache.camel.model.rest");
+        boolean processor = hasSuperClass(processingEnv, roundEnv, classElement, "org.apache.camel.model.ProcessorDefinition");
+        boolean language = hasSuperClass(processingEnv, roundEnv, classElement, "org.apache.camel.model.language.ExpressionDefinition");
+        boolean dataformat = hasSuperClass(processingEnv, roundEnv, classElement, "org.apache.camel.model.DataFormatDefinition");
+
+        if (!rest && !processor && !language && !dataformat) {
+            return;
+        }
+
+        TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.model.DefinitionPropertyPlaceholderConfigurable");
+        String def = classElement.getSimpleName().toString();
+        String fqnDef = classElement.getQualifiedName().toString();
+        String cn = def + "PropertyPlaceholderProvider";
+        String fqn = "org.apache.camel.model.placeholder." + cn;
+
+        doWritePropertyPlaceholderProviderSource(processingEnv, parent, def, fqnDef, cn, fqn, options);
+
+        // we also need to generate from when we generate route as from can also configure property placeholders
+        if ("RouteDefinition".equals(def)) {
+            def = "FromDefinition";
+            fqnDef = "org.apache.camel.model.FromDefinition";
+            cn = "FromDefinitionPropertyPlaceholderProvider";
+            fqn = "org.apache.camel.model.placeholder.FromDefinitionPropertyPlaceholderProvider";
+
+            options.clear();
+            options.add(new EipOption("id", null, null, "java.lang.String", false, null, null, false, null, false, null, false, null, false));
+            options.add(new EipOption("uri", null, null, "java.lang.String", false, null, null, false, null, false, null, false, null, false));
+
+            doWritePropertyPlaceholderProviderSource(processingEnv, parent, def, fqnDef, cn, fqn, options);
+        }
+    }
+
+    private void doWritePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, TypeElement parent,
+                                                          String def, String fqnDef, String cn, String fqn,
+                                                          Set<EipOption> options) {
+
+        Writer w = null;
+        try {
+            JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn, parent);
+            w = src.openWriter();
+
+            w.write("/* Generated by camel-apt */\n");
+            w.write("package org.apache.camel.model.placeholder;\n");
+            w.write("\n");
+            w.write("import java.util.HashMap;\n");
+            w.write("import java.util.Map;\n");
+            w.write("import java.util.function.Consumer;\n");
+            w.write("import java.util.function.Supplier;\n");
+            w.write("\n");
+            w.write("import org.apache.camel.CamelContext;\n");
+            w.write("import " + fqnDef + ";\n");
+            w.write("import org.apache.camel.model.DefinitionPropertyPlaceholderConfigurable;\n");
+            w.write("\n");
+            w.write("public class " + cn + " implements DefinitionPropertyPlaceholderConfigurable {\n");
+            w.write("\n");
+            w.write("    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();\n");
+            w.write("    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();\n");
+            w.write("\n");
+
+            // add constructor
+            w.write("    public " + cn + "(Object obj) {\n");
+            w.write("        " + def + " definition = (" + def + ") obj;\n");
+            w.write("\n");
+
+            // only include string types as they are the only ones we can use for property placeholders
+            boolean found = false;
+            for (EipOption option : options) {
+                if ("java.lang.String".equals(option.getType())) {
+                    found = true;
+                    String getOrSet = sanitizeOptionName(def, option);
+                    getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1);
+                    w.write("        readPlaceholders.put(\"" + option.getName() + "\", definition::get" + getOrSet + ");\n");
+                    w.write("        writePlaceholders.put(\"" + option.getName() + "\", definition::set" + getOrSet + ");\n");
+                }
+            }
+            if (!found) {
+                w.write("\n");
+            }
+
+            w.write("    }\n");
+            w.write("\n");
+            w.write("    @Override\n");
+            w.write("    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {\n");
+            w.write("        return readPlaceholders;\n");
+            w.write("    }\n");
+            w.write("\n");
+            w.write("    @Override\n");
+            w.write("    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {\n");
+            w.write("        return writePlaceholders;\n");
+            w.write("    }\n");
+            w.write("\n");
+            w.write("}\n");
+            w.write("\n");
+        } catch (Exception e) {
+            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to process annotated elements in " + getClass().getSimpleName() + ": " + e.getMessage());
+            dumpExceptionToErrorFile("camel-apt-error.log", "Error processing annotation in " + getClass().getSimpleName(), e);
+        } finally {
+            IOHelper.close(w);
+        }
+    }
+
+    public String sanitizeOptionName(String def, EipOption option) {
+        // some elements have different setter/getter names vs the xml dsl
+        if ("SimpleExpression".equals(def) || "JsonPathExpression".equals(def)) {
+            if ("resultType".equals(option.getName())) {
+                return "resultTypeName";
+            }
+        } else if ("EnrichDefinition".equals(def) || "PollEnrichDefinition".equals(def) || "ClaimCheckDefinition".equals(def)) {
+            if ("strategyRef".equals(option.getName())) {
+                return "aggregationStrategyRef";
+            } else if ("strategyMethodName".equals(option.getName())) {
+                return "aggregationStrategyMethodName";
+            } else if ("strategyMethodAllowNull".equals(option.getName())) {
+                return "aggregationStrategyMethodAllowNull";
+            }
+        } else if ("MethodCallExpression".equals(def)) {
+            if ("beanType".equals(option.getName())) {
+                return "beanTypeName";
+            }
+        } else if ("XPathExpression".equals(def)) {
+            if ("documentType".equals(option.getName())) {
+                return "documentTypeName";
+            } else if ("resultType".equals(option.getName())) {
+                return "resultTypeName";
+            }
+        } else if ("WireTapDefinition".equals(def)) {
+            if ("processorRef".equals(option.getName())) {
+                return "newExchangeProcessorRef";
+            }
+        } else if ("TidyMarkupDataFormat".equals(def)) {
+            if ("dataObjectType".equals(option.getName())) {
+                return "dataObjectTypeName";
+            }
+        } else if ("BindyDataFormat".equals(def)) {
+            if ("classType".equals(option.getName())) {
+                return "classTypeAsString";
+            }
+        }
+
+        return option.getName();
     }
 
     public String createParameterJsonSchema(EipModel eipModel, Set<EipOption> options) {


[camel] 08/09: CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 94564a5217fb873c34da0a3d759f4bee29730383
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 13 06:12:37 2019 +0200

    CAMEL-13850: Optimize model classes to provide changeable properties that support property placeholders to avoid reflection. Work in progress.
---
 .../camel/model/ProcessorDefinitionHelper.java     | 81 +++++++---------------
 .../org/apache/camel/reifier/ChoiceReifier.java    |  3 -
 .../org/apache/camel/reifier/ProcessorReifier.java | 12 ----
 ...RouteWithConstantFieldFromExchangeFailTest.java |  1 +
 4 files changed, 25 insertions(+), 72 deletions(-)

diff --git a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
index 439ffbe..69e06b3 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinitionHelper.java
@@ -32,6 +32,7 @@ import java.util.function.Supplier;
 import javax.xml.namespace.QName;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
 import org.apache.camel.NamedNode;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.ExecutorServiceManager;
@@ -40,6 +41,7 @@ import org.apache.camel.spi.RouteContext;
 import org.apache.camel.support.IntrospectionSupport;
 import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -668,7 +670,10 @@ public final class ProcessorDefinitionHelper {
      * Inspects the given definition and resolves any property placeholders from its properties.
      * <p/>
      * This implementation will check all the getter/setter pairs on this instance and for all the values
-     * (which is a String type) will be property placeholder resolved. The definition should implement {@link OtherAttributesAware}
+     * (which is a String type) will be property placeholder resolved.
+     * Additional properties are also resolved if the definition implements {@link OtherAttributesAware}.
+     * Also known constant fields on {@link Exchange} is replaced with their actual constant value, eg
+     * <tt>Exchange.FILE_NAME</tt> is replaced with <tt>CamelFileName</tt>.
      *
      * @param camelContext the Camel context
      * @param definition   the definition which should implement {@link OtherAttributesAware}
@@ -692,12 +697,12 @@ public final class ProcessorDefinitionHelper {
         Map<String, Supplier<String>> readProperties = ppa.getReadPropertyPlaceholderOptions(camelContext);
         Map<String, Consumer<String>> writeProperties = ppa.getWritePropertyPlaceholderOptions(camelContext);
 
-        // processor's may have additional placeholder properties (can typically be used by the XML DSL to
+        // definitions may have additional placeholder properties (can typically be used by the XML DSL to
         // allow to configure using placeholders for properties that are not xs:string types)
-        if (definition instanceof ProcessorDefinition) {
-            ProcessorDefinition pd = (ProcessorDefinition) definition;
+        if (definition instanceof OtherAttributesAware) {
+            OtherAttributesAware ooa = (OtherAttributesAware) definition;
 
-            if (pd.getOtherAttributes() != null && !pd.getOtherAttributes().isEmpty()) {
+            if (ooa.getOtherAttributes() != null && !ooa.getOtherAttributes().isEmpty()) {
                 Map<String, Supplier<String>> extraRead = new HashMap<>();
                 if (readProperties != null && !readProperties.isEmpty()) {
                     extraRead.putAll(readProperties);
@@ -707,7 +712,7 @@ public final class ProcessorDefinitionHelper {
                     extraWrite.putAll(writeProperties);
                 }
 
-                Map<QName, Object> other = pd.getOtherAttributes();
+                Map<QName, Object> other = ooa.getOtherAttributes();
                 other.forEach((k, v) -> {
                     if (Constants.PLACEHOLDER_QNAME.equals(k.getNamespaceURI())) {
                         if (v instanceof String) {
@@ -757,6 +762,19 @@ public final class ProcessorDefinitionHelper {
                 String name = entry.getKey();
                 String value = entry.getValue().get();
                 String text = camelContext.resolvePropertyPlaceholders(value);
+
+                // is the value a known field (currently we only support constants from Exchange.class)
+                if (text != null && text.startsWith("Exchange.")) {
+                    String field = StringHelper.after(text, "Exchange.");
+                    // TODO: Avoid reflection via fields
+                    String constant = ObjectHelper.lookupConstantFieldValue(Exchange.class, field);
+                    if (constant != null) {
+                        text = constant;
+                    } else {
+                        throw new IllegalArgumentException("Constant field with name: " + field + " not found on Exchange.class");
+                    }
+                }
+
                 if (!Objects.equals(text, value)) {
                     writeProperties.get(name).accept(text);
                     changedProperties.put(name, value);
@@ -769,55 +787,4 @@ public final class ProcessorDefinitionHelper {
         addRestoreAction(writeProperties, changedProperties);
     }
 
-    /**
-     * Inspects the given definition and resolves known fields
-     * <p/>
-     * This implementation will check all the getter/setter pairs on this instance and for all the values
-     * (which is a String type) will check if it refers to a known field (such as on Exchange).
-     *
-     * @param camelContext the camel context
-     * @param definition   the definition
-     */
-    public static void resolveKnownConstantFields(CamelContext camelContext, Object definition) throws Exception {
-        LOG.trace("Resolving known fields for: {}", definition);
-
-        // TODO: implement this
-/*
-        // find all String getter/setter
-        Map<String, Object> properties = new HashMap<>();
-        IntrospectionSupport.getProperties(definition, properties, null);
-
-        Map<String, Object> changedProperties = new HashMap<>();
-        if (!properties.isEmpty()) {
-            LOG.trace("There are {} properties on: {}", properties.size(), definition);
-
-            // lookup and resolve known constant fields for String based properties
-            for (Map.Entry<String, Object> entry : properties.entrySet()) {
-                String name = entry.getKey();
-                Object value = entry.getValue();
-                if (value instanceof String) {
-                    // we can only resolve String typed values
-                    String text = (String) value;
-
-                    // is the value a known field (currently we only support constants from Exchange.class)
-                    if (text.startsWith("Exchange.")) {
-                        String field = StringHelper.after(text, "Exchange.");
-                        String constant = ObjectHelper.lookupConstantFieldValue(Exchange.class, field);
-                        if (constant != null) {
-                            // invoke setter as the text has changed
-                            IntrospectionSupport.setProperty(camelContext, definition, name, constant);
-                            changedProperties.put(name, value);
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("Changed property [{}] from: {} to: {}", name, value, constant);
-                            }
-                        } else {
-                            throw new IllegalArgumentException("Constant field with name: " + field + " not found on Exchange.class");
-                        }
-                    }
-                }
-            }
-        }
-        addRestoreAction(camelContext, definition, changedProperties);*/
-    }
-
 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/reifier/ChoiceReifier.java b/core/camel-core/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
index e8b8461..8524fa9 100644
--- a/core/camel-core/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
+++ b/core/camel-core/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
@@ -66,9 +66,6 @@ public class ChoiceReifier extends ProcessorReifier<ChoiceDefinition> {
             if (exp != null) {
                 // resolve properties before we create the processor
                 ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), exp);
-
-                // resolve constant fields (eg Exchange.FILE_NAME)
-                ProcessorDefinitionHelper.resolveKnownConstantFields(routeContext.getCamelContext(), exp);
             }
 
             FilterProcessor filter = (FilterProcessor) createProcessor(routeContext, whenClause);
diff --git a/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java b/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
index 8f4a253..460443e 100644
--- a/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
+++ b/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
@@ -446,9 +446,6 @@ public abstract class ProcessorReifier<T extends ProcessorDefinition<?>> {
             // resolve properties before we create the processor
             ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), output);
 
-            // resolve constant fields (eg Exchange.FILE_NAME)
-            ProcessorDefinitionHelper.resolveKnownConstantFields(routeContext.getCamelContext(), output);
-
             // also resolve properties and constant fields on embedded expressions
             ProcessorDefinition<?> me = (ProcessorDefinition<?>) output;
             if (me instanceof ExpressionNode) {
@@ -457,9 +454,6 @@ public abstract class ProcessorReifier<T extends ProcessorDefinition<?>> {
                 if (expressionDefinition != null) {
                     // resolve properties before we create the processor
                     ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), expressionDefinition);
-
-                    // resolve constant fields (eg Exchange.FILE_NAME)
-                    ProcessorDefinitionHelper.resolveKnownConstantFields(routeContext.getCamelContext(), expressionDefinition);
                 }
             }
 
@@ -529,9 +523,6 @@ public abstract class ProcessorReifier<T extends ProcessorDefinition<?>> {
         // resolve properties before we create the processor
         ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), definition);
 
-        // resolve constant fields (eg Exchange.FILE_NAME)
-        ProcessorDefinitionHelper.resolveKnownConstantFields(routeContext.getCamelContext(), definition);
-
         // also resolve properties and constant fields on embedded expressions
         ProcessorDefinition<?> me = definition;
         if (me instanceof ExpressionNode) {
@@ -540,9 +531,6 @@ public abstract class ProcessorReifier<T extends ProcessorDefinition<?>> {
             if (expressionDefinition != null) {
                 // resolve properties before we create the processor
                 ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), expressionDefinition);
-
-                // resolve constant fields (eg Exchange.FILE_NAME)
-                ProcessorDefinitionHelper.resolveKnownConstantFields(routeContext.getCamelContext(), expressionDefinition);
             }
         }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/RouteWithConstantFieldFromExchangeFailTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/RouteWithConstantFieldFromExchangeFailTest.java
index 669aeef..fed484d 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/RouteWithConstantFieldFromExchangeFailTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/RouteWithConstantFieldFromExchangeFailTest.java
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 package org.apache.camel.processor;
+
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.junit.Before;


[camel] 06/09: Regen

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 758ff0bd195aed22ad653be27836e3cd9caf3b9c
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 13 05:36:37 2019 +0200

    Regen
---
 components/camel-atmos/src/main/docs/atmos-component.adoc |  2 +-
 docs/components/modules/ROOT/pages/atmos-component.adoc   | 12 ++++++------
 docs/components/modules/ROOT/pages/xmpp-component.adoc    |  3 ++-
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/components/camel-atmos/src/main/docs/atmos-component.adoc b/components/camel-atmos/src/main/docs/atmos-component.adoc
index cf38b30..f145b79 100644
--- a/components/camel-atmos/src/main/docs/atmos-component.adoc
+++ b/components/camel-atmos/src/main/docs/atmos-component.adoc
@@ -103,7 +103,7 @@ The component supports 7 options, which are listed below.
 | *camel.component.atmos.enabled* | Enable atmos component | true | Boolean
 | *camel.component.atmos.full-token-id* | The token id to pass to the Atmos client |  | String
 | *camel.component.atmos.resolve-property-placeholders* | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | Boolean
-| *camel.component.atmos.secret-key* | The secret key to pass to the Atmos client |  | String
+| *camel.component.atmos.secret-key* | The secret key to pass to the Atmos client (should be base64 encoded) |  | String
 | *camel.component.atmos.ssl-validation* | Whether the Atmos client should perform SSL validation | false | Boolean
 | *camel.component.atmos.uri* | The URI of the server for the Atmos client to connect to |  | String
 |===
diff --git a/docs/components/modules/ROOT/pages/atmos-component.adoc b/docs/components/modules/ROOT/pages/atmos-component.adoc
index 6593aef..f145b79 100644
--- a/docs/components/modules/ROOT/pages/atmos-component.adoc
+++ b/docs/components/modules/ROOT/pages/atmos-component.adoc
@@ -24,7 +24,7 @@ The Atmos component supports 6 options, which are listed below.
 |===
 | Name | Description | Default | Type
 | *fullTokenId* (security) | The token id to pass to the Atmos client |  | String
-| *secretKey* (security) | The secret key to pass to the Atmos client |  | String
+| *secretKey* (security) | The secret key to pass to the Atmos client (should be base64 encoded) |  | String
 | *uri* (advanced) | The URI of the server for the Atmos client to connect to |  | String
 | *sslValidation* (security) | Whether the Atmos client should perform SSL validation | false | boolean
 | *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
@@ -60,20 +60,20 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *enableSslValidation* (common) | Atmos SSL validation | false | boolean
-| *fullTokenId* (common) | Atmos client fullTokenId |  | String
 | *localPath* (common) | Local path to put files |  | String
 | *newRemotePath* (common) | New path on Atmos when moving files |  | String
 | *query* (common) | Search query on Atmos |  | String
 | *remotePath* (common) | Where to put files on Atmos |  | String
-| *secretKey* (common) | Atmos shared secret |  | String
-| *uri* (common) | Atomos server uri |  | String
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. |  | ExchangePattern
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
 | *basicPropertyBinding* (advanced) | Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
+| *uri* (advanced) | Atomos server uri |  | String
+| *fullTokenId* (security) | Atmos client fullTokenId |  | String
+| *secretKey* (security) | The secret key to pass to the Atmos client (should be base64 encoded) |  | String
+| *sslValidation* (security) | Atmos SSL validation | false | boolean
 |===
 // endpoint options: END
 // spring-boot-auto-configure options: START
@@ -103,7 +103,7 @@ The component supports 7 options, which are listed below.
 | *camel.component.atmos.enabled* | Enable atmos component | true | Boolean
 | *camel.component.atmos.full-token-id* | The token id to pass to the Atmos client |  | String
 | *camel.component.atmos.resolve-property-placeholders* | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | Boolean
-| *camel.component.atmos.secret-key* | The secret key to pass to the Atmos client |  | String
+| *camel.component.atmos.secret-key* | The secret key to pass to the Atmos client (should be base64 encoded) |  | String
 | *camel.component.atmos.ssl-validation* | Whether the Atmos client should perform SSL validation | false | Boolean
 | *camel.component.atmos.uri* | The URI of the server for the Atmos client to connect to |  | String
 |===
diff --git a/docs/components/modules/ROOT/pages/xmpp-component.adoc b/docs/components/modules/ROOT/pages/xmpp-component.adoc
index b2b0e8a..895ec9d 100644
--- a/docs/components/modules/ROOT/pages/xmpp-component.adoc
+++ b/docs/components/modules/ROOT/pages/xmpp-component.adoc
@@ -73,7 +73,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (20 parameters):
+=== Query Parameters (21 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -98,6 +98,7 @@ with the following path and query parameters:
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
 | *headerFilterStrategy* (filter) | To use a custom HeaderFilterStrategy to filter header to and from Camel message. |  | HeaderFilterStrategy
 | *password* (security) | Password for login |  | String
+| *roomPassword* (security) | Password for room |  | String
 | *user* (security) | User name (without server name). If not specified, anonymous login will be attempted. |  | String
 |===
 // endpoint options: END