mockit.internal.ClassFile 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;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
import javax.annotation.*;
import mockit.external.asm.*;
import mockit.internal.state.*;
import static mockit.external.asm.ClassReader.*;
public final class ClassFile
{
private static final Map CLASS_FILES = new ConcurrentHashMap();
private ClassFile() {}
public static final class NotFoundException extends RuntimeException
{
private NotFoundException(@Nonnull String classNameOrDesc)
{
super("Unable to find class file for " + classNameOrDesc.replace('/', '.'));
}
}
private static void verifyClassFileFound(@Nullable InputStream classFile, @Nonnull String classNameOrDesc)
{
if (classFile == null) {
throw new NotFoundException(classNameOrDesc);
}
}
@Nonnull
public static ClassReader createClassFileReader(@Nonnull Class> aClass)
{
byte[] cachedClassfile = CachedClassfiles.getClassfile(aClass);
if (cachedClassfile != null) {
return new ClassReader(cachedClassfile);
}
String className = aClass.getName();
InputStream classFile = aClass.getResourceAsStream('/' + className.replace('.', '/') + ".class");
verifyClassFileFound(classFile, className);
try {
return new ClassReader(classFile);
}
catch (IOException e) {
throw new RuntimeException("Failed to read class file for " + className, e);
}
}
@Nonnull
public static ClassReader createReaderOrGetFromCache(@Nonnull Class> aClass)
{
byte[] cachedClassfile = CachedClassfiles.getClassfile(aClass);
if (cachedClassfile != null) {
return new ClassReader(cachedClassfile);
}
String classDesc = aClass.getName().replace('.', '/');
ClassReader reader = CLASS_FILES.get(classDesc);
if (reader == null) {
reader = readFromFile(classDesc);
CLASS_FILES.put(classDesc, reader);
}
return reader;
}
@Nonnull @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
private static InputStream readClassFromClasspath(@Nonnull String classDesc)
{
String classFileName = classDesc + ".class";
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = null;
if (contextClassLoader != null) {
inputStream = contextClassLoader.getResourceAsStream(classFileName);
}
if (inputStream == null) {
ClassLoader thisClassLoader = ClassFile.class.getClassLoader();
if (thisClassLoader != contextClassLoader) {
inputStream = thisClassLoader.getResourceAsStream(classFileName);
if (inputStream == null) {
Class> testClass = TestRun.getCurrentTestClass();
if (testClass != null) {
inputStream = testClass.getClassLoader().getResourceAsStream(classFileName);
}
}
}
}
verifyClassFileFound(inputStream, classDesc);
//noinspection ConstantConditions
return inputStream;
}
@Nonnull
public static ClassReader createReaderFromLastRedefinitionIfAny(@Nonnull Class> aClass)
{
byte[] classfile = TestRun.mockFixture().getRedefinedClassfile(aClass);
if (classfile == null) {
classfile = CachedClassfiles.getClassfile(aClass);
}
if (classfile != null) {
return new ClassReader(classfile);
}
String classDesc = aClass.getName().replace('.', '/');
ClassReader reader = readFromFile(classDesc);
CLASS_FILES.put(classDesc, reader);
return reader;
}
@Nonnull
public static ClassReader createClassFileReader(@Nullable ClassLoader loader, @Nonnull String internalClassName)
{
byte[] cachedClassfile = CachedClassfiles.getClassfile(loader, internalClassName);
if (cachedClassfile != null) {
return new ClassReader(cachedClassfile);
}
return readFromFile(internalClassName);
}
@Nonnull
public static ClassReader readFromFile(@Nonnull Class> aClass)
{
String classDesc = aClass.getName().replace('.', '/');
return readFromFile(classDesc);
}
@Nonnull
public static ClassReader readFromFile(@Nonnull String classDesc)
{
if (classDesc.startsWith("java/") || classDesc.startsWith("javax/")) {
byte[] classfile = CachedClassfiles.getClassfile(classDesc);
if (classfile != null) {
return new ClassReader(classfile);
}
}
InputStream classFile = readClassFromClasspath(classDesc);
try {
return new ClassReader(classFile);
}
catch (IOException e) {
throw new RuntimeException("Failed to read class file for " + classDesc.replace('/', '.'), e);
}
}
public static void visitClass(@Nonnull String classDesc, @Nonnull ClassVisitor visitor)
{
byte[] classfile = CachedClassfiles.getClassfile(classDesc);
ClassReader cr = classfile != null ? new ClassReader(classfile) : readFromFile(classDesc);
cr.accept(visitor, SKIP_DEBUG);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy