All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.internal.util.ClassLoad Maven / Gradle / Ivy

Go to download

JMockit is a Java toolkit for automated developer testing. It contains APIs for the creation of the objects to be tested, for mocking dependencies, and for faking external APIs; JUnit (4 & 5) and TestNG test runners are supported. It also contains an advanced code coverage tool.

There is a newer version: 1.49
Show newest version
/*
 * Copyright (c) 2006 Rogério Liesenfeld
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
 */
package mockit.internal.util;

import java.util.*;
import java.util.concurrent.*;
import javax.annotation.*;

import mockit.internal.state.*;

public final class ClassLoad
{
   public static final String OBJECT = "java/lang/Object";

   private static final ClassLoader THIS_CL = ClassLoad.class.getClassLoader();
   private static final Map> LOADED_CLASSES = new ConcurrentHashMap>();
   private static final Map SUPER_CLASSES = new ConcurrentHashMap();

   private ClassLoad() {}

   public static void registerLoadedClass(@Nonnull Class aClass)
   {
      LOADED_CLASSES.put(aClass.getName(), aClass);
   }

   @Nonnull
   public static  Class loadByInternalName(@Nonnull String internalClassName)
   {
      return loadClass(internalClassName.replace('/', '.'));
   }

   @Nonnull
   public static  Class loadClass(@Nonnull String className)
   {
      @Nullable Class loadedClass = LOADED_CLASSES.get(className);

      if (loadedClass == null) {
         try {
            loadedClass = loadClass(null, className);

            if (loadedClass == null) {
               if (className.startsWith("mockit.")) {
                  loadedClass = loadClass(THIS_CL, className);
               }

               if (loadedClass == null) {
                  Class testClass = TestRun.getCurrentTestClass();
                  loadedClass = testClass == null ? null : loadClass(testClass.getClassLoader(), className);

                  if (loadedClass == null) {
                     ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
                     loadedClass = loadClass(contextCL, className);

                     if (loadedClass == null) {
                        throw new IllegalArgumentException("No class with name \"" + className + "\" found");
                     }
                  }
               }
            }
         }
         catch (LinkageError e) {
            e.printStackTrace();
            throw e;
         }
      }

      //noinspection unchecked
      return (Class) loadedClass;
   }

   @Nonnull
   public static  Class loadClassAtStartup(@Nonnull String className)
   {
      ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
      Class loadedClass;

      try {
         loadedClass = loadClass(contextCL, className);

         if (loadedClass == null) {
            loadedClass = loadClass(THIS_CL, className);

            if (loadedClass == null) {
               throw new IllegalArgumentException("No class with name \"" + className + "\" found");
            }
         }
      }
      catch (LinkageError e) {
         e.printStackTrace();
         throw e;
      }

      //noinspection unchecked
      return (Class) loadedClass;
   }

   @Nullable
   public static Class loadClass(@Nullable ClassLoader loader, @Nonnull String className)
   {
      try { return Class.forName(className, true, loader); } catch (ClassNotFoundException ignore) { return null; }
   }

   @Nonnull
   public static  Class loadFromLoader(@Nullable ClassLoader loader, @Nonnull String className)
   {
      try {
         //noinspection unchecked
         return (Class) Class.forName(className, true, loader);
      }
      catch (ClassNotFoundException ignore) {
         throw new IllegalArgumentException("No class with name \"" + className + "\" found");
      }
   }

   @Nullable
   public static  Class searchTypeInClasspath(@Nonnull String typeName)
   {
       return searchTypeInClasspath(typeName, false);
   }

   @Nullable
   public static  Class searchTypeInClasspath(@Nonnull String typeName, boolean initializeType)
   {
      //noinspection OverlyBroadCatchBlock
      try {
         //noinspection unchecked
         return (Class) Class.forName(typeName, initializeType, THIS_CL);
      }
      catch (Throwable ignore) { return null; }
   }

   public static void addSuperClass(@Nonnull String classInternalName, @Nonnull String superClassInternalName)
   {
      SUPER_CLASSES.put(classInternalName.intern(), superClassInternalName.intern());
   }

   @Nonnull
   public static String getSuperClass(@Nonnull String classInternalName)
   {
      String classDesc = classInternalName.intern();
      String superName = SUPER_CLASSES.get(classDesc);

      if (superName == null) {
         Class theClass = loadByInternalName(classDesc);
         Class superClass = theClass.getSuperclass();

         if (superClass != null) {
            superName = superClass.getName().replace('.', '/').intern();
            SUPER_CLASSES.put(classDesc, superName);
         }
      }

      return superName == null ? OBJECT : superName;
   }

   @Nullable
   public static String whichIsSuperClass(@Nonnull String internalClassName1, @Nonnull String internalClassName2)
   {
      String class1 = actualSuperClass(internalClassName1, internalClassName2);

      if (class1 != null) {
         return class1;
      }

      String class2 = actualSuperClass(internalClassName2, internalClassName1);
      return class2;
   }

   @Nullable
   private static String actualSuperClass(@Nonnull String candidateSuperClass, @Nonnull String candidateSubclass)
   {
      String subclass = candidateSubclass;

      while (true) {
         String superClass = getSuperClass(subclass);

         if (superClass.equals(OBJECT)) {
            return null;
         }

         if (superClass.equals(candidateSuperClass)) {
            return candidateSuperClass;
         }

         subclass = superClass;
      }
   }

   public static boolean isGeneratedSubclass(@Nonnull String className)
   {
      int p = className.indexOf('$') + 1;

      if (p < 2 || p == className.length() || className.charAt(p) != '$') {
         return false;
      }

      return className.contains("_$$_javassist_") || className.contains("_$$_jvst") || className.contains("CGLIB$$");
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy