1 /* 2 * Copyright (c) 2016 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.creation.bytebuddy; 6 7 import net.bytebuddy.implementation.bind.annotation.AllArguments; 8 import net.bytebuddy.implementation.bind.annotation.Argument; 9 import net.bytebuddy.implementation.bind.annotation.BindingPriority; 10 import net.bytebuddy.implementation.bind.annotation.FieldValue; 11 import net.bytebuddy.implementation.bind.annotation.Origin; 12 import net.bytebuddy.implementation.bind.annotation.RuntimeType; 13 import net.bytebuddy.implementation.bind.annotation.StubValue; 14 import net.bytebuddy.implementation.bind.annotation.SuperCall; 15 import net.bytebuddy.implementation.bind.annotation.This; 16 import org.mockito.internal.debugging.LocationImpl; 17 import org.mockito.internal.invocation.RealMethod; 18 import org.mockito.invocation.Location; 19 import org.mockito.invocation.MockHandler; 20 import org.mockito.mock.MockCreationSettings; 21 22 import java.io.ObjectStreamException; 23 import java.io.Serializable; 24 import java.lang.reflect.Method; 25 import java.util.concurrent.Callable; 26 27 import static org.mockito.internal.invocation.DefaultInvocationFactory.createInvocation; 28 29 public class MockMethodInterceptor implements Serializable { 30 31 private static final long serialVersionUID = 7152947254057253027L; 32 33 final MockHandler handler; 34 35 private final MockCreationSettings mockCreationSettings; 36 37 private final ByteBuddyCrossClassLoaderSerializationSupport serializationSupport; 38 MockMethodInterceptor(MockHandler handler, MockCreationSettings mockCreationSettings)39 public MockMethodInterceptor(MockHandler handler, MockCreationSettings mockCreationSettings) { 40 this.handler = handler; 41 this.mockCreationSettings = mockCreationSettings; 42 serializationSupport = new ByteBuddyCrossClassLoaderSerializationSupport(); 43 } 44 doIntercept(Object mock, Method invokedMethod, Object[] arguments, RealMethod realMethod)45 Object doIntercept(Object mock, 46 Method invokedMethod, 47 Object[] arguments, 48 RealMethod realMethod) throws Throwable { 49 return doIntercept( 50 mock, 51 invokedMethod, 52 arguments, 53 realMethod, 54 new LocationImpl() 55 ); 56 } 57 doIntercept(Object mock, Method invokedMethod, Object[] arguments, RealMethod realMethod, Location location)58 Object doIntercept(Object mock, 59 Method invokedMethod, 60 Object[] arguments, 61 RealMethod realMethod, 62 Location location) throws Throwable { 63 return handler.handle(createInvocation(mock, invokedMethod, arguments, realMethod, mockCreationSettings, location)); 64 } 65 getMockHandler()66 public MockHandler getMockHandler() { 67 return handler; 68 } 69 getSerializationSupport()70 public ByteBuddyCrossClassLoaderSerializationSupport getSerializationSupport() { 71 return serializationSupport; 72 } 73 74 public static class ForHashCode { 75 76 @SuppressWarnings("unused") doIdentityHashCode(@his Object thiz)77 public static int doIdentityHashCode(@This Object thiz) { 78 return System.identityHashCode(thiz); 79 } 80 } 81 82 public static class ForEquals { 83 84 @SuppressWarnings("unused") doIdentityEquals(@his Object thiz, @Argument(0) Object other)85 public static boolean doIdentityEquals(@This Object thiz, @Argument(0) Object other) { 86 return thiz == other; 87 } 88 } 89 90 public static class ForWriteReplace { 91 doWriteReplace(@his MockAccess thiz)92 public static Object doWriteReplace(@This MockAccess thiz) throws ObjectStreamException { 93 return thiz.getMockitoInterceptor().getSerializationSupport().writeReplace(thiz); 94 } 95 } 96 97 public static class DispatcherDefaultingToRealMethod { 98 99 @SuppressWarnings("unused") 100 @RuntimeType 101 @BindingPriority(BindingPriority.DEFAULT * 2) interceptSuperCallable(@his Object mock, @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor, @Origin Method invokedMethod, @AllArguments Object[] arguments, @SuperCall(serializableProxy = true) Callable<?> superCall)102 public static Object interceptSuperCallable(@This Object mock, 103 @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor, 104 @Origin Method invokedMethod, 105 @AllArguments Object[] arguments, 106 @SuperCall(serializableProxy = true) Callable<?> superCall) throws Throwable { 107 if (interceptor == null) { 108 return superCall.call(); 109 } 110 return interceptor.doIntercept( 111 mock, 112 invokedMethod, 113 arguments, 114 new RealMethod.FromCallable(superCall) 115 ); 116 } 117 118 @SuppressWarnings("unused") 119 @RuntimeType interceptAbstract(@his Object mock, @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor, @StubValue Object stubValue, @Origin Method invokedMethod, @AllArguments Object[] arguments)120 public static Object interceptAbstract(@This Object mock, 121 @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor, 122 @StubValue Object stubValue, 123 @Origin Method invokedMethod, 124 @AllArguments Object[] arguments) throws Throwable { 125 if (interceptor == null) { 126 return stubValue; 127 } 128 return interceptor.doIntercept( 129 mock, 130 invokedMethod, 131 arguments, 132 RealMethod.IsIllegal.INSTANCE 133 ); 134 } 135 } 136 } 137