12637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin/*
22637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * Copyright (c) 2016 Mockito contributors
32637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * This program is made available under the terms of the MIT License.
42637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin */
52637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpackage org.mockito.internal.creation.bytebuddy;
62637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
72637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport net.bytebuddy.implementation.bind.annotation.*;
82637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.InternalMockHandler;
92637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.creation.DelegatingMethod;
102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.invocation.MockitoMethod;
112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.invocation.SerializableMethod;
122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.progress.SequenceNumber;
132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.invocation.MockHandler;
142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.mock.MockCreationSettings;
152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.io.ObjectStreamException;
172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.io.Serializable;
182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.lang.reflect.Method;
192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.util.concurrent.Callable;
202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpublic class MockMethodInterceptor implements Serializable {
222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private static final long serialVersionUID = 7152947254057253027L;
242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    final InternalMockHandler handler;
262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private final MockCreationSettings mockCreationSettings;
282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private final ByteBuddyCrossClassLoaderSerializationSupport serializationSupport;
302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockMethodInterceptor(InternalMockHandler handler, MockCreationSettings mockCreationSettings) {
322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.handler = handler;
332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.mockCreationSettings = mockCreationSettings;
342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        serializationSupport = new ByteBuddyCrossClassLoaderSerializationSupport();
352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    Object doIntercept(Object mock,
382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                       Method invokedMethod,
392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                       Object[] arguments,
402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                       InterceptedInvocation.SuperMethod superMethod) throws Throwable {
412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return handler.handle(new InterceptedInvocation(
422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                mock,
432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                createMockitoMethod(invokedMethod),
442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                arguments,
452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                superMethod,
462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                SequenceNumber.next()
472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        ));
482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private MockitoMethod createMockitoMethod(Method method) {
512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        if (mockCreationSettings.isSerializable()) {
522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return new SerializableMethod(method);
532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        } else {
542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return new DelegatingMethod(method);
552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockHandler getMockHandler() {
592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return handler;
602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public ByteBuddyCrossClassLoaderSerializationSupport getSerializationSupport() {
632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return serializationSupport;
642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public static class ForHashCode {
672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @SuppressWarnings("unused")
692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public static int doIdentityHashCode(@This Object thiz) {
702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return System.identityHashCode(thiz);
712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public static class ForEquals {
752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @SuppressWarnings("unused")
772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public static boolean doIdentityEquals(@This Object thiz, @Argument(0) Object other) {
782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return thiz == other;
792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public static class ForWriteReplace {
832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public static Object doWriteReplace(@This MockAccess thiz) throws ObjectStreamException {
852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return thiz.getMockitoInterceptor().getSerializationSupport().writeReplace(thiz);
862637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
872637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
882637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
892637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public static class DispatcherDefaultingToRealMethod {
902637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
912637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @SuppressWarnings("unused")
922637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @RuntimeType
932637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @BindingPriority(BindingPriority.DEFAULT * 2)
942637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public static Object interceptSuperCallable(@This Object mock,
952637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                                    @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor,
962637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                                    @Origin Method invokedMethod,
972637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                                    @AllArguments Object[] arguments,
982637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                                    @SuperCall(serializableProxy = true) Callable<?> superCall) throws Throwable {
992637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (interceptor == null) {
1002637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                return superCall.call();
1012637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
1022637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return interceptor.doIntercept(
1032637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    mock,
1042637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    invokedMethod,
1052637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    arguments,
1062637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    new InterceptedInvocation.SuperMethod.FromCallable(superCall)
1072637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            );
1082637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1092637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @SuppressWarnings("unused")
1112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        @RuntimeType
1122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public static Object interceptAbstract(@This Object mock,
1132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                               @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor,
1142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                               @StubValue Object stubValue,
1152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                               @Origin Method invokedMethod,
1162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                                               @AllArguments Object[] arguments) throws Throwable {
1172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (interceptor == null) {
1182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                return stubValue;
1192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
1202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            return interceptor.doIntercept(
1212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    mock,
1222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    invokedMethod,
1232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    arguments,
1242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                    InterceptedInvocation.SuperMethod.IsIllegal.INSTANCE
1252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            );
1262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin}
129