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

mockit.internal.state.CachedClassfiles Maven / Gradle / Ivy

There is a newer version: 2.5.0
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.state;

import java.lang.instrument.*;
import java.security.*;
import java.util.*;

/**
 * Holds a map of internal class names to the corresponding class files (bytecode arrays), for the classes
 * that have already been loaded during the test run.
 * These classfiles are not necessarily the same as those stored in the corresponding ".class" files
 * available from the runtime classpath.
 * If any third-party {@link java.lang.instrument.ClassFileTransformer}s are active, those original classfiles
 * may have been modified before being loaded by the JVM.
 * JMockit installs a {@code ClassFileTransformer} of its own which saves all potentially modified classfiles
 * here.
 * 

* This bytecode cache allows classes to be mocked and un-mocked correctly, even in the presence of other * bytecode modification agents such as the AspectJ load-time weaver. */ public final class CachedClassfiles implements ClassFileTransformer { public static final CachedClassfiles INSTANCE = new CachedClassfiles(); private final Map> classLoadersAndClassfiles = new WeakHashMap>(2); private ClassDefinition[] classesBeingMocked; public void setClassesBeingMocked(ClassDefinition[] classDefs) { classesBeingMocked = classDefs; } private CachedClassfiles() {} public byte[] transform( ClassLoader loader, String classDesc, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { if (classBeingRedefined == null) { // class definition if (!isExcluded(classDesc)) { addClassfile(loader, classDesc, classfileBuffer); } } else if (!isBeingMocked(classBeingRedefined) && !isExcluded(classDesc)) { // class redefinition addClassfileIfNotYetPresent(loader, classDesc, classfileBuffer); } return null; } private boolean isExcluded(String classDesc) { return classDesc.startsWith("org/junit/") || classDesc.startsWith("sun/") && !classDesc.startsWith("sun/proxy/$") || classDesc.startsWith("com/intellij/") || classDesc.startsWith("mockit/internal/") || classDesc.startsWith("mockit/integration/") || classDesc.startsWith("mockit/coverage/") || classDesc.startsWith("mockit/") && classDesc.indexOf('$') < 0; } private boolean isBeingMocked(Class classBeingRedefined) { if (classesBeingMocked != null) { for (ClassDefinition classDef : classesBeingMocked) { if (classDef.getDefinitionClass() == classBeingRedefined) { return true; } } } return false; } private synchronized void addClassfile(ClassLoader loader, String classDesc, byte[] classfile) { Map classfiles = getClassfiles(loader); classfiles.put(classDesc, classfile); } private Map getClassfiles(ClassLoader loader) { Map classfiles = classLoadersAndClassfiles.get(loader); if (classfiles == null) { classfiles = new HashMap(100); classLoadersAndClassfiles.put(loader, classfiles); } return classfiles; } private synchronized void addClassfileIfNotYetPresent(ClassLoader loader, String classDesc, byte[] classfile) { Map classfiles = getClassfiles(loader); if (!classfiles.containsKey(classDesc)) { classfiles.put(classDesc, classfile); } } private synchronized byte[] findClassfile(Class aClass) { Map classfiles = getClassfiles(aClass.getClassLoader()); return classfiles.get(aClass.getName().replace('.', '/')); } private synchronized byte[] findClassfile(ClassLoader loader, String classDesc) { Map classfiles = getClassfiles(loader); return classfiles.get(classDesc); } public static byte[] getClassfile(Class aClass) { return INSTANCE.findClassfile(aClass); } public static byte[] getClassfile(ClassLoader loader, String internalClassName) { return INSTANCE.findClassfile(loader, internalClassName); } public static void addClassfile(Class aClass, byte[] classfile) { INSTANCE.addClassfile(aClass.getClassLoader(), aClass.getName().replace('.', '/'), classfile); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy