View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
4    */
5   package mockit.internal.util;
6   
7   import edu.umd.cs.findbugs.annotations.NonNull;
8   import edu.umd.cs.findbugs.annotations.Nullable;
9   
10  import java.lang.reflect.Proxy;
11  
12  public final class GeneratedClasses {
13      private static final String IMPLCLASS_PREFIX = "$Impl_";
14      private static final String SUBCLASS_PREFIX = "$Subclass_";
15  
16      private GeneratedClasses() {
17      }
18  
19      @NonNull
20      public static String getNameForGeneratedClass(@NonNull Class<?> aClass, @Nullable String suffix) {
21          String prefix = aClass.isInterface() ? IMPLCLASS_PREFIX : SUBCLASS_PREFIX;
22          StringBuilder name = new StringBuilder(60).append(prefix).append(aClass.getSimpleName());
23  
24          if (suffix != null) {
25              name.append('_').append(suffix);
26          }
27  
28          if (aClass.getClassLoader() != null) {
29              Package targetPackage = aClass.getPackage();
30  
31              if (targetPackage != null && !targetPackage.isSealed() && !targetPackage.getName().isEmpty()) {
32                  name.insert(0, '.').insert(0, targetPackage.getName());
33              }
34          }
35  
36          return name.toString();
37      }
38  
39      public static boolean isGeneratedImplementationClass(@NonNull Class<?> mockedType) {
40          return isGeneratedImplementationClassName(mockedType.getName());
41      }
42  
43      public static boolean isGeneratedImplementationClassName(@NonNull String className) {
44          return className.contains(IMPLCLASS_PREFIX);
45      }
46  
47      private static boolean isGeneratedSubclass(@NonNull String className) {
48          return className.contains(SUBCLASS_PREFIX);
49      }
50  
51      public static boolean isExternallyGeneratedSubclass(@NonNull String className) {
52          int p = className.indexOf('$') + 1;
53  
54          // noinspection SimplifiableIfStatement
55          if (p < 2 || p == className.length() || className.charAt(p) != '$') {
56              return false;
57          }
58  
59          return className.contains("_$$_javassist_") || className.contains("_$$_jvst") || className.contains("CGLIB$$");
60      }
61  
62      public static boolean isGeneratedClass(@NonNull String className) {
63          return isGeneratedSubclass(className) || isGeneratedImplementationClassName(className);
64      }
65  
66      @NonNull
67      public static Class<?> getMockedClassOrInterfaceType(@NonNull Class<?> aClass) {
68          if (Proxy.isProxyClass(aClass) || isGeneratedImplementationClass(aClass)) {
69              // Assumes that a proxy class implements a single interface.
70              return aClass.getInterfaces()[0];
71          }
72  
73          if (isGeneratedSubclass(aClass.getName())) {
74              return aClass.getSuperclass();
75          }
76  
77          return aClass;
78      }
79  
80      @NonNull
81      public static Class<?> getMockedClass(@NonNull Object mock) {
82          return getMockedClassOrInterfaceType(mock.getClass());
83      }
84  }