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

mockit.internal.ClassFile Maven / Gradle / Ivy

Go to download

JMockit is a Java toolkit for developer (unit/integration) testing. It contains mocking APIs and other tools, supporting both JUnit and TestNG. The mocking APIs allow all kinds of Java code, without testability restrictions, to be tested in isolation from selected dependencies.

There is a newer version: 1.7
Show newest version
/*
 * Copyright (c) 2006-2013 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 org.jetbrains.annotations.*;

import mockit.external.asm4.*;
import mockit.internal.state.*;

public final class ClassFile
{
   private static final Map CLASS_FILES = new ConcurrentHashMap();

   private ClassFile() {}

   public static final class NotFoundException extends RuntimeException
   {
      private NotFoundException(@NotNull String className)
      {
         super("Unable to find class file for " + className.replace('/', '.'));
      }
   }

   @Contract("null, _ -> fail")
   private static void verifyClassFileFound(@Nullable InputStream classFile, @NotNull String className)
   {
      if (classFile == null) {
         throw new NotFoundException(className);
      }
   }

   @NotNull public static ClassReader createClassFileReader(@NotNull Class aClass)
   {
      byte[] cachedClassfile = CachedClassfiles.getClassfile(aClass);

      if (cachedClassfile != null) {
         return new ClassReader(cachedClassfile);
      }

      String className = aClass.getName();
      InputStream classFile = aClass.getResourceAsStream('/' + internalClassName(className) + ".class");
      verifyClassFileFound(classFile, className);

      try {
         return new ClassReader(classFile);
      }
      catch (IOException e) {
         throw new RuntimeException("Failed to read class file for " + className, e);
      }
   }

   @NotNull private static String internalClassName(@NotNull String className) { return className.replace('.', '/'); }

   @NotNull public static ClassReader createReaderOrGetFromCache(@NotNull Class aClass)
   {
      byte[] cachedClassfile = CachedClassfiles.getClassfile(aClass);

      if (cachedClassfile != null) {
         return new ClassReader(cachedClassfile);
      }

      String className = aClass.getName();
      String classDesc = internalClassName(className);
      ClassReader reader = CLASS_FILES.get(classDesc);

      if (reader == null) {
         InputStream classFile = readClassFromClasspath(classDesc);
         verifyClassFileFound(classFile, className);

         try {
            reader = new ClassReader(classFile);
         }
         catch (IOException e) {
            throw new RuntimeException("Failed to read class file for " + className, e);
         }

         CLASS_FILES.put(classDesc, reader);
      }

      return reader;
   }

   @Nullable private static InputStream readClassFromClasspath(@NotNull String internalClassName)
   {
      String classFileName = internalClassName + ".class";
      ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
      InputStream 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);
               }
            }
         }
      }

      return inputStream;
   }

   @NotNull public static ClassReader createReaderFromLastRedefinitionIfAny(@NotNull Class aClass)
   {
      byte[] classfile = TestRun.mockFixture().getRedefinedClassfile(aClass);

      if (classfile == null) {
         classfile = CachedClassfiles.getClassfile(aClass);
      }

      if (classfile != null) {
         return new ClassReader(classfile);
      }

      String className = aClass.getName();
      String classDesc = internalClassName(className);
      ClassReader reader;

      try {
         reader = readClass(classDesc);
      }
      catch (IOException e) {
         throw new RuntimeException("Failed to read class file for " + className, e);
      }

      CLASS_FILES.put(classDesc, reader);
      return reader;
   }

   @NotNull
   public static ClassReader createClassFileReader(@Nullable ClassLoader loader, @NotNull String internalClassName)
   {
      byte[] cachedClassfile = CachedClassfiles.getClassfile(loader, internalClassName);

      if (cachedClassfile != null) {
         return new ClassReader(cachedClassfile);
      }

      try {
         return readClass(internalClassName);
      }
      catch (IOException e) {
         throw new RuntimeException("Failed to read class file for " + internalClassName.replace('/', '.'), e);
      }
   }

   @NotNull public static ClassReader readClass(@NotNull String classDesc) throws IOException
   {
      InputStream classFile = readClassFromClasspath(classDesc);

      if (classFile == null) {
         throw new NotFoundException(classDesc.replace('/', '.'));
      }

      return new ClassReader(classFile);
   }

   public static void visitClass(@NotNull String internalClassName, @NotNull ClassVisitor visitor)
   {
      InputStream classFile = readClassFromClasspath(internalClassName);
      verifyClassFileFound(classFile, internalClassName);

      try {
         ClassReader cr = new ClassReader(classFile);
         cr.accept(visitor, ClassReader.SKIP_DEBUG);
      }
      catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy