org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mockito-core Show documentation
Show all versions of mockito-core Show documentation
Mockito mock objects library core API and implementation
/*
* Copyright (c) 2016 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.creation.bytebuddy;
import net.bytebuddy.TypeCache;
import org.mockito.mock.SerializableMode;
import java.lang.ref.ReferenceQueue;
import java.util.Set;
import java.util.concurrent.Callable;
class TypeCachingBytecodeGenerator extends ReferenceQueue implements BytecodeGenerator {
private final Object BOOTSTRAP_LOCK = new Object();
private final BytecodeGenerator bytecodeGenerator;
private final TypeCache typeCache;
public TypeCachingBytecodeGenerator(BytecodeGenerator bytecodeGenerator, boolean weak) {
this.bytecodeGenerator = bytecodeGenerator;
typeCache = new TypeCache.WithInlineExpunction(weak ? TypeCache.Sort.WEAK : TypeCache.Sort.SOFT);
}
@SuppressWarnings("unchecked")
@Override
public Class mockClass(final MockFeatures params) {
try {
ClassLoader classLoader = params.mockedType.getClassLoader();
return (Class) typeCache.findOrInsert(classLoader,
new SerializationFeatureKey(params.mockedType, params.interfaces, params.serializableMode),
new Callable>() {
@Override
public Class call() throws Exception {
return bytecodeGenerator.mockClass(params);
}
}, classLoader == null ? BOOTSTRAP_LOCK : classLoader);
} catch (IllegalArgumentException exception) {
Throwable cause = exception.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else {
throw exception;
}
}
}
private static class SerializationFeatureKey extends TypeCache.SimpleKey {
private final SerializableMode serializableMode;
private SerializationFeatureKey(Class type, Set> additionalType, SerializableMode serializableMode) {
super(type, additionalType);
this.serializableMode = serializableMode;
}
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
if (!super.equals(object)) return false;
SerializationFeatureKey that = (SerializationFeatureKey) object;
return serializableMode.equals(that.serializableMode);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + serializableMode.hashCode();
return result;
}
}
}