MethodCoercions { 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(); Method accessibleMethod = Reflections.findAccessibleMethod(method).get(); try { int numOptionParams = ((List<?>)arguments).size(); Object[] coercedArguments = new Object[numOptionParams]; for (int paramCount = 0; paramCount < numOptionParams; paramCount++) { Object argument = arguments.get(paramCount); Type paramType = method.getGenericParameterTypes()[paramCount]; Maybe<?> coercedArgumentM = TypeCoercions.tryCoerce(argument, TypeToken.of(paramType)); RuntimeException exception = Maybe.getException(coercedArgumentM); if (coercedArgumentM.isPresent() && coercedArgumentM.get()!=null) { if (!Boxing.boxedTypeToken(paramType).getRawType().isAssignableFrom(coercedArgumentM.get().getClass())) { exception = new IllegalArgumentException("Type mismatch after coercion; "+coercedArgumentM.get()+" is not a "+TypeToken.of(paramType)); } } if (coercedArgumentM.isAbsent() || exception!=null) { return Maybe.absent("Cannot convert parameter "+(paramCount+1)+" for "+method+": "+ Exceptions.collapseText(Maybe.getException(coercedArgumentM)), exception); } coercedArguments[paramCount] = coercedArgumentM.get(); } return Maybe.of(accessibleMethod.invoke(instanceOrClazz, coercedArguments)); } catch (IllegalAccessException | InvocationTargetException e) { throw Exceptions.propagate(e); } } else { return Maybe.absent(); } }  static Predicate<Method> matchSingleParameterMethod(final String methodName, final Object argument); static Maybe<?> tryFindAndInvokeSingleParameterMethod(final Object instance, final String methodName, final Object argument); static Predicate<Method> matchMultiParameterMethod(final String methodName, final List<?> arguments); static Predicate<Method> matchMethodByName(final String methodName); static Predicate<Method> matchMultiParameterMethod(final List<?> arguments); static Maybe<?> tryFindAndInvokeMultiParameterMethod(Object instanceOrClazz, Iterable<Method> methods, List<?> arguments); static Maybe<?> tryFindAndInvokeMultiParameterMethod(Object instance, String methodName, List<?> arguments); static Maybe<?> tryFindAndInvokeBestMatchingMethod(Object instance, String methodName, Object argument);  }
@Test public void testTryFindAndInvokeMultiParameterMethod() throws Exception { TestClass instance = new TestClass(); Maybe<?> maybe = MethodCoercions.tryFindAndInvokeMultiParameterMethod(instance, "multiParameterMethod", ImmutableList.of("true", "42")); assertTrue(maybe.isPresent()); assertTrue(instance.wasMultiParameterMethodCalled()); }
@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(); } }