// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.dynamic;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import scouter.bytebuddy.dynamic.scaffold.TypeInitializer;
import scouter.bytebuddy.implementation.LoadedTypeInitializer;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* A type resolution strategy is responsible for loading a class and for initializing its {@link LoadedTypeInitializer}s.
*/
public interface TypeResolutionStrategy {
/**
* Resolves a type resolution strategy for actual application.
*
* @return A resolved version of this type resolution strategy.
*/
Resolved resolve();
/**
* A resolved {@link TypeResolutionStrategy}.
*/
interface Resolved {
/**
* Injects a type initializer into the supplied type initializer, if applicable. This way, a type resolution
* strategy is capable of injecting code into the generated class's initializer to inline the initialization.
*
* @param typeInitializer The type initializer to potentially expend.
* @return A type initializer to apply for performing the represented type resolution.
*/
TypeInitializer injectedInto(TypeInitializer typeInitializer);
/**
* Loads and initializes a dynamic type.
*
* @param dynamicType The dynamic type to initialize.
* @param classLoader The class loader to use.
* @param classLoadingStrategy The class loading strategy to use.
* @param <S> The least specific type of class loader this strategy can apply to.
* @return A map of all type descriptions mapped to their representation as a loaded class.
*/
<S extends ClassLoader> Map<TypeDescription, Class<?>> initialize(DynamicType dynamicType, S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
}
/**
* A type resolution strategy that applies all {@link LoadedTypeInitializer} after class loading using reflection. This implies that the initializers
* are executed <b>after</b> a type initializer is executed.
*/
enum Passive implements TypeResolutionStrategy, Resolved {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Resolved resolve() {
return this;
}
@Override
public TypeInitializer injectedInto(TypeInitializer typeInitializer) {
return typeInitializer;
}
@Override
public <S extends ClassLoader> Map<TypeDescription, Class<?>> initialize(DynamicType dynamicType, S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
Map<TypeDescription, Class<?>> types = classLoadingStrategy.load(classLoader, dynamicType.getAllTypes());
for (Map.Entry<TypeDescription, LoadedTypeInitializer> entry : dynamicType.getLoadedTypeInitializers().entrySet()) {
entry.getValue().onLoad(types.get(entry.getKey()));
}
return new HashMap<TypeDescription, Class<?>>(types);
}
}
/**
* A type resolution strategy that applies all {@link LoadedTypeInitializer} as a part of class loading using reflection. This implies that the initializers
* are executed <b>before</b> (as a first action of) a type initializer is executed.
*/
class Active implements TypeResolutionStrategy {
/**
* The nexus accessor to use.
*/
private final NexusAccessor nexusAccessor;
/**
* Creates a new active type resolution strategy that uses a default nexus accessor.
*/
public Active() {
this(new NexusAccessor());
}
/**
* Creates a new active type resolution strategy that uses the supplied nexus accessor.
*
* @param nexusAccessor The nexus accessor to use.
*/
public Active(NexusAccessor nexusAccessor) {
this.nexusAccessor = nexusAccessor;
}
@Override
public TypeResolutionStrategy.Resolved resolve() {
return new Resolved(nexusAccessor, new Random().nextInt());
}
/**
* A resolved version of an active type resolution strategy.
*/
protected static class Resolved implements TypeResolutionStrategy.Resolved {
/**
* The nexus accessor to use.
*/
private final NexusAccessor nexusAccessor;
/**
* The id used for identifying the loaded type initializer that was added to the {@link Nexus}.
*/
private final int identification;
/**
* Creates a new resolved active type resolution strategy.
*
* @param nexusAccessor The nexus accessor to use.
* @param identification The id used for identifying the loaded type initializer that was added to the {@link Nexus}.
*/
protected Resolved(NexusAccessor nexusAccessor, int identification) {
this.nexusAccessor = nexusAccessor;
this.identification = identification;
}
@Override
public TypeInitializer injectedInto(TypeInitializer typeInitializer) {
return typeInitializer.expandWith(new NexusAccessor.InitializationAppender(identification));
}
@Override
public <S extends ClassLoader> Map<TypeDescription, Class<?>> initialize(DynamicType dynamicType, S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
Map<TypeDescription, LoadedTypeInitializer> loadedTypeInitializers = new HashMap<TypeDescription, LoadedTypeInitializer>(dynamicType.getLoadedTypeInitializers());
TypeDescription instrumentedType = dynamicType.getTypeDescription();
Map<TypeDescription, Class<?>> types = classLoadingStrategy.load(classLoader, dynamicType.getAllTypes());
nexusAccessor.register(instrumentedType.getName(), types.get(instrumentedType).getClassLoader(), identification, loadedTypeInitializers.remove(instrumentedType));
for (Map.Entry<TypeDescription, LoadedTypeInitializer> entry : loadedTypeInitializers.entrySet()) {
entry.getValue().onLoad(types.get(entry.getKey()));
}
return types;
}
@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 TypeResolutionStrategy.Active.Resolved)) return false;
final TypeResolutionStrategy.Active.Resolved other = (TypeResolutionStrategy.Active.Resolved) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$nexusAccessor = this.nexusAccessor;
final java.lang.Object other$nexusAccessor = other.nexusAccessor;
if (this$nexusAccessor == null ? other$nexusAccessor != null : !this$nexusAccessor.equals(other$nexusAccessor)) return false;
if (this.identification != other.identification) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypeResolutionStrategy.Active.Resolved;
}
@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 $nexusAccessor = this.nexusAccessor;
result = result * PRIME + ($nexusAccessor == null ? 43 : $nexusAccessor.hashCode());
result = result * PRIME + this.identification;
return result;
}
}
@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 TypeResolutionStrategy.Active)) return false;
final TypeResolutionStrategy.Active other = (TypeResolutionStrategy.Active) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$nexusAccessor = this.nexusAccessor;
final java.lang.Object other$nexusAccessor = other.nexusAccessor;
if (this$nexusAccessor == null ? other$nexusAccessor != null : !this$nexusAccessor.equals(other$nexusAccessor)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypeResolutionStrategy.Active;
}
@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 $nexusAccessor = this.nexusAccessor;
result = result * PRIME + ($nexusAccessor == null ? 43 : $nexusAccessor.hashCode());
return result;
}
}
/**
* A type resolution strategy that does not apply any {@link LoadedTypeInitializer}s but only loads all types.
*/
enum Lazy implements TypeResolutionStrategy, Resolved {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Resolved resolve() {
return this;
}
@Override
public TypeInitializer injectedInto(TypeInitializer typeInitializer) {
return typeInitializer;
}
@Override
public <S extends ClassLoader> Map<TypeDescription, Class<?>> initialize(DynamicType dynamicType, S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
return classLoadingStrategy.load(classLoader, dynamicType.getAllTypes());
}
}
/**
* A type resolution strategy that does not allow for explicit loading of a class and that does not inject any code into the type initializer.
*/
enum Disabled implements TypeResolutionStrategy, Resolved {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Resolved resolve() {
return this;
}
@Override
public TypeInitializer injectedInto(TypeInitializer typeInitializer) {
return typeInitializer;
}
@Override
public <S extends ClassLoader> Map<TypeDescription, Class<?>> initialize(DynamicType dynamicType, S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
throw new IllegalStateException("Cannot initialize a dynamic type for a disabled type resolution strategy");
}
}
}