// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.dynamic.scaffold.subclass;
import scouter.bytebuddy.ClassFileVersion;
import scouter.bytebuddy.asm.AsmVisitorWrapper;
import scouter.bytebuddy.description.method.MethodDescription;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.dynamic.DynamicType;
import scouter.bytebuddy.dynamic.TypeResolutionStrategy;
import scouter.bytebuddy.dynamic.scaffold.*;
import scouter.bytebuddy.implementation.Implementation;
import scouter.bytebuddy.implementation.attribute.AnnotationRetention;
import scouter.bytebuddy.implementation.attribute.AnnotationValueFilter;
import scouter.bytebuddy.implementation.attribute.TypeAttributeAppender;
import scouter.bytebuddy.implementation.auxiliary.AuxiliaryType;
import scouter.bytebuddy.matcher.ElementMatcher;
import scouter.bytebuddy.matcher.LatentMatcher;
import scouter.bytebuddy.pool.TypePool;
import static scouter.bytebuddy.matcher.ElementMatchers.*;
/**
* A type builder that creates an instrumented type as a subclass, i.e. a type that is not based on an existing class file.
*
* @param <T> A loaded type that the dynamic type is guaranteed to be a subtype of.
*/
public class SubclassDynamicTypeBuilder<T> extends DynamicType.Builder.AbstractBase.Adapter<T> {
/**
* The constructor strategy to apply onto the instrumented type.
*/
private final ConstructorStrategy constructorStrategy;
/**
* Creates a new type builder for creating a subclass.
*
* @param instrumentedType An instrumented type representing the subclass.
* @param classFileVersion The class file version to use for types that are not based on an existing class file.
* @param auxiliaryTypeNamingStrategy The naming strategy to use for naming auxiliary types.
* @param annotationValueFilterFactory The annotation value filter factory to use.
* @param annotationRetention The annotation retention strategy to use.
* @param implementationContextFactory The implementation context factory to use.
* @param methodGraphCompiler The method graph compiler to use.
* @param typeValidation Determines if a type should be explicitly validated.
* @param ignoredMethods A matcher for identifying methods that should be excluded from instrumentation.
* @param constructorStrategy The constructor strategy to apply onto the instrumented type.
*/
public SubclassDynamicTypeBuilder(InstrumentedType.WithFlexibleName instrumentedType, ClassFileVersion classFileVersion, AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy, AnnotationValueFilter.Factory annotationValueFilterFactory, AnnotationRetention annotationRetention, Implementation.Context.Factory implementationContextFactory, MethodGraph.Compiler methodGraphCompiler, TypeValidation typeValidation, LatentMatcher<? super MethodDescription> ignoredMethods, ConstructorStrategy constructorStrategy) {
this(instrumentedType, new FieldRegistry.Default(), new MethodRegistry.Default(), TypeAttributeAppender.ForInstrumentedType.INSTANCE, AsmVisitorWrapper.NoOp.INSTANCE, classFileVersion, auxiliaryTypeNamingStrategy, annotationValueFilterFactory, annotationRetention, implementationContextFactory, methodGraphCompiler, typeValidation, ignoredMethods, constructorStrategy);
}
/**
* Creates a new type builder for creating a subclass.
*
* @param instrumentedType An instrumented type representing the subclass.
* @param fieldRegistry The field pool to use.
* @param methodRegistry The method pool to use.
* @param typeAttributeAppender The type attribute appender to apply onto the instrumented type.
* @param asmVisitorWrapper The ASM visitor wrapper to apply onto the class writer.
* @param classFileVersion The class file version to use for types that are not based on an existing class file.
* @param auxiliaryTypeNamingStrategy The naming strategy to use for naming auxiliary types.
* @param annotationValueFilterFactory The annotation value filter factory to use.
* @param annotationRetention The annotation retention strategy to use.
* @param implementationContextFactory The implementation context factory to use.
* @param methodGraphCompiler The method graph compiler to use.
* @param typeValidation Determines if a type should be explicitly validated.
* @param ignoredMethods A matcher for identifying methods that should be excluded from instrumentation.
* @param constructorStrategy The constructor strategy to apply onto the instrumented type.
*/
protected SubclassDynamicTypeBuilder(InstrumentedType.WithFlexibleName instrumentedType, FieldRegistry fieldRegistry, MethodRegistry methodRegistry, TypeAttributeAppender typeAttributeAppender, AsmVisitorWrapper asmVisitorWrapper, ClassFileVersion classFileVersion, AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy, AnnotationValueFilter.Factory annotationValueFilterFactory, AnnotationRetention annotationRetention, Implementation.Context.Factory implementationContextFactory, MethodGraph.Compiler methodGraphCompiler, TypeValidation typeValidation, LatentMatcher<? super MethodDescription> ignoredMethods, ConstructorStrategy constructorStrategy) {
super(instrumentedType, fieldRegistry, methodRegistry, typeAttributeAppender, asmVisitorWrapper, classFileVersion, auxiliaryTypeNamingStrategy, annotationValueFilterFactory, annotationRetention, implementationContextFactory, methodGraphCompiler, typeValidation, ignoredMethods);
this.constructorStrategy = constructorStrategy;
}
@Override
protected DynamicType.Builder<T> materialize(InstrumentedType.WithFlexibleName instrumentedType, FieldRegistry fieldRegistry, MethodRegistry methodRegistry, TypeAttributeAppender typeAttributeAppender, AsmVisitorWrapper asmVisitorWrapper, ClassFileVersion classFileVersion, AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy, AnnotationValueFilter.Factory annotationValueFilterFactory, AnnotationRetention annotationRetention, Implementation.Context.Factory implementationContextFactory, MethodGraph.Compiler methodGraphCompiler, TypeValidation typeValidation, LatentMatcher<? super MethodDescription> ignoredMethods) {
return new SubclassDynamicTypeBuilder<T>(instrumentedType, fieldRegistry, methodRegistry, typeAttributeAppender, asmVisitorWrapper, classFileVersion, auxiliaryTypeNamingStrategy, annotationValueFilterFactory, annotationRetention, implementationContextFactory, methodGraphCompiler, typeValidation, ignoredMethods, constructorStrategy);
}
@Override
public DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy) {
return make(typeResolutionStrategy, TypePool.ClassLoading.ofClassPath()); // Mimics the default behavior of ASM for least surprise.
}
@Override
public DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
MethodRegistry.Compiled methodRegistry = constructorStrategy.inject(this.methodRegistry).prepare(applyConstructorStrategy(instrumentedType), methodGraphCompiler, typeValidation, new InstrumentableMatcher(ignoredMethods)).compile(SubclassImplementationTarget.Factory.SUPER_CLASS, classFileVersion);
return TypeWriter.Default.<T>forCreation(methodRegistry, fieldRegistry.compile(methodRegistry.getInstrumentedType()), typeAttributeAppender, asmVisitorWrapper, classFileVersion, annotationValueFilterFactory, annotationRetention, auxiliaryTypeNamingStrategy, implementationContextFactory, typeValidation, typePool).make(typeResolutionStrategy.resolve());
}
/**
* Applies this builder's constructor strategy to the given instrumented type.
*
* @param instrumentedType The instrumented type to apply the constructor onto.
* @return The instrumented type with the constructor strategy applied onto.
*/
private InstrumentedType applyConstructorStrategy(InstrumentedType instrumentedType) {
if (!instrumentedType.isInterface()) {
for (MethodDescription.Token token : constructorStrategy.extractConstructors(instrumentedType)) {
instrumentedType = instrumentedType.withMethod(token);
}
}
return instrumentedType;
}
/**
* A matcher that locates all methods that are overridable and not ignored or that are directly defined on the instrumented type.
*/
protected static class InstrumentableMatcher implements LatentMatcher<MethodDescription> {
/**
* A matcher for the ignored methods.
*/
private final LatentMatcher<? super MethodDescription> ignoredMethods;
/**
* Creates a latent method matcher that matches all methods that are to be instrumented by a {@link SubclassDynamicTypeBuilder}.
*
* @param ignoredMethods A matcher for the ignored methods.
*/
protected InstrumentableMatcher(LatentMatcher<? super MethodDescription> ignoredMethods) {
this.ignoredMethods = ignoredMethods;
}
@Override
public ElementMatcher<? super MethodDescription> resolve(TypeDescription typeDescription) {
// Casting is required by JDK 6.
return (ElementMatcher<? super MethodDescription>) isVirtual().and(not(isFinal()))
.and(isVisibleTo(typeDescription))
.and(not(ignoredMethods.resolve(typeDescription)))
.or(isDeclaredBy(typeDescription));
}
@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 SubclassDynamicTypeBuilder.InstrumentableMatcher)) return false;
final SubclassDynamicTypeBuilder.InstrumentableMatcher other = (SubclassDynamicTypeBuilder.InstrumentableMatcher) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$ignoredMethods = this.ignoredMethods;
final java.lang.Object other$ignoredMethods = other.ignoredMethods;
if (this$ignoredMethods == null ? other$ignoredMethods != null : !this$ignoredMethods.equals(other$ignoredMethods)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof SubclassDynamicTypeBuilder.InstrumentableMatcher;
}
@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 $ignoredMethods = this.ignoredMethods;
result = result * PRIME + ($ignoredMethods == null ? 43 : $ignoredMethods.hashCode());
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 SubclassDynamicTypeBuilder)) return false;
final SubclassDynamicTypeBuilder<?> other = (SubclassDynamicTypeBuilder<?>) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (!super.equals(o)) return false;
final java.lang.Object this$constructorStrategy = this.constructorStrategy;
final java.lang.Object other$constructorStrategy = other.constructorStrategy;
if (this$constructorStrategy == null ? other$constructorStrategy != null : !this$constructorStrategy.equals(other$constructorStrategy)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof SubclassDynamicTypeBuilder;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + super.hashCode();
final java.lang.Object $constructorStrategy = this.constructorStrategy;
result = result * PRIME + ($constructorStrategy == null ? 43 : $constructorStrategy.hashCode());
return result;
}
}