Home | History | Annotate | Download | only in bytebuddy
      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.*;
      8 import org.mockito.internal.InternalMockHandler;
      9 import org.mockito.internal.creation.DelegatingMethod;
     10 import org.mockito.internal.invocation.MockitoMethod;
     11 import org.mockito.internal.invocation.SerializableMethod;
     12 import org.mockito.internal.progress.SequenceNumber;
     13 import org.mockito.invocation.MockHandler;
     14 import org.mockito.mock.MockCreationSettings;
     15 
     16 import java.io.ObjectStreamException;
     17 import java.io.Serializable;
     18 import java.lang.reflect.Method;
     19 import java.util.concurrent.Callable;
     20 
     21 public class MockMethodInterceptor implements Serializable {
     22 
     23     private static final long serialVersionUID = 7152947254057253027L;
     24 
     25     final InternalMockHandler handler;
     26 
     27     private final MockCreationSettings mockCreationSettings;
     28 
     29     private final ByteBuddyCrossClassLoaderSerializationSupport serializationSupport;
     30 
     31     public MockMethodInterceptor(InternalMockHandler handler, MockCreationSettings mockCreationSettings) {
     32         this.handler = handler;
     33         this.mockCreationSettings = mockCreationSettings;
     34         serializationSupport = new ByteBuddyCrossClassLoaderSerializationSupport();
     35     }
     36 
     37     Object doIntercept(Object mock,
     38                        Method invokedMethod,
     39                        Object[] arguments,
     40                        InterceptedInvocation.SuperMethod superMethod) throws Throwable {
     41         return handler.handle(new InterceptedInvocation(
     42                 mock,
     43                 createMockitoMethod(invokedMethod),
     44                 arguments,
     45                 superMethod,
     46                 SequenceNumber.next()
     47         ));
     48     }
     49 
     50     private MockitoMethod createMockitoMethod(Method method) {
     51         if (mockCreationSettings.isSerializable()) {
     52             return new SerializableMethod(method);
     53         } else {
     54             return new DelegatingMethod(method);
     55         }
     56     }
     57 
     58     public MockHandler getMockHandler() {
     59         return handler;
     60     }
     61 
     62     public ByteBuddyCrossClassLoaderSerializationSupport getSerializationSupport() {
     63         return serializationSupport;
     64     }
     65 
     66     public static class ForHashCode {
     67 
     68         @SuppressWarnings("unused")
     69         public static int doIdentityHashCode(@This Object thiz) {
     70             return System.identityHashCode(thiz);
     71         }
     72     }
     73 
     74     public static class ForEquals {
     75 
     76         @SuppressWarnings("unused")
     77         public static boolean doIdentityEquals(@This Object thiz, @Argument(0) Object other) {
     78             return thiz == other;
     79         }
     80     }
     81 
     82     public static class ForWriteReplace {
     83 
     84         public static Object doWriteReplace(@This MockAccess thiz) throws ObjectStreamException {
     85             return thiz.getMockitoInterceptor().getSerializationSupport().writeReplace(thiz);
     86         }
     87     }
     88 
     89     public static class DispatcherDefaultingToRealMethod {
     90 
     91         @SuppressWarnings("unused")
     92         @RuntimeType
     93         @BindingPriority(BindingPriority.DEFAULT * 2)
     94         public static Object interceptSuperCallable(@This Object mock,
     95                                                     @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor,
     96                                                     @Origin Method invokedMethod,
     97                                                     @AllArguments Object[] arguments,
     98                                                     @SuperCall(serializableProxy = true) Callable<?> superCall) throws Throwable {
     99             if (interceptor == null) {
    100                 return superCall.call();
    101             }
    102             return interceptor.doIntercept(
    103                     mock,
    104                     invokedMethod,
    105                     arguments,
    106                     new InterceptedInvocation.SuperMethod.FromCallable(superCall)
    107             );
    108         }
    109 
    110         @SuppressWarnings("unused")
    111         @RuntimeType
    112         public static Object interceptAbstract(@This Object mock,
    113                                                @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor,
    114                                                @StubValue Object stubValue,
    115                                                @Origin Method invokedMethod,
    116                                                @AllArguments Object[] arguments) throws Throwable {
    117             if (interceptor == null) {
    118                 return stubValue;
    119             }
    120             return interceptor.doIntercept(
    121                     mock,
    122                     invokedMethod,
    123                     arguments,
    124                     InterceptedInvocation.SuperMethod.IsIllegal.INSTANCE
    125             );
    126         }
    127     }
    128 }
    129