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

mockit.internal.ImplementationClass Maven / Gradle / Ivy

/*
 * 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.lang.reflect.Type;

import org.jetbrains.annotations.*;

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

/**
 * Allows the creation of new implementation classes for interfaces and abstract classes.
 */
public abstract class ImplementationClass
{
   @NotNull private final Type mockedType;
   private byte[] generatedBytecode;

   protected ImplementationClass(@NotNull Type mockedType) { this.mockedType = mockedType; }

   @NotNull public final Class generateNewMockImplementationClassForInterface()
   {
      Class mockedClass = Utilities.getClassType(mockedType);
      ClassReader interfaceReader = ClassFile.createClassFileReader(mockedClass);
      String mockClassName = GeneratedClasses.getNameForGeneratedClass(mockedClass);

      ClassVisitor modifier = createMethodBodyGenerator(interfaceReader, mockClassName);
      interfaceReader.accept(modifier, ClassReader.SKIP_DEBUG);

      generatedBytecode = modifier.toByteArray();

      @SuppressWarnings("unchecked")
      Class implClass = (Class) defineNewClass(mockedClass.getClassLoader(), generatedBytecode, mockClassName);

      return implClass;
   }

   @NotNull
   protected abstract ClassVisitor createMethodBodyGenerator(
      @NotNull ClassReader typeReader, @NotNull String className);

   public final byte[] getGeneratedBytecode() { return generatedBytecode; }

   @NotNull
   public static Class defineNewClass(
      @Nullable ClassLoader parentLoader, @NotNull final byte[] bytecode, @NotNull String className)
   {
      if (parentLoader == null) {
         //noinspection AssignmentToMethodParameter
         parentLoader = ImplementationClass.class.getClassLoader();
      }

      return new ClassLoader(parentLoader) {
         @Override
         protected Class findClass(String name)
         {
            return defineClass(name, bytecode, 0, bytecode.length);
         }
      }.findClass(className);
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy