Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.testifyproject.bytebuddy.dynamic;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.EqualsAndHashCode;
import org.testifyproject.bytebuddy.description.NamedElement;
import org.testifyproject.bytebuddy.description.type.TypeDescription;
import org.testifyproject.bytebuddy.utility.JavaModule;
import org.testifyproject.bytebuddy.utility.JavaType;
import org.testifyproject.bytebuddy.utility.StreamDrainer;
import java.io.*;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.testifyproject.bytebuddy.matcher.ElementMatchers.isChildOf;
/**
* Locates a class file or its byte array representation when it is given its type description.
*/
public interface ClassFileLocator extends Closeable {
/**
* The file extension for a Java class file.
*/
String CLASS_FILE_EXTENSION = ".class";
/**
* Locates the class file for a given type and returns the binary data of the class file.
*
* @param typeName The name of the type to locate a class file representation for.
* @return Any binary representation of the type which might be illegal.
* @throws java.io.IOException If reading a class file causes an error.
*/
Resolution locate(String typeName) throws IOException;
/**
* Represents a class file as binary data.
*/
interface Resolution {
/**
* Checks if this binary representation is valid.
*
* @return {@code true} if this binary representation is valid.
*/
boolean isResolved();
/**
* Finds the data of this binary representation. Calling this method is only legal for resolved instances.
* For non-resolved instances, an exception is thrown.
*
* @return The requested binary data. The returned array must not be altered.
*/
byte[] resolve();
/**
* A canonical representation of an illegal binary representation.
*/
@EqualsAndHashCode
class Illegal implements Resolution {
/**
* The name of the unresolved class file.
*/
private final String typeName;
/**
* Creates an illegal resolution for a class file.
*
* @param typeName The name of the unresolved class file.
*/
public Illegal(String typeName) {
this.typeName = typeName;
}
@Override
public boolean isResolved() {
return false;
}
@Override
public byte[] resolve() {
throw new IllegalStateException("Could not locate class file for " + typeName);
}
}
/**
* Represents a byte array as binary data.
*/
@EqualsAndHashCode
class Explicit implements Resolution {
/**
* The represented data.
*/
private final byte[] binaryRepresentation;
/**
* Creates a new explicit resolution of a given array of binary data.
*
* @param binaryRepresentation The binary data to represent. The array must not be modified.
*/
@SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not to be modified by contract")
public Explicit(byte[] binaryRepresentation) {
this.binaryRepresentation = binaryRepresentation;
}
@Override
public boolean isResolved() {
return true;
}
@Override
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not to be modified by contract")
public byte[] resolve() {
return binaryRepresentation;
}
}
}
/**
* A class file locator that cannot locate any class files.
*/
enum NoOp implements ClassFileLocator {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Resolution locate(String typeName) {
return new Resolution.Illegal(typeName);
}
@Override
public void close() throws IOException {
/* do nothing */
}
}
/**
* A simple class file locator that returns class files from a selection of given types.
*/
@EqualsAndHashCode
class Simple implements ClassFileLocator {
/**
* The class files that are known to this class file locator mapped by their type name.
*/
private final Map classFiles;
/**
* Creates a new simple class file locator.
*
* @param classFiles The class files that are known to this class file locator mapped by their type name.
*/
public Simple(Map classFiles) {
this.classFiles = classFiles;
}
/**
* Creates a class file locator for a single known type.
*
* @param typeName The name of the type.
* @param binaryRepresentation The binary representation of the type.
* @return An appropriate class file locator.
*/
public static ClassFileLocator of(String typeName, byte[] binaryRepresentation) {
return new Simple(Collections.singletonMap(typeName, binaryRepresentation));
}
/**
* Creates a class file locator for a single known type with an additional fallback locator.
*
* @param typeName The name of the type.
* @param binaryRepresentation The binary representation of the type.
* @param fallback The class file locator to query in case that a lookup triggers any other type.
* @return An appropriate class file locator.
*/
public static ClassFileLocator of(String typeName, byte[] binaryRepresentation, ClassFileLocator fallback) {
return new Compound(new Simple(Collections.singletonMap(typeName, binaryRepresentation)), fallback);
}
/**
* Creates a class file locator that represents all types of a dynamic type.
*
* @param dynamicType The dynamic type to represent.
* @return A class file locator representing the dynamic type's types.
*/
public static ClassFileLocator of(DynamicType dynamicType) {
return of(dynamicType.getAllTypes());
}
/**
* Creates a class file locator that represents all types of a dynamic type.
*
* @param binaryRepresentations The binary representation of all types.
* @return A class file locator representing the dynamic type's types.
*/
public static ClassFileLocator of(Map binaryRepresentations) {
Map classFiles = new HashMap();
for (Map.Entry entry : binaryRepresentations.entrySet()) {
classFiles.put(entry.getKey().getName(), entry.getValue());
}
return new Simple(classFiles);
}
@Override
public Resolution locate(String typeName) {
byte[] binaryRepresentation = classFiles.get(typeName);
return binaryRepresentation == null
? new Resolution.Illegal(typeName)
: new Resolution.Explicit(binaryRepresentation);
}
@Override
public void close() {
/* do nothing */
}
}
/**
*
* A class file locator that queries a class loader for binary representations of class files.
*
*
* Important: Even when calling {@link Closeable#close()} on this class file locator, no underlying
* class loader is closed if it implements the {@link Closeable} interface as this is typically not intended.
*
*/
@EqualsAndHashCode
class ForClassLoader implements ClassFileLocator {
/**
* The class loader to query.
*/
private final ClassLoader classLoader;
/**
* Creates a new class file locator for the given class loader.
*
* @param classLoader The class loader to query which must not be the bootstrap class loader, i.e. {@code null}.
*/
protected ForClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
/**
* Creates a class file locator that queries the system class loader.
*
* @return A class file locator that queries the system class loader.
*/
public static ClassFileLocator ofClassPath() {
return new ForClassLoader(ClassLoader.getSystemClassLoader());
}
/**
* Creates a class file locator for a given class loader.
*
* @param classLoader The class loader to be used. If this class loader represents the bootstrap class
* loader which is represented by the {@code null} value, this system class loader
* is used instead.
* @return A corresponding source locator.
*/
public static ClassFileLocator of(ClassLoader classLoader) {
return new ForClassLoader(classLoader == null
? ClassLoader.getSystemClassLoader()
: classLoader);
}
/**
* Attempts to create a binary representation of a loaded type by requesting data from its
* {@link java.lang.ClassLoader}.
*
* @param type The type of interest.
* @return The binary data to this type which might be illegal.
*/
public static Resolution read(Class> type) {
try {
ClassLoader classLoader = type.getClassLoader();
return locate(classLoader == null
? ClassLoader.getSystemClassLoader()
: classLoader, TypeDescription.ForLoadedType.getName(type));
} catch (IOException exception) {
throw new IllegalStateException("Cannot read class file for " + type, exception);
}
}
@Override
public Resolution locate(String typeName) throws IOException {
return locate(classLoader, typeName);
}
@Override
public void close() throws IOException {
/* do nothing */
}
/**
* Locates the class file for the supplied type by requesting a resource from the class loader.
*
* @param classLoader The class loader to query for the resource.
* @param typeName The name of the type for which to locate a class file.
* @return A resolution for the class file.
* @throws IOException If reading the class file causes an exception.
*/
protected static Resolution locate(ClassLoader classLoader, String typeName) throws IOException {
InputStream inputStream = classLoader.getResourceAsStream(typeName.replace('.', '/') + CLASS_FILE_EXTENSION);
if (inputStream != null) {
try {
return new Resolution.Explicit(StreamDrainer.DEFAULT.drain(inputStream));
} finally {
inputStream.close();
}
} else {
return new Resolution.Illegal(typeName);
}
}
/**
*
* A class file locator that queries a class loader for binary representations of class files.
* The class loader is only weakly referenced.
*
*
* Important: Even when calling {@link Closeable#close()} on this class file locator, no underlying
* class loader is closed if it implements the {@link Closeable} interface as this is typically not intended.
*
*/
public static class WeaklyReferenced extends WeakReference implements ClassFileLocator {
/**
* The represented class loader's hash code.
*/
private final int hashCode;
/**
* Creates a class file locator for a class loader that is weakly referenced.
*
* @param classLoader The class loader to represent.
*/
protected WeaklyReferenced(ClassLoader classLoader) {
super(classLoader);
hashCode = System.identityHashCode(classLoader);
}
/**
* Creates a class file locator for a given class loader. If the class loader is not the bootstrap
* class loader or the system class loader which cannot be collected, the class loader is only weakly
* referenced.
*
* @param classLoader The class loader to be used. If this class loader represents the bootstrap class
* loader which is represented by the {@code null} value, this system class loader
* is used instead.
* @return A corresponding source locator.
*/
public static ClassFileLocator of(ClassLoader classLoader) {
return classLoader == null || classLoader == ClassLoader.getSystemClassLoader() || classLoader == ClassLoader.getSystemClassLoader().getParent()
? ForClassLoader.of(classLoader)
: new WeaklyReferenced(classLoader);
}
@Override
public Resolution locate(String typeName) throws IOException {
ClassLoader classLoader = get();
return classLoader == null
? new Resolution.Illegal(typeName)
: ForClassLoader.locate(classLoader, typeName);
}
@Override
public void close() throws IOException {
/* do nothing */
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
WeaklyReferenced that = (WeaklyReferenced) object;
ClassLoader classLoader = that.get();
return classLoader != null && get() == classLoader;
}
}
}
/**
*
* A class file locator that locates class files by querying a Java module's {@code getResourceAsStream} method.
*
*
* Important: Even when calling {@link Closeable#close()} on this class file locator, no underlying
* class loader is closed if it implements the {@link Closeable} interface as this is typically not intended.
*
*/
@EqualsAndHashCode
class ForModule implements ClassFileLocator {
/**
* The represented Java module.
*/
private final JavaModule module;
/**
* Creates a new class file locator for a Java module.
*
* @param module The represented Java module.
*/
protected ForModule(JavaModule module) {
this.module = module;
}
/**
* Returns a class file locator that exposes all class files of the boot module layer. This class file locator is only available
* on virtual machines of version 9 or later. On earlier versions, the returned class file locator does not locate any resources.
*
* @return A class file locator that locates classes of the boot layer.
*/
@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception is supposed to be rethrown")
public static ClassFileLocator ofBootLayer() {
try {
Map bootModules = new HashMap();
Class> layerType = Class.forName("java.lang.ModuleLayer");
Method getPackages = JavaType.MODULE.load().getMethod("getPackages");
for (Object rawModule : (Set>) layerType.getMethod("modules").invoke(layerType.getMethod("boot").invoke(null))) {
ClassFileLocator classFileLocator = ForModule.of(JavaModule.of(rawModule));
for (Object packageName : (Set>) getPackages.invoke(rawModule)) {
bootModules.put((String) packageName, classFileLocator);
}
}
return new PackageDiscriminating(bootModules);
} catch (Exception exception) {
throw new IllegalStateException("Cannot process boot layer", exception);
}
}
/**
* Returns a class file locator for the provided module. If the provided module is not named, class files are located via this
* unnamed module's class loader.
*
* @param module The module to create a class file locator for.
* @return An appropriate class file locator.
*/
public static ClassFileLocator of(JavaModule module) {
return module.isNamed()
? new ForModule(module)
: ForClassLoader.of(module.getClassLoader());
}
@Override
public Resolution locate(String typeName) throws IOException {
return locate(module, typeName);
}
/**
* Creates a resolution for a Java module's class files.
*
* @param module The Java module to query.
* @param typeName The name of the type being queried.
* @return A resolution for the query.
* @throws IOException If an I/O exception was thrown.
*/
protected static Resolution locate(JavaModule module, String typeName) throws IOException {
InputStream inputStream = module.getResourceAsStream(typeName.replace('.', '/') + CLASS_FILE_EXTENSION);
if (inputStream != null) {
try {
return new Resolution.Explicit(StreamDrainer.DEFAULT.drain(inputStream));
} finally {
inputStream.close();
}
} else {
return new Resolution.Illegal(typeName);
}
}
@Override
public void close() throws IOException {
/* do nothing */
}
/**
*
* A class file locator for a Java module that only references this module weakly. If a module was garbage collected,
* this class file locator only returns unresolved resolutions.
*
*
* Important: Even when calling {@link Closeable#close()} on this class file locator, no underlying
* class loader is closed if it implements the {@link Closeable} interface as this is typically not intended.
*
*/
public static class WeaklyReferenced extends WeakReference