mockit.internal.util.ClassLoad Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmockit Show documentation
Show all versions of jmockit Show documentation
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.
/*
* 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 = loadClassFromAClassLoader(className);
}
catch (LinkageError e) {
e.printStackTrace();
throw e;
}
}
//noinspection unchecked
return (Class) loadedClass;
}
@Nonnull
private static Class> loadClassFromAClassLoader(@Nonnull String className)
{
Class> 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");
}
}
}
}
return 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, false, 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, false, loader);
}
catch (ClassNotFoundException ignore) {
throw new IllegalArgumentException("No class with name \"" + className + "\" found");
}
}
@Nullable
public static Class extends T> searchTypeInClasspath(@Nonnull String typeName)
{
return searchTypeInClasspath(typeName, false);
}
@Nullable
public static Class extends T> searchTypeInClasspath(@Nonnull String typeName, boolean initializeType)
{
//noinspection OverlyBroadCatchBlock
try {
//noinspection unchecked
return (Class extends T>) 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 isClassLoaderWithNoDirectAccess(@Nullable ClassLoader classLoader)
{
return classLoader == null || classLoader != THIS_CL && classLoader.getParent() != THIS_CL;
}
public static ClassLoader getClassLoaderWithAccess(@Nonnull Class> classToBeAccessed)
{
ClassLoader cl = classToBeAccessed.getClassLoader();
return isClassLoaderWithNoDirectAccess(cl) ? THIS_CL : cl;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy