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

mockit.internal.capturing.CaptureOfImplementations 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.capturing;

import java.util.*;

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

public abstract class CaptureOfImplementations implements Runnable
{
   private final List captureTransformers;

   protected CaptureOfImplementations() { captureTransformers = new ArrayList(); }

   protected abstract ClassVisitor createModifier(ClassLoader cl, ClassReader cr, String capturedTypeDesc);

   public final void makeSureAllSubtypesAreModified(Class baseType)
   {
      makeSureAllSubtypesAreModified(baseType, false);
   }

   public final void makeSureAllSubtypesAreModified(Class baseType, boolean registerCapturedClasses)
   {
      if (baseType == null) {
         throw new IllegalArgumentException("Capturing implementations of multiple base types is not supported");
      }

      String baseTypeDesc = Type.getInternalName(baseType);
      CapturedType captureMetadata = new CapturedType(baseType);

      redefineClassesAlreadyLoaded(captureMetadata, baseTypeDesc);
      createCaptureTransformer(captureMetadata, registerCapturedClasses);
   }

   private void redefineClassesAlreadyLoaded(CapturedType captureMetadata, String baseTypeDesc)
   {
      Class[] classesLoaded = Startup.instrumentation().getAllLoadedClasses();

      for (Class aClass : classesLoaded) {
         if (captureMetadata.isToBeCaptured(aClass)) {
            redefineClass(aClass, baseTypeDesc);
         }
      }
   }

   private void redefineClass(Class realClass, String baseTypeDesc)
   {
      if (!TestRun.mockFixture().containsRedefinedClass(realClass)) {
         ClassReader classReader;

         try {
            classReader = ClassFile.createReaderOrGetFromCache(realClass);
         }
         catch (ClassFile.NotFoundException ignore) {
            return;
         }

         ClassVisitor modifier = createModifier(realClass.getClassLoader(), classReader, baseTypeDesc);
         classReader.accept(modifier, 0);
         byte[] modifiedClass = modifier.toByteArray();

         new RedefinitionEngine(realClass).redefineMethodsWhileRegisteringTheClass(modifiedClass);
      }
   }

   private void createCaptureTransformer(CapturedType captureMetadata, boolean registerCapturedClasses)
   {
      CaptureTransformer transformer = new CaptureTransformer(captureMetadata, this, registerCapturedClasses);
      Startup.instrumentation().addTransformer(transformer);
      captureTransformers.add(transformer);
   }

   public void cleanUp()
   {
      for (CaptureTransformer transformer : captureTransformers) {
         transformer.deactivate();
         Startup.instrumentation().removeTransformer(transformer);
      }

      captureTransformers.clear();
   }

   public final void run() { cleanUp(); }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy