You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2016/07/21 10:01:35 UTC

[5/5] camel git commit: CAMEL-10102: [api-component-framework] api method resolution should not allocate temporary arrays

CAMEL-10102: [api-component-framework] api method resolution should not allocate temporary arrays


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/773e9ee7
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/773e9ee7
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/773e9ee7

Branch: refs/heads/master
Commit: 773e9ee7daef2eef51924bb2cf54734d2a33fc60
Parents: 6a7338b
Author: lburgazzoli <lb...@gmail.com>
Authored: Wed Jun 29 17:35:19 2016 +0200
Committer: lburgazzoli <lb...@gmail.com>
Committed: Thu Jul 21 11:47:40 2016 +0200

----------------------------------------------------------------------
 .../util/component/AbstractApiConsumer.java     | 21 +-------
 .../util/component/AbstractApiEndpoint.java     | 10 ++--
 .../util/component/AbstractApiProducer.java     | 12 +++--
 .../camel/util/component/ApiConsumerHelper.java |  7 +--
 .../camel/util/component/ApiMethodHelper.java   | 55 ++++++++++++++------
 .../util/component/ApiMethodHelperTest.java     | 14 ++---
 .../apache/camel/component/box/BoxConsumer.java | 11 ++--
 7 files changed, 62 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiConsumer.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiConsumer.java b/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiConsumer.java
index dc14855..900fb82 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiConsumer.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiConsumer.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.util.component;
 
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -62,7 +61,7 @@ public abstract class AbstractApiConsumer<E extends Enum<E> & ApiName, T>
     @Override
     protected int poll() throws Exception {
         // invoke the consumer method
-        final Map<String, Object> args = new HashMap<String, Object>();
+        final Map<String, Object> args = new HashMap<>();
         args.putAll(endpoint.getEndpointProperties());
 
         // let the endpoint and the Consumer intercept properties
@@ -102,13 +101,7 @@ public abstract class AbstractApiConsumer<E extends Enum<E> & ApiName, T>
 
     @Override
     public Object splitResult(Object result) {
-        // process result according to type
-        if (splitResult && result != null && (result instanceof Collection || result.getClass().isArray())) {
-            // create an exchange for every element
-            return getResultAsArray(result);
-        } else {
-            return result;
-        }
+        return result;
     }
 
     @Override
@@ -116,16 +109,6 @@ public abstract class AbstractApiConsumer<E extends Enum<E> & ApiName, T>
         // do nothing by default
     }
 
-    private static Object getResultAsArray(Object result) {
-        if (result.getClass().isArray()) {
-            // no conversion needed
-            return result;
-        }
-        // must be a Collection
-        Collection<?> collection = (Collection<?>) result;
-        return collection.toArray(new Object[collection.size()]);
-    }
-
     public final boolean isSplitResult() {
         return splitResult;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiEndpoint.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiEndpoint.java b/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiEndpoint.java
index 89e8e41..ab50d12 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiEndpoint.java
@@ -132,9 +132,7 @@ public abstract class AbstractApiEndpoint<E extends ApiName, T>
         this.endpointProperties = Collections.unmodifiableMap(properties);
 
         // get endpoint property names
-        final Set<String> arguments = new HashSet<String>();
-        arguments.addAll(endpointPropertyNames);
-
+        final Set<String> arguments = new HashSet<>(endpointPropertyNames);
         // add inBody argument for producers
         if (inBody != null) {
             arguments.add(inBody);
@@ -142,11 +140,9 @@ public abstract class AbstractApiEndpoint<E extends ApiName, T>
 
         interceptPropertyNames(arguments);
 
-        final String[] argNames = arguments.toArray(new String[arguments.size()]);
-
         // create a list of candidate methods
-        candidates = new ArrayList<ApiMethod>();
-        candidates.addAll(methodHelper.getCandidateMethods(methodName, argNames));
+        candidates = new ArrayList<>();
+        candidates.addAll(methodHelper.getCandidateMethods(methodName, arguments));
         candidates = Collections.unmodifiableList(candidates);
 
         // error if there are no candidates

http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiProducer.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiProducer.java b/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiProducer.java
index 0a6130f..506b5d0 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiProducer.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/AbstractApiProducer.java
@@ -139,15 +139,17 @@ public abstract class AbstractApiProducer<E extends Enum<E> & ApiName, T>
 
             // filter candidates based on endpoint and exchange properties
             final Set<String> argNames = properties.keySet();
-            final List<ApiMethod> filteredMethods = methodHelper.filterMethods(candidates,
-                    ApiMethodHelper.MatchType.SUPER_SET,
-                    argNames.toArray(new String[argNames.size()]));
+            final List<ApiMethod> filteredMethods = methodHelper.filterMethods(
+                candidates,
+                ApiMethodHelper.MatchType.SUPER_SET,
+                argNames);
 
             // get the method to call
             if (filteredMethods.isEmpty()) {
-                final Set<String> missing = methodHelper.getMissingProperties(endpoint.getMethodName(), argNames);
                 throw new RuntimeCamelException(String.format("Missing properties for %s, need one or more from %s",
-                        endpoint.getMethodName(), missing));
+                    endpoint.getMethodName(),
+                    methodHelper.getMissingProperties(endpoint.getMethodName(), argNames))
+                );
             } else if (filteredMethods.size() == 1) {
                 // found an exact match
                 method = filteredMethods.get(0);

http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/camel-core/src/main/java/org/apache/camel/util/component/ApiConsumerHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/ApiConsumerHelper.java b/camel-core/src/main/java/org/apache/camel/util/component/ApiConsumerHelper.java
index 658ce0c..e298690 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/ApiConsumerHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/ApiConsumerHelper.java
@@ -49,14 +49,11 @@ public final class ApiConsumerHelper {
 
         ApiMethod result;
         // find one that takes the largest subset of endpoint parameters
-        final Set<String> argNames = new HashSet<String>();
-        argNames.addAll(endpoint.getEndpointPropertyNames());
-
+        final Set<String> argNames = new HashSet<>(endpoint.getEndpointPropertyNames());
         propertyNamesInterceptor.interceptPropertyNames(argNames);
 
-        final String[] argNamesArray = argNames.toArray(new String[argNames.size()]);
         List<ApiMethod> filteredMethods = endpoint.methodHelper.filterMethods(
-                endpoint.getCandidates(), ApiMethodHelper.MatchType.SUPER_SET, argNamesArray);
+                endpoint.getCandidates(), ApiMethodHelper.MatchType.SUPER_SET, argNames);
 
         if (filteredMethods.isEmpty()) {
             ApiMethodHelper<? extends ApiMethod> methodHelper = endpoint.getMethodHelper();

http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
index d938f30..3d06e3f 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
@@ -19,7 +19,6 @@ package org.apache.camel.util.component;
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -29,6 +28,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.apache.camel.RuntimeCamelException;
 import org.slf4j.Logger;
@@ -207,32 +207,43 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
      * Note that the args list is a required subset of arguments for returned methods.
      *
      * @param name case sensitive method name or alias to lookup
+     * @return non-null unmodifiable list of methods that take all of the given arguments, empty if there is no match
+     */
+    public List<ApiMethod> getCandidateMethods(String name) {
+        return getCandidateMethods(name, Collections.emptyList());
+    }
+
+    /**
+     * Gets methods that match the given name and arguments.<p/>
+     * Note that the args list is a required subset of arguments for returned methods.
+     *
+     * @param name case sensitive method name or alias to lookup
      * @param argNames unordered required argument names
      * @return non-null unmodifiable list of methods that take all of the given arguments, empty if there is no match
      */
-    public List<ApiMethod> getCandidateMethods(String name, String... argNames) {
+    public List<ApiMethod> getCandidateMethods(String name, Collection<String> argNames) {
         List<T> methods = methodMap.get(name);
         if (methods == null) {
             if (aliasesMap.containsKey(name)) {
-                methods = new ArrayList<T>();
-                for (String method : aliasesMap.get(name)) {
-                    methods.addAll(methodMap.get(method));
-                }
+                methods = aliasesMap.get(name)
+                    .stream()
+                    .map(method -> (T)methodMap.get(method))
+                    .collect(Collectors.toList());
             }
         }
         if (methods == null) {
             LOG.debug("No matching method for method {}", name);
             return Collections.emptyList();
         }
-        int nArgs = argNames != null ? argNames.length : 0;
+        int nArgs = argNames != null ? argNames.size() : 0;
         if (nArgs == 0) {
             LOG.debug("Found {} methods for method {}", methods.size(), name);
-            return Collections.<ApiMethod>unmodifiableList(methods);
+            return Collections.unmodifiableList(methods);
         } else {
             final List<ApiMethod> filteredSet = filterMethods(methods, MatchType.SUBSET, argNames);
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Found {} filtered methods for {}",
-                    filteredSet.size(), name + Arrays.toString(argNames).replace('[', '(').replace(']', ')'));
+                    filteredSet.size(), name + argNames.toString().replace('[', '(').replace(']', ')'));
             }
             return filteredSet;
         }
@@ -243,18 +254,28 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
      *
      * @param methods list of methods to filter
      * @param matchType whether the arguments are an exact match, a subset or a super set of method args
+     * @return methods with arguments that satisfy the match type.<p/>
+     * For SUPER_SET match, if methods with exact match are found, methods that take a subset are ignored
+     */
+    public List<ApiMethod> filterMethods(List<? extends ApiMethod> methods, MatchType matchType) {
+        return filterMethods(methods, matchType, Collections.emptyList());
+    }
+
+    /**
+     * Filters a list of methods to those that take the given set of arguments.
+     *
+     * @param methods list of methods to filter
+     * @param matchType whether the arguments are an exact match, a subset or a super set of method args
      * @param argNames argument names to filter the list
      * @return methods with arguments that satisfy the match type.<p/>
      * For SUPER_SET match, if methods with exact match are found, methods that take a subset are ignored
      */
-    public List<ApiMethod> filterMethods(List<? extends ApiMethod> methods, MatchType matchType,
-                                                          String... argNames) {
+    public List<ApiMethod> filterMethods(List<? extends ApiMethod> methods, MatchType matchType, Collection<String> argNames) {
         // original arguments
-        final List<String> argsList = Arrays.asList(argNames);
         // supplied arguments with missing nullable arguments
         final List<String> withNullableArgsList;
         if (!nullableArguments.isEmpty()) {
-            withNullableArgsList = new ArrayList<String>(argsList);
+            withNullableArgsList = new ArrayList<>(argNames);
             withNullableArgsList.addAll(nullableArguments);
         } else {
             withNullableArgsList = null;
@@ -270,21 +291,21 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
             switch (matchType) {
             case EXACT:
                 // method must take all args, and no more
-                if (methodArgs.containsAll(argsList) && argsList.containsAll(methodArgs)) {
+                if (methodArgs.containsAll(argNames) && argNames.containsAll(methodArgs)) {
                     result.add(method);
                 }
                 break;
             case SUBSET:
                 // all args are required, method may take more
-                if (methodArgs.containsAll(argsList)) {
+                if (methodArgs.containsAll(argNames)) {
                     result.add(method);
                 }
                 break;
             default:
             case SUPER_SET:
                 // all method args must be present
-                if (argsList.containsAll(methodArgs)) {
-                    if (methodArgs.containsAll(argsList)) {
+                if (argNames.containsAll(methodArgs)) {
+                    if (methodArgs.containsAll(argNames)) {
                         // prefer exact match to avoid unused args
                         result.add(method);
                     } else {

http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java b/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
index 574c9d4..8913e33 100644
--- a/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
@@ -49,19 +49,19 @@ public class ApiMethodHelperTest {
         methods = apiMethodHelper.getCandidateMethods("hi");
         assertEquals("Can't find sayHi(name)", 2, methods.size());
 
-        methods = apiMethodHelper.getCandidateMethods("hi", "name");
+        methods = apiMethodHelper.getCandidateMethods("hi", Arrays.asList("name"));
         assertEquals("Can't find sayHi(name)", 1, methods.size());
 
         methods = apiMethodHelper.getCandidateMethods("greetMe");
         assertEquals("Can't find greetMe(name)", 1, methods.size());
 
-        methods = apiMethodHelper.getCandidateMethods("greetUs", "name1");
+        methods = apiMethodHelper.getCandidateMethods("greetUs", Arrays.asList("name1"));
         assertEquals("Can't find greetUs(name1, name2)", 1, methods.size());
 
-        methods = apiMethodHelper.getCandidateMethods("greetAll", "nameMap");
+        methods = apiMethodHelper.getCandidateMethods("greetAll", Arrays.asList("nameMap"));
         assertEquals("Can't find greetAll(nameMap)", 1, methods.size());
 
-        methods = apiMethodHelper.getCandidateMethods("greetInnerChild", "child");
+        methods = apiMethodHelper.getCandidateMethods("greetInnerChild", Arrays.asList("child"));
         assertEquals("Can't find greetInnerChild(child)", 1, methods.size());
     }
 
@@ -74,15 +74,15 @@ public class ApiMethodHelperTest {
         methods = apiMethodHelper.filterMethods(Arrays.asList(sayHis), ApiMethodHelper.MatchType.SUBSET);
         assertEquals("Subset match failed for sayHi(*)", 2, methods.size());
 
-        methods = apiMethodHelper.filterMethods(Arrays.asList(sayHis), ApiMethodHelper.MatchType.SUBSET, "name");
+        methods = apiMethodHelper.filterMethods(Arrays.asList(sayHis), ApiMethodHelper.MatchType.SUBSET, Arrays.asList("name"));
         assertEquals("Subset match failed for sayHi(name)", 1, methods.size());
         assertEquals("Exact match failed for sayHi()", TestMethod.SAYHI_1, methods.get(0));
 
-        methods = apiMethodHelper.filterMethods(Arrays.asList(sayHis), ApiMethodHelper.MatchType.SUPER_SET, "name");
+        methods = apiMethodHelper.filterMethods(Arrays.asList(sayHis), ApiMethodHelper.MatchType.SUPER_SET, Arrays.asList("name"));
         assertEquals("Super set match failed for sayHi(name)", 1, methods.size());
         assertEquals("Exact match failed for sayHi()", TestMethod.SAYHI_1, methods.get(0));
 
-        methods = apiMethodHelper.filterMethods(Arrays.asList(TestMethod.values()), ApiMethodHelper.MatchType.SUPER_SET, "name");
+        methods = apiMethodHelper.filterMethods(Arrays.asList(TestMethod.values()), ApiMethodHelper.MatchType.SUPER_SET, Arrays.asList("name"));
         assertEquals("Super set match failed for sayHi(name)", 2, methods.size());
 
         // test nullable names

http://git-wip-us.apache.org/repos/asf/camel/blob/773e9ee7/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConsumer.java b/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConsumer.java
index 6b6fabf..7868d70 100644
--- a/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConsumer.java
+++ b/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConsumer.java
@@ -16,13 +16,11 @@
  */
 package org.apache.camel.component.box;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
 import com.box.boxjavalibv2.dao.BoxEventCollection;
-import com.box.boxjavalibv2.dao.BoxTypedObject;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.component.box.internal.BoxConstants;
@@ -109,12 +107,9 @@ public class BoxConsumer extends DefaultConsumer
 
     @Override
     public Object splitResult(Object result) {
-        if (result instanceof BoxEventCollection && splitResult) {
-            BoxEventCollection eventCollection = (BoxEventCollection) result;
-            final ArrayList<BoxTypedObject> entries = eventCollection.getEntries();
-            return entries.toArray(new BoxTypedObject[entries.size()]);
-        }
-        return result;
+        return (result instanceof BoxEventCollection && splitResult)
+            ? ((BoxEventCollection) result).getEntries()
+            : result;
     }
 
     @Override