1
2
3
4
5 package mockit.internal.faking;
6
7 import static java.lang.reflect.Modifier.isPublic;
8
9 import edu.umd.cs.findbugs.annotations.NonNull;
10 import edu.umd.cs.findbugs.annotations.Nullable;
11
12 import java.lang.reflect.Proxy;
13 import java.lang.reflect.Type;
14
15 import mockit.MockUp;
16 import mockit.asm.classes.ClassReader;
17 import mockit.asm.classes.ClassVisitor;
18 import mockit.internal.classGeneration.ImplementationClass;
19 import mockit.internal.expectations.mocking.InterfaceImplementationGenerator;
20 import mockit.internal.util.Utilities;
21
22 public final class FakedImplementationClass<T> {
23 private static final ClassLoader THIS_CL = FakedImplementationClass.class.getClassLoader();
24
25 @NonNull
26 private final MockUp<?> fakeInstance;
27 @Nullable
28 private ImplementationClass<T> implementationClass;
29 private Class<T> generatedClass;
30
31 public FakedImplementationClass(@NonNull MockUp<?> fakeInstance) {
32 this.fakeInstance = fakeInstance;
33 }
34
35 @NonNull
36 public Class<T> createImplementation(@NonNull Class<T> interfaceToBeFaked, @Nullable Type typeToFake) {
37 createImplementation(interfaceToBeFaked);
38 byte[] generatedBytecode = implementationClass == null ? null : implementationClass.getGeneratedBytecode();
39
40 FakeClassSetup fakeClassSetup = new FakeClassSetup(generatedClass, typeToFake, fakeInstance, generatedBytecode);
41 fakeClassSetup.redefineMethodsInGeneratedClass();
42
43 return generatedClass;
44 }
45
46 @NonNull
47 Class<T> createImplementation(@NonNull Class<T> interfaceToBeFaked) {
48 if (isPublic(interfaceToBeFaked.getModifiers())) {
49 generateImplementationForPublicInterface(interfaceToBeFaked);
50 } else {
51
52 generatedClass = (Class<T>) Proxy.getProxyClass(interfaceToBeFaked.getClassLoader(), interfaceToBeFaked);
53 }
54
55 return generatedClass;
56 }
57
58 private void generateImplementationForPublicInterface(@NonNull Class<T> interfaceToBeFaked) {
59 implementationClass = new ImplementationClass<T>(interfaceToBeFaked) {
60 @NonNull
61 @Override
62 protected ClassVisitor createMethodBodyGenerator(@NonNull ClassReader typeReader) {
63 return new InterfaceImplementationGenerator(typeReader, interfaceToBeFaked, generatedClassName);
64 }
65 };
66
67 generatedClass = implementationClass.generateClass();
68 }
69
70 @NonNull
71 public Class<T> createImplementation(@NonNull Type[] interfacesToBeFaked) {
72 Class<?>[] interfacesToFake = new Class<?>[interfacesToBeFaked.length];
73
74 for (int i = 0; i < interfacesToFake.length; i++) {
75 interfacesToFake[i] = Utilities.getClassType(interfacesToBeFaked[i]);
76 }
77
78
79 generatedClass = (Class<T>) Proxy.getProxyClass(THIS_CL, interfacesToFake);
80 new FakeClassSetup(generatedClass, null, fakeInstance, null).redefineMethods();
81
82 return generatedClass;
83 }
84 }