You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2017/05/23 14:23:42 UTC

[4/6] brooklyn-server git commit: MethodCoercions: add more utility methods

MethodCoercions: add more utility methods


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/8a832de5
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/8a832de5
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/8a832de5

Branch: refs/heads/master
Commit: 8a832de59c513d81c4e8c97e723fc03f0aadf26a
Parents: b945fdc
Author: Aled Sage <al...@gmail.com>
Authored: Mon May 22 18:09:15 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue May 23 14:45:33 2017 +0100

----------------------------------------------------------------------
 .../util/core/flags/MethodCoercions.java        | 84 +++++++++++++++-----
 .../util/core/flags/MethodCoercionsTest.java    | 83 ++++++++++++++-----
 2 files changed, 125 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8a832de5/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java b/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
index a243581..b0afcdd 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
@@ -18,15 +18,7 @@
  */
 package org.apache.brooklyn.util.core.flags;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -34,7 +26,16 @@ import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.List;
 
-import static com.google.common.base.Preconditions.checkNotNull;
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
 
 /**
  * A way of binding a loosely-specified method call into a strongly-typed Java method call.
@@ -93,7 +94,7 @@ public class MethodCoercions {
             return Maybe.absent();
         }
     }
-
+    
     /**
      * Returns a predicate that matches a method with the given name, and parameters that
      * {@link org.apache.brooklyn.util.core.flags.TypeCoercions#tryCoerce(Object, com.google.common.reflect.TypeToken)} can process
@@ -104,21 +105,48 @@ public class MethodCoercions {
      * @return a predicate that will match a compatible method
      */
     public static Predicate<Method> matchMultiParameterMethod(final String methodName, final List<?> arguments) {
+        return Predicates.and(matchMethodByName(methodName), matchMultiParameterMethod(arguments));
+    }
+
+    /**
+     * Returns a predicate that matches a method with the given name.
+     *
+     * @param methodName name of the method
+     * @return a predicate that will match a compatible method
+     */
+    public static Predicate<Method> matchMethodByName(final String methodName) {
         checkNotNull(methodName, "methodName");
+
+        return new Predicate<Method>() {
+            @Override
+            public boolean apply(@Nullable Method input) {
+                return (input != null) && input.getName().equals(methodName);
+            }
+        };
+    }
+
+    /**
+     * Returns a predicate that matches a method with parameters that
+     * {@link org.apache.brooklyn.util.core.flags.TypeCoercions#tryCoerce(Object, com.google.common.reflect.TypeToken)} can process
+     * from the given list of arguments.
+     *
+     * @param arguments arguments that is intended to be given
+     * @return a predicate that will match a compatible method
+     */
+    public static Predicate<Method> matchMultiParameterMethod(final List<?> arguments) {
         checkNotNull(arguments, "arguments");
 
         return new Predicate<Method>() {
             @Override
             public boolean apply(@Nullable Method input) {
                 if (input == null) return false;
-                if (!input.getName().equals(methodName)) return false;
                 int numOptionParams = arguments.size();
                 Type[] parameterTypes = input.getGenericParameterTypes();
                 if (parameterTypes.length != numOptionParams) return false;
 
                 for (int paramCount = 0; paramCount < numOptionParams; paramCount++) {
                     if (!TypeCoercions.tryCoerce(((List<?>) arguments).get(paramCount),
-                            TypeToken.of(parameterTypes[paramCount])).isPresentAndNonNull()) return false;
+                            TypeToken.of(parameterTypes[paramCount])).isPresent()) return false;
                 }
                 return true;
             }
@@ -129,15 +157,13 @@ public class MethodCoercions {
      * Tries to find a multiple-parameter method with each parameter compatible with (can be coerced to) the
      * corresponding argument, and invokes it.
      *
-     * @param instance the object to invoke the method on
-     * @param methodName the name of the method to invoke
+     * @param instanceOrClazz the object or class to invoke the method on
+     * @param methods the methods to choose from
      * @param argument a list of the arguments to the method's parameters.
      * @return the result of the method call, or {@link org.apache.brooklyn.util.guava.Maybe#absent()} if method could not be matched.
      */
-    public static Maybe<?> tryFindAndInvokeMultiParameterMethod(final Object instance, final String methodName, final List<?> arguments) {
-        Class<?> clazz = instance.getClass();
-        Iterable<Method> methods = Arrays.asList(clazz.getMethods());
-        Optional<Method> matchingMethod = Iterables.tryFind(methods, matchMultiParameterMethod(methodName, arguments));
+    public static Maybe<?> tryFindAndInvokeMultiParameterMethod(Object instanceOrClazz, Iterable<Method> methods, List<?> arguments) {
+        Optional<Method> matchingMethod = Iterables.tryFind(methods, matchMultiParameterMethod(arguments));
         if (matchingMethod.isPresent()) {
             Method method = matchingMethod.get();
             try {
@@ -148,7 +174,7 @@ public class MethodCoercions {
                     Type paramType = method.getGenericParameterTypes()[paramCount];
                     coercedArguments[paramCount] = TypeCoercions.coerce(argument, TypeToken.of(paramType));
                 }
-                return Maybe.of(method.invoke(instance, coercedArguments));
+                return Maybe.of(method.invoke(instanceOrClazz, coercedArguments));
             } catch (IllegalAccessException | InvocationTargetException e) {
                 throw Exceptions.propagate(e);
             }
@@ -156,6 +182,21 @@ public class MethodCoercions {
             return Maybe.absent();
         }
     }
+    
+    /**
+     * Tries to find a multiple-parameter method with each parameter compatible with (can be coerced to) the
+     * corresponding argument, and invokes it.
+     *
+     * @param instance the object to invoke the method on
+     * @param methodName the name of the method to invoke
+     * @param argument a list of the arguments to the method's parameters.
+     * @return the result of the method call, or {@link org.apache.brooklyn.util.guava.Maybe#absent()} if method could not be matched.
+     */
+    public static Maybe<?> tryFindAndInvokeMultiParameterMethod(Object instance, String methodName, List<?> arguments) {
+        Class<?> clazz = instance.getClass();
+        Iterable<Method> methods = Iterables.filter(Arrays.asList(clazz.getMethods()), matchMethodByName(methodName));
+        return tryFindAndInvokeMultiParameterMethod(instance, methods, arguments);
+    }
 
     /**
      * Tries to find a method with each parameter compatible with (can be coerced to) the corresponding argument, and invokes it.
@@ -165,7 +206,7 @@ public class MethodCoercions {
      * @param argument a list of the arguments to the method's parameters, or a single argument for a single-parameter method.
      * @return the result of the method call, or {@link org.apache.brooklyn.util.guava.Maybe#absent()} if method could not be matched.
      */
-    public static Maybe<?> tryFindAndInvokeBestMatchingMethod(final Object instance, final String methodName, final Object argument) {
+    public static Maybe<?> tryFindAndInvokeBestMatchingMethod(Object instance, String methodName, Object argument) {
         if (argument instanceof List) {
             List<?> arguments = (List<?>) argument;
 
@@ -181,5 +222,4 @@ public class MethodCoercions {
             return tryFindAndInvokeSingleParameterMethod(instance, methodName, argument);
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8a832de5/core/src/test/java/org/apache/brooklyn/util/core/flags/MethodCoercionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/flags/MethodCoercionsTest.java b/core/src/test/java/org/apache/brooklyn/util/core/flags/MethodCoercionsTest.java
index e48d2b6..57adb54 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/flags/MethodCoercionsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/flags/MethodCoercionsTest.java
@@ -18,22 +18,23 @@
  */
 package org.apache.brooklyn.util.core.flags;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.List;
 
-import org.apache.brooklyn.util.core.flags.MethodCoercions;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.lang.reflect.Method;
-import java.util.List;
-
-import static org.testng.Assert.*;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
 
 public class MethodCoercionsTest {
 
+    private Method staticMultiParameterMethod;
     private Method singleParameterMethod;
     private Method multiParameterMethod;
     private Method singleCollectionParameterMethod;
@@ -41,6 +42,7 @@ public class MethodCoercionsTest {
     @BeforeClass
     public void testFixtureSetUp() {
         try {
+            staticMultiParameterMethod = TestClass.class.getMethod("staticMultiParameterMethod", boolean.class, int.class);
             singleParameterMethod = TestClass.class.getMethod("singleParameterMethod", int.class);
             multiParameterMethod = TestClass.class.getMethod("multiParameterMethod", boolean.class, int.class);
             singleCollectionParameterMethod = TestClass.class.getMethod("singleCollectionParameterMethod", List.class);
@@ -58,11 +60,19 @@ public class MethodCoercionsTest {
     }
 
     @Test
-    public void testTryFindAndInvokeSingleParameterMethod() throws Exception {
-        TestClass instance = new TestClass();
-        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleParameterMethod(instance, "singleParameterMethod", "42");
-        assertTrue(maybe.isPresent());
-        assertTrue(instance.wasSingleParameterMethodCalled());
+    public void testMatchSingleCollectionParameterMethod() throws Exception {
+        Predicate<Method> predicate = MethodCoercions.matchSingleParameterMethod("singleCollectionParameterMethod", ImmutableList.of("42"));
+        assertFalse(predicate.apply(singleParameterMethod));
+        assertFalse(predicate.apply(multiParameterMethod));
+        assertTrue(predicate.apply(singleCollectionParameterMethod));
+    }
+
+    @Test
+    public void testMatchMethodByName() throws Exception {
+        Predicate<Method> predicate = MethodCoercions.matchMethodByName("singleParameterMethod");
+        assertTrue(predicate.apply(singleParameterMethod));
+        assertFalse(predicate.apply(multiParameterMethod));
+        assertFalse(predicate.apply(singleCollectionParameterMethod));
     }
 
     @Test
@@ -74,6 +84,14 @@ public class MethodCoercionsTest {
     }
 
     @Test
+    public void testMatchMultiParameterMethodWithoutName() throws Exception {
+        Predicate<Method> predicate = MethodCoercions.matchMultiParameterMethod(ImmutableList.of("true", "42"));
+        assertFalse(predicate.apply(singleParameterMethod));
+        assertTrue(predicate.apply(multiParameterMethod));
+        assertFalse(predicate.apply(singleCollectionParameterMethod));
+    }
+
+    @Test
     public void testTryFindAndInvokeMultiParameterMethod() throws Exception {
         TestClass instance = new TestClass();
         Maybe<?> maybe = MethodCoercions.tryFindAndInvokeMultiParameterMethod(instance, "multiParameterMethod", ImmutableList.of("true", "42"));
@@ -82,6 +100,17 @@ public class MethodCoercionsTest {
     }
 
     @Test
+    public void testTryFindAndInvokeStaticMultiParameterMethod() throws Exception {
+        try {
+            Maybe<?> maybe = MethodCoercions.tryFindAndInvokeMultiParameterMethod(TestClass.class, ImmutableList.of(staticMultiParameterMethod), ImmutableList.of("true", "42"));
+            assertTrue(maybe.isPresent());
+            assertTrue(TestClass.wasStaticMultiParameterMethodCalled());
+        } finally {
+            TestClass.clear();
+        }
+    }
+
+    @Test
     public void testTryFindAndInvokeBestMatchingMethod() throws Exception {
         TestClass instance = new TestClass();
         Maybe<?> maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "singleParameterMethod", "42");
@@ -98,29 +127,43 @@ public class MethodCoercionsTest {
         assertTrue(maybe.isPresent());
         assertTrue(instance.wasSingleCollectionParameterMethodCalled());
     }
-/*
+
     @Test
-    public void testMatchSingleCollectionParameterMethod() throws Exception {
-        Predicate<Method> predicate = MethodCoercions.matchSingleCollectionParameterMethod("singleCollectionParameterMethod", ImmutableList.of("42"));
-        assertFalse(predicate.apply(singleParameterMethod));
-        assertFalse(predicate.apply(multiParameterMethod));
-        assertTrue(predicate.apply(singleCollectionParameterMethod));
+    public void testTryFindAndInvokeSingleParameterMethod() throws Exception {
+        TestClass instance = new TestClass();
+        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleParameterMethod(instance, "singleParameterMethod", "42");
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasSingleParameterMethodCalled());
     }
 
     @Test
     public void testTryFindAndInvokeSingleCollectionParameterMethod() throws Exception {
         TestClass instance = new TestClass();
-        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleCollectionParameterMethod(instance, "singleCollectionParameterMethod", ImmutableList.of("42"));
+        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleParameterMethod(instance, "singleCollectionParameterMethod", ImmutableList.of("42"));
         assertTrue(maybe.isPresent());
         assertTrue(instance.wasSingleCollectionParameterMethodCalled());
     }
-*/
+
     public static class TestClass {
 
+        private static boolean staticMultiParameterMethodCalled;
+        
         private boolean singleParameterMethodCalled;
         private boolean multiParameterMethodCalled;
         private boolean singleCollectionParameterMethodCalled;
 
+        public static void staticMultiParameterMethod(boolean parameter1, int parameter2) {
+            staticMultiParameterMethodCalled = true;
+        }
+
+        public static boolean wasStaticMultiParameterMethodCalled() {
+            return staticMultiParameterMethodCalled;
+        }
+
+        public static void clear() {
+            staticMultiParameterMethodCalled = false;
+        }
+        
         public void singleParameterMethod(int parameter) {
             singleParameterMethodCalled = true;
         }