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