package net.bytebuddy.implementation.bind.annotation; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.test.utility.JavaVersionRule; import net.bytebuddy.test.utility.ObjectPropertyAssertion; import net.bytebuddy.utility.JavaConstant; import net.bytebuddy.utility.JavaType; import org.junit.Rule; import org.junit.Test; import org.junit.rules.MethodRule; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Iterator; import static net.bytebuddy.matcher.ElementMatchers.named; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; public class TargetMethodAnnotationDriverBinderParameterBinderForFixedValueOfConstantOtherTest { private static final String FOO = "foo"; @Rule public MethodRule javaVersionRule = new JavaVersionRule(); @Test public void testTypeDescription() throws Exception { assertThat(new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, TypeDescription.OBJECT)) .to(Foo.class)) .make() .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo(), is((Object) Object.class)); } @Test public void testNull() throws Exception { assertThat(new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, null)) .to(Foo.class)) .make() .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo(), nullValue(Object.class)); } @Test @JavaVersionRule.Enforce(7) public void testMethodHandleLoaded() throws Exception { Method publicLookup = Class.forName("java.lang.invoke.MethodHandles").getDeclaredMethod("publicLookup"); Object lookup = publicLookup.invoke(null); Method unreflected = Class.forName("java.lang.invoke.MethodHandles$Lookup").getDeclaredMethod("unreflect", Method.class); Object methodHandleLoaded = unreflected.invoke(lookup, Foo.class.getDeclaredMethod(FOO)); assertThat(JavaConstant.MethodHandle.ofLoaded(new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, methodHandleLoaded)) .to(Foo.class)) .make() .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo()), is(JavaConstant.MethodHandle.ofLoaded(methodHandleLoaded))); } @Test @JavaVersionRule.Enforce(7) public void testMethodHandle() throws Exception { Method publicLookup = Class.forName("java.lang.invoke.MethodHandles").getDeclaredMethod("publicLookup"); Object lookup = publicLookup.invoke(null); Method unreflected = Class.forName("java.lang.invoke.MethodHandles$Lookup").getDeclaredMethod("unreflect", Method.class); Object methodHandleLoaded = unreflected.invoke(lookup, Foo.class.getDeclaredMethod(FOO)); assertThat(JavaConstant.MethodHandle.ofLoaded(new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, JavaConstant.MethodHandle.ofLoaded(methodHandleLoaded))) .to(Foo.class)) .make() .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo()), is(JavaConstant.MethodHandle.ofLoaded(methodHandleLoaded))); } @Test @JavaVersionRule.Enforce(7) public void testMethodTypeLoaded() throws Exception { Object loadedMethodType = JavaType.METHOD_TYPE.load().getDeclaredMethod("methodType", Class.class, Class[].class) .invoke(null, void.class, new Class<?>[]{Object.class}); assertThat(JavaConstant.MethodType.ofLoaded(new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, loadedMethodType)) .to(Foo.class)) .make() .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo()), is(JavaConstant.MethodType.ofLoaded(loadedMethodType))); } @Test @JavaVersionRule.Enforce(7) public void testMethodType() throws Exception { Object loadedMethodType = JavaType.METHOD_TYPE.load().getDeclaredMethod("methodType", Class.class, Class[].class) .invoke(null, void.class, new Class<?>[]{Object.class}); assertThat(JavaConstant.MethodType.ofLoaded(new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, JavaConstant.MethodType.ofLoaded(loadedMethodType))) .to(Foo.class)) .make() .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo()), is(JavaConstant.MethodType.ofLoaded(loadedMethodType))); } @Test(expected = IllegalStateException.class) public void testIllegalArgument() throws Exception { new ByteBuddy() .subclass(Foo.class) .method(named(FOO)) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of(Bar.class, new Object())) .to(Foo.class)) .make(); } @Test public void testObjectProperties() throws Exception { final Iterator<Class<?>> iterator = Arrays.<Class<?>>asList(Object.class, String.class, int.class, float.class).iterator(); ObjectPropertyAssertion.of(TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.class).create(new ObjectPropertyAssertion.Creator<Class<?>>() { @Override public Class<?> create() { return iterator.next(); } }).apply(); } public static class Foo { public static Object intercept(@Bar Object value) { return value; } public Object foo() { throw new AssertionError(); } } @Retention(RetentionPolicy.RUNTIME) public @interface Bar { /* empty */ } }