Skip to content

Commit

Permalink
Added convenience methods for finding methods
Browse files Browse the repository at this point in the history
  • Loading branch information
bbottema committed May 8, 2019
1 parent 214a120 commit 7949cc3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
18 changes: 18 additions & 0 deletions src/main/java/org/bbottema/javareflection/MethodUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,14 @@ public static Set<InvokableObject<Method>> findSimpleCompatibleMethod(final Clas
}
}

/**
* Delegates to {@link #findCompatibleMethod(Class, String, Set, Class[])}, with the types of the given arguments extracted using {@link TypeUtils#collectTypes(Object[])}.
*/
public static Set<InvokableObject<Method>> findCompatibleMethod(final Class<?> datatype, final String methodName, final Set<LookupMode> lookupMode,
final Object... args) throws NoSuchMethodException {
return findCompatibleMethod(datatype, methodName, lookupMode, TypeUtils.collectTypes(args));
}

/**
* Same as <code>getConstructor()</code>, except for getting a {@link Method} of a classtype, using the name to indicate which method should be
* located.
Expand Down Expand Up @@ -543,4 +551,14 @@ public static boolean methodHasCollectionParameter(final Method m) {
}
return false;
}

public static Method onlyMethod(Set<InvokableObject<Method>> methods) {
if (methods.size() == 0) {
return null;
} else if (methods.size() == 1) {
return methods.iterator().next().getMethod();
} else {
throw new AssertionError("Expected 1 or less methods, but found more than 1 methods: " + methods);
}
}
}
20 changes: 9 additions & 11 deletions src/test/java/org/bbottema/javareflection/MethodUtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package org.bbottema.javareflection;

import lombok.AllArgsConstructor;
import org.bbottema.javareflection.model.InvokableObject;
import org.bbottema.javareflection.model.LookupMode;
import org.bbottema.javareflection.model.MethodModifier;
import org.bbottema.javareflection.model.MethodParameter;
import org.bbottema.javareflection.testmodel.*;
import org.bbottema.javareflection.util.MetaAnnotationExtractor;
import org.bbottema.javareflection.valueconverter.ValueConversionHelper;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
Expand All @@ -30,6 +27,7 @@
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.util.Lists.newArrayList;
import static org.bbottema.javareflection.ClassUtils.collectMethodsByName;
import static org.bbottema.javareflection.MethodUtils.onlyMethod;
import static org.bbottema.javareflection.model.MethodModifier.MATCH_ANY;

public class MethodUtilsTest {
Expand All @@ -47,19 +45,19 @@ public void testFindCompatibleMethod()
allButSmartLookup.remove(LookupMode.SMART_CONVERT);

Set<InvokableObject<Method>> m = MethodUtils.findCompatibleMethod(B.class, "foo", allButSmartLookup, double.class, Pear.class, String.class);
assertThat(m).isNotEmpty();
assertThat(m.iterator().next().getMethod()).isEqualTo(Foo.class.getMethod("foo", Double.class, Fruit.class, char.class));
assertThat(m).hasSize(1);
assertThat(onlyMethod(m)).isEqualTo(Foo.class.getMethod("foo", Double.class, Fruit.class, char.class));
Set<InvokableObject<Method>> m2 = MethodUtils.findCompatibleMethod(B.class, "foo", allButSmartLookup, double.class, Pear.class, String.class);
assertThat(m2).isNotEmpty();
assertThat(m2).hasSize(1);
assertThat(m2).isEqualTo(m);
// find the same method, but now the first implementation on C should be returned
m = MethodUtils.findCompatibleMethod(C.class, "foo", allButSmartLookup, double.class, Pear.class, String.class);
assertThat(m).isNotEmpty();
assertThat(m.iterator().next().getMethod()).isEqualTo(C.class.getMethod("foo", Double.class, Fruit.class, char.class));
assertThat(m).hasSize(1);
assertThat(onlyMethod(m)).isEqualTo(C.class.getMethod("foo", Double.class, Fruit.class, char.class));
// find a String method
m = MethodUtils.findCompatibleMethod(String.class, "concat", EnumSet.noneOf(LookupMode.class), String.class);
assertThat(m).isNotEmpty();
assertThat(m.iterator().next().getMethod()).isEqualTo(String.class.getMethod("concat", String.class));
assertThat(m).hasSize(1);
assertThat(onlyMethod(m)).isEqualTo(String.class.getMethod("concat", String.class));
// shouldn't be able to find the following methods
try {
MethodUtils.findCompatibleMethod(B.class, "foos", allButSmartLookup, double.class, Pear.class, String.class);
Expand All @@ -80,7 +78,7 @@ public void testFindCompatibleMethod()
// OK
}
Set<InvokableObject<Method>> result = MethodUtils.findCompatibleMethod(B.class, "foo", LookupMode.FULL, double.class, Fruit.class, Math.class);
assertThat(result).isNotEmpty();
assertThat(result).hasSize(1);
}

@Test
Expand Down

0 comments on commit 7949cc3

Please sign in to comment.