// Generated by delombok at Sun Feb 26 12:31:38 KST 2017 package scouter.bytebuddy.utility; import scouter.bytebuddy.description.NamedElement; import java.io.InputStream; import java.lang.instrument.Instrumentation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Map; import java.util.Set; /** * Type-safe representation of a {@code java.lang.reflect.Module}. On platforms that do not support the module API, modules are represented by {@code null}. */ public class JavaModule implements NamedElement.WithOptionalName { /** * Canonical representation of a Java module on a JVM that does not support the module API. */ public static final JavaModule UNSUPPORTED = null; /** * The dispatcher to use for accessing Java modules, if available. */ private static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE); /** * The {@code java.lang.reflect.Module} instance this wrapper represents. */ private final Object module; /** * Creates a new Java module representation. * * @param module The {@code java.lang.reflect.Module} instance this wrapper represents. */ protected JavaModule(Object module) { this.module = module; } /** * Returns a representation of the supplied type's {@code java.lang.reflect.Module} or {@code null} if the current VM does not support modules. * * @param type The type for which to describe the module. * @return A representation of the type's module or {@code null} if the current VM does not support modules. */ public static JavaModule ofType(Class<?> type) { return DISPATCHER.moduleOf(type); } /** * Represents the supplied {@code java.lang.reflect.Module} as an instance of this class and validates that the * supplied instance really represents a Java {@code Module}. * * @param module The module to represent. * @return A representation of the supplied Java module. */ public static JavaModule of(Object module) { if (!JavaType.MODULE.getTypeStub().isInstance(module)) { throw new IllegalArgumentException("Not a Java module: " + module); } return new JavaModule(module); } /** * Checks if the current VM supports the {@code java.lang.reflect.Module} API. * * @return {@code true} if the current VM supports modules. */ public static boolean isSupported() { return DISPATCHER.isAlive(); } @Override public boolean isNamed() { return DISPATCHER.isNamed(module); } @Override public String getActualName() { return DISPATCHER.getName(module); } /** * Returns a resource stream for this module for a resource of the given name or {@code null} if such a resource does not exist. * * @param name The name of the resource. * @return An input stream for the resource or {@code null} if it does not exist. */ public InputStream getResourceAsStream(String name) { return DISPATCHER.getResourceAsStream(module, name); } /** * Returns the class loader of this module. * * @return The class loader of the represented module. */ public ClassLoader getClassLoader() { return DISPATCHER.getClassLoader(module); } /** * Unwraps this instance to a {@code java.lang.reflect.Module}. * * @return The represented {@code java.lang.reflect.Module}. */ public Object unwrap() { return module; } /** * Checks if this module can read the exported packages of the supplied module. * * @param module The module to check for its readability by this module. * @return {@code true} if this module can read the supplied module. */ public boolean canRead(JavaModule module) { return DISPATCHER.canRead(this.module, module.unwrap()); } /** * Adds a read-edge to this module to the supplied module using the instrumentation API. * * @param instrumentation The instrumentation instance to use for adding the edge. * @param module The module to add as a read dependency to this module. */ public void addReads(Instrumentation instrumentation, JavaModule module) { DISPATCHER.addReads(instrumentation, this.module, module.unwrap()); } @Override public boolean equals(Object other) { if (this == other) return true; if (!(other instanceof JavaModule)) return false; JavaModule that = (JavaModule) other; return module.equals(that.module); } @Override public int hashCode() { return module.hashCode(); } @Override public String toString() { return module.toString(); } /** * A dispatcher for accessing the {@code java.lang.reflect.Module} API if it is available on the current VM. */ protected interface Dispatcher { /** * Checks if this dispatcher is alive, i.e. supports modules. * * @return {@code true} if modules are supported on the current VM. */ boolean isAlive(); /** * Extracts the Java {@code Module} for the provided class or returns {@code null} if the current VM does not support modules. * * @param type The type for which to extract the module. * @return The class's {@code Module} or {@code null} if the current VM does not support modules. */ JavaModule moduleOf(Class<?> type); /** * Returns {@code true} if the supplied module is named. * * @param module The {@code java.lang.reflect.Module} to check for the existence of a name. * @return {@code true} if the supplied module is named. */ boolean isNamed(Object module); /** * Returns the module's name. * * @param module The {@code java.lang.reflect.Module} to check for its name. * @return The module's (implicit or explicit) name. */ String getName(Object module); /** * Returns a resource stream for this module for a resource of the given name or {@code null} if such a resource does not exist. * * @param module The {@code java.lang.reflect.Module} instance to apply this method upon. * @param name The name of the resource. * @return An input stream for the resource or {@code null} if it does not exist. */ InputStream getResourceAsStream(Object module, String name); /** * Returns the module's class loader. * * @param module The {@code java.lang.reflect.Module} * @return The module's class loader. */ ClassLoader getClassLoader(Object module); /** * Checks if the source module can read the target module. * * @param source The source module. * @param target The target module. * @return {@code true} if the source module can read the target module. */ boolean canRead(Object source, Object target); /** * Adds a read-edge from the source to the target module. * * @param instrumentation The instrumentation instance to use for adding the edge. * @param source The source module. * @param target The target module. */ void addReads(Instrumentation instrumentation, Object source, Object target); /** * A creation action for a dispatcher. */ enum CreationAction implements PrivilegedAction<Dispatcher> { /** * The singleton instance. */ INSTANCE; @Override public Dispatcher run() { try { Class<?> module = Class.forName("java.lang.reflect.Module"); return new Dispatcher.Enabled(Class.class.getMethod("getModule"), module.getMethod("getClassLoader"), module.getMethod("isNamed"), module.getMethod("getName"), module.getMethod("getResourceAsStream", String.class), module.getMethod("canRead", module), Instrumentation.class.getMethod("redefineModule", module, Set.class, Map.class, Map.class, Set.class, Map.class)); } catch (Exception ignored) { return Dispatcher.Disabled.INSTANCE; } } } /** * A dispatcher for a VM that does support the {@code java.lang.reflect.Module} API. */ class Enabled implements Dispatcher { /** * The {@code java.lang.Class#getModule()} method. */ private final Method getModule; /** * The {@code java.lang.reflect.Module#getClassLoader()} method. */ private final Method getClassLoader; /** * The {@code java.lang.reflect.Module#isNamed()} method. */ private final Method isNamed; /** * The {@code java.lang.reflect.Module#getName()} method. */ private final Method getName; /** * The {@code java.lang.reflect.Module#getResourceAsStream(String)} method. */ private final Method getResourceAsStream; /** * The {@code java.lang.reflect.Module#canRead(Module)} method. */ private final Method canRead; /** * The {@code java.lang.instrument.Instrumentation#redefineModule} method. */ private final Method redefineModule; /** * Creates an enabled dispatcher. * * @param getModule The {@code java.lang.Class#getModule()} method. * @param getClassLoader The {@code java.lang.reflect.Module#getClassLoader()} method. * @param isNamed The {@code java.lang.reflect.Module#isNamed()} method. * @param getName The {@code java.lang.reflect.Module#getName()} method. * @param getResourceAsStream The {@code java.lang.reflect.Module#getResourceAsStream(String)} method. * @param canRead The {@code java.lang.reflect.Module#canRead(Module)} method. * @param redefineModule The {@code java.lang.instrument.Instrumentation#redefineModule} method. */ protected Enabled(Method getModule, Method getClassLoader, Method isNamed, Method getName, Method getResourceAsStream, Method canRead, Method redefineModule) { this.getModule = getModule; this.getClassLoader = getClassLoader; this.isNamed = isNamed; this.getName = getName; this.getResourceAsStream = getResourceAsStream; this.canRead = canRead; this.redefineModule = redefineModule; } @Override public boolean isAlive() { return true; } @Override public JavaModule moduleOf(Class<?> type) { try { return new JavaModule(getModule.invoke(type)); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getModule, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getModule, exception.getCause()); } } @Override public InputStream getResourceAsStream(Object module, String name) { try { return (InputStream) getResourceAsStream.invoke(module, name); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getResourceAsStream, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getResourceAsStream, exception.getCause()); } } @Override public ClassLoader getClassLoader(Object module) { try { return (ClassLoader) getClassLoader.invoke(module); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getClassLoader, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getClassLoader, exception.getCause()); } } @Override public boolean isNamed(Object module) { try { return (Boolean) isNamed.invoke(module); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + isNamed, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + isNamed, exception.getCause()); } } @Override public String getName(Object module) { try { return (String) getName.invoke(module); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getName, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getName, exception.getCause()); } } @Override public boolean canRead(Object source, Object target) { try { return (Boolean) canRead.invoke(source, target); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + canRead, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + canRead, exception.getCause()); } } @Override public void addReads(Instrumentation instrumentation, Object source, Object target) { try { redefineModule.invoke(instrumentation, source, Collections.singleton(target), Collections.emptyMap(), Collections.emptyMap(), Collections.emptySet(), Collections.emptyMap()); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + redefineModule, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + redefineModule, exception.getCause()); } } @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") public boolean equals(final java.lang.Object o) { if (o == this) return true; if (!(o instanceof JavaModule.Dispatcher.Enabled)) return false; final JavaModule.Dispatcher.Enabled other = (JavaModule.Dispatcher.Enabled) o; if (!other.canEqual((java.lang.Object) this)) return false; final java.lang.Object this$getModule = this.getModule; final java.lang.Object other$getModule = other.getModule; if (this$getModule == null ? other$getModule != null : !this$getModule.equals(other$getModule)) return false; final java.lang.Object this$getClassLoader = this.getClassLoader; final java.lang.Object other$getClassLoader = other.getClassLoader; if (this$getClassLoader == null ? other$getClassLoader != null : !this$getClassLoader.equals(other$getClassLoader)) return false; final java.lang.Object this$isNamed = this.isNamed; final java.lang.Object other$isNamed = other.isNamed; if (this$isNamed == null ? other$isNamed != null : !this$isNamed.equals(other$isNamed)) return false; final java.lang.Object this$getName = this.getName; final java.lang.Object other$getName = other.getName; if (this$getName == null ? other$getName != null : !this$getName.equals(other$getName)) return false; final java.lang.Object this$getResourceAsStream = this.getResourceAsStream; final java.lang.Object other$getResourceAsStream = other.getResourceAsStream; if (this$getResourceAsStream == null ? other$getResourceAsStream != null : !this$getResourceAsStream.equals(other$getResourceAsStream)) return false; final java.lang.Object this$canRead = this.canRead; final java.lang.Object other$canRead = other.canRead; if (this$canRead == null ? other$canRead != null : !this$canRead.equals(other$canRead)) return false; final java.lang.Object this$redefineModule = this.redefineModule; final java.lang.Object other$redefineModule = other.redefineModule; if (this$redefineModule == null ? other$redefineModule != null : !this$redefineModule.equals(other$redefineModule)) return false; return true; } @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") protected boolean canEqual(final java.lang.Object other) { return other instanceof JavaModule.Dispatcher.Enabled; } @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") public int hashCode() { final int PRIME = 59; int result = 1; final java.lang.Object $getModule = this.getModule; result = result * PRIME + ($getModule == null ? 43 : $getModule.hashCode()); final java.lang.Object $getClassLoader = this.getClassLoader; result = result * PRIME + ($getClassLoader == null ? 43 : $getClassLoader.hashCode()); final java.lang.Object $isNamed = this.isNamed; result = result * PRIME + ($isNamed == null ? 43 : $isNamed.hashCode()); final java.lang.Object $getName = this.getName; result = result * PRIME + ($getName == null ? 43 : $getName.hashCode()); final java.lang.Object $getResourceAsStream = this.getResourceAsStream; result = result * PRIME + ($getResourceAsStream == null ? 43 : $getResourceAsStream.hashCode()); final java.lang.Object $canRead = this.canRead; result = result * PRIME + ($canRead == null ? 43 : $canRead.hashCode()); final java.lang.Object $redefineModule = this.redefineModule; result = result * PRIME + ($redefineModule == null ? 43 : $redefineModule.hashCode()); return result; } } /** * A disabled dispatcher for a VM that does not support the {@code java.lang.reflect.Module} API. */ enum Disabled implements Dispatcher { /** * The singleton instance. */ INSTANCE; @Override public boolean isAlive() { return false; } @Override public JavaModule moduleOf(Class<?> type) { return UNSUPPORTED; } @Override public ClassLoader getClassLoader(Object module) { throw new IllegalStateException("Current VM does not support modules"); } @Override public boolean isNamed(Object module) { throw new IllegalStateException("Current VM does not support modules"); } @Override public String getName(Object module) { throw new IllegalStateException("Current VM does not support modules"); } @Override public InputStream getResourceAsStream(Object module, String name) { throw new IllegalStateException("Current VM does not support modules"); } @Override public boolean canRead(Object source, Object target) { throw new IllegalStateException("Current VM does not support modules"); } @Override public void addReads(Instrumentation instrumentation, Object source, Object target) { throw new IllegalStateException("Current VM does not support modules"); } } } }