// Generated by delombok at Sun Feb 26 12:31:38 KST 2017 package scouter.bytebuddy.dynamic.scaffold.subclass; import scouter.bytebuddy.description.method.MethodDescription; import scouter.bytebuddy.description.method.MethodList; import scouter.bytebuddy.description.type.TypeDescription; import scouter.bytebuddy.dynamic.Transformer; import scouter.bytebuddy.dynamic.scaffold.MethodRegistry; import scouter.bytebuddy.implementation.SuperMethodCall; import scouter.bytebuddy.implementation.attribute.MethodAttributeAppender; import scouter.bytebuddy.matcher.LatentMatcher; import scouter.bytebuddy.jar.asm.Opcodes; import scouter.bytebuddy.matcher.ElementMatchers; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static scouter.bytebuddy.matcher.ElementMatchers.*; /** * A constructor strategy is responsible for creating bootstrap constructors for a * {@link SubclassDynamicTypeBuilder}. * * @see ConstructorStrategy.Default */ public interface ConstructorStrategy { /** * Extracts constructors for a given super type. The extracted constructor signatures will then be imitated by the * created dynamic type. * * @param instrumentedType The type for which the constructors should be created. * @return A list of tokens that describe the constructors that are to be implemented. */ List<MethodDescription.Token> extractConstructors(TypeDescription instrumentedType); /** * Returns a method registry that is capable of creating byte code for the constructors that were * provided by the * {@link ConstructorStrategy#extractConstructors(TypeDescription)} * method of this instance. * * @param methodRegistry The original method registry. * @return A method registry that is capable of providing byte code for the constructors that were added by this strategy. */ MethodRegistry inject(MethodRegistry methodRegistry); /** * Default implementations of constructor strategies. Any such strategy offers to additionally apply an {@link MethodAttributeAppender.Factory}. */ enum Default implements ConstructorStrategy { /** * This strategy is adding no constructors such that the instrumented type will by default not have any. This * is legal by Java byte code requirements. However, if no constructor is added manually if this strategy is * applied, the type is not constructable without using JVM non-public functionality. */ NO_CONSTRUCTORS { @Override protected List<MethodDescription.Token> doExtractConstructors(TypeDescription superClass) { return Collections.emptyList(); } @Override protected MethodRegistry doInject(MethodRegistry methodRegistry, MethodAttributeAppender.Factory methodAttributeAppenderFactory) { return methodRegistry; } }, /** * This strategy is adding a default constructor that calls it's super types default constructor. If no such * constructor is defined by the super class, an {@link IllegalArgumentException} is thrown. Note that the default * constructor needs to be visible to its sub type for this strategy to work. The declared default constructor of * the created class is declared public and without annotations. */ DEFAULT_CONSTRUCTOR { @Override protected List<MethodDescription.Token> doExtractConstructors(TypeDescription instrumentedType) { TypeDescription.Generic superClass = instrumentedType.getSuperClass(); MethodList<?> defaultConstructors = superClass == null ? new MethodList.Empty<MethodDescription.InGenericShape>() : superClass.getDeclaredMethods().filter(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(0)).<MethodDescription>and(ElementMatchers.isVisibleTo(instrumentedType))); if (defaultConstructors.size() == 1) { return Collections.singletonList(new MethodDescription.Token(Opcodes.ACC_PUBLIC)); } else { throw new IllegalArgumentException(instrumentedType.getSuperClass() + " declares no constructor that is visible to " + instrumentedType); } } @Override protected MethodRegistry doInject(MethodRegistry methodRegistry, MethodAttributeAppender.Factory methodAttributeAppenderFactory) { return methodRegistry.append(new LatentMatcher.Resolved<MethodDescription>(ElementMatchers.isConstructor()), new MethodRegistry.Handler.ForImplementation(SuperMethodCall.INSTANCE), methodAttributeAppenderFactory, Transformer.NoOp.<MethodDescription>make()); } }, /** * This strategy is adding all constructors of the instrumented type's super class where each constructor is * directly invoking its signature-equivalent super class constructor. Only constructors that are visible to the * instrumented type are added, i.e. package-private constructors are only added if the super type is defined * in the same package as the instrumented type and private constructors are always skipped. */ IMITATE_SUPER_CLASS { @Override protected List<MethodDescription.Token> doExtractConstructors(TypeDescription instrumentedType) { TypeDescription.Generic superClass = instrumentedType.getSuperClass(); return (superClass == null ? new MethodList.Empty<MethodDescription.InGenericShape>() : superClass.getDeclaredMethods().filter(ElementMatchers.isConstructor().and(ElementMatchers.isVisibleTo(instrumentedType)))).asTokenList(is(instrumentedType)); } @Override public MethodRegistry doInject(MethodRegistry methodRegistry, MethodAttributeAppender.Factory methodAttributeAppenderFactory) { return methodRegistry.append(new LatentMatcher.Resolved<MethodDescription>(ElementMatchers.isConstructor()), new MethodRegistry.Handler.ForImplementation(SuperMethodCall.INSTANCE), methodAttributeAppenderFactory, Transformer.NoOp.<MethodDescription>make()); } }, /** * This strategy is adding all constructors of the instrumented type's super class where each constructor is * directly invoking its signature-equivalent super class constructor. Only {@code public} constructors are * added. */ IMITATE_SUPER_CLASS_PUBLIC { @Override protected List<MethodDescription.Token> doExtractConstructors(TypeDescription instrumentedType) { TypeDescription.Generic superClass = instrumentedType.getSuperClass(); return (superClass == null ? new MethodList.Empty<MethodDescription.InGenericShape>() : superClass.getDeclaredMethods().filter(ElementMatchers.isPublic().and(ElementMatchers.isConstructor()))).asTokenList(is(instrumentedType)); } @Override public MethodRegistry doInject(MethodRegistry methodRegistry, MethodAttributeAppender.Factory methodAttributeAppenderFactory) { return methodRegistry.append(new LatentMatcher.Resolved<MethodDescription>(ElementMatchers.isConstructor()), new MethodRegistry.Handler.ForImplementation(SuperMethodCall.INSTANCE), methodAttributeAppenderFactory, Transformer.NoOp.<MethodDescription>make()); } }, /** * This strategy is adding all constructors of the instrumented type's super class where each constructor is * directly invoking its signature-equivalent super class constructor. A constructor is added for any constructor * of the super class that is invokable and is declared as {@code public}. */ IMITATE_SUPER_CLASS_OPENING { @Override protected List<MethodDescription.Token> doExtractConstructors(TypeDescription instrumentedType) { TypeDescription.Generic superClass = instrumentedType.getSuperClass(); return (superClass == null ? new MethodList.Empty<MethodDescription.InGenericShape>() : superClass.getDeclaredMethods().filter(ElementMatchers.isConstructor().and(ElementMatchers.isVisibleTo(instrumentedType)))).asTokenList(is(instrumentedType)); } @Override public MethodRegistry doInject(MethodRegistry methodRegistry, MethodAttributeAppender.Factory methodAttributeAppenderFactory) { return methodRegistry.append(new LatentMatcher.Resolved<MethodDescription>(ElementMatchers.isConstructor()), new MethodRegistry.Handler.ForImplementation(SuperMethodCall.INSTANCE), methodAttributeAppenderFactory, Transformer.NoOp.<MethodDescription>make()); } @Override protected int resolveModifier(int modifiers) { return Opcodes.ACC_PUBLIC; } }; @Override public List<MethodDescription.Token> extractConstructors(TypeDescription instrumentedType) { List<MethodDescription.Token> tokens = doExtractConstructors(instrumentedType); List<MethodDescription.Token> stripped = new ArrayList<MethodDescription.Token>(tokens.size()); for (MethodDescription.Token token : tokens) { stripped.add(new MethodDescription.Token(token.getName(), resolveModifier(token.getModifiers()), token.getTypeVariableTokens(), token.getReturnType(), token.getParameterTokens(), token.getExceptionTypes(), token.getAnnotations(), token.getDefaultValue(), TypeDescription.Generic.UNDEFINED)); } return stripped; } /** * Resolves a constructor's modifiers. * * @param modifiers The actual constructor's modifiers. * @return The resolved modifiers. */ protected int resolveModifier(int modifiers) { return modifiers; } /** * Extracts the relevant method tokens of the instrumented type's constructors. * * @param instrumentedType The type for which to extract the constructors. * @return A list of relevant method tokens. */ protected abstract List<MethodDescription.Token> doExtractConstructors(TypeDescription instrumentedType); @Override public MethodRegistry inject(MethodRegistry methodRegistry) { return doInject(methodRegistry, MethodAttributeAppender.NoOp.INSTANCE); } /** * Applies the actual injection with a method attribute appender factory supplied. * * @param methodRegistry The method registry into which to inject the constructors. * @param methodAttributeAppenderFactory The method attribute appender to use. * @return The resulting method registry. */ protected abstract MethodRegistry doInject(MethodRegistry methodRegistry, MethodAttributeAppender.Factory methodAttributeAppenderFactory); /** * Returns a constructor strategy that supplies the supplied method attribute appender factory. * * @param methodAttributeAppenderFactory The method attribute appender factory to use. * @return A copy of this constructor strategy with the method attribute appender factory applied. */ public ConstructorStrategy with(MethodAttributeAppender.Factory methodAttributeAppenderFactory) { return new WithMethodAttributeAppenderFactory(this, methodAttributeAppenderFactory); } /** * Applies this constructor strategy while retaining any of the base constructor's annotations. * * @return A copy of this constructor strategy which retains any of the base constructor's annotations. */ public ConstructorStrategy withInheritedAnnotations() { return new WithMethodAttributeAppenderFactory(this, MethodAttributeAppender.ForInstrumentedMethod.EXCLUDING_RECEIVER); } /** * A wrapper for a default constructor strategy which additionally applies a method attribute appender factory. */ protected static class WithMethodAttributeAppenderFactory implements ConstructorStrategy { /** * The delegate default constructor strategy. */ private final Default delegate; /** * The method attribute appender factory to apply. */ private final MethodAttributeAppender.Factory methodAttributeAppenderFactory; /** * Creates a new wrapper for a default constructor strategy. * * @param delegate The delegate default constructor strategy. * @param methodAttributeAppenderFactory The method attribute appender factory to apply. */ protected WithMethodAttributeAppenderFactory(Default delegate, MethodAttributeAppender.Factory methodAttributeAppenderFactory) { this.delegate = delegate; this.methodAttributeAppenderFactory = methodAttributeAppenderFactory; } @Override public List<MethodDescription.Token> extractConstructors(TypeDescription instrumentedType) { return delegate.extractConstructors(instrumentedType); } @Override public MethodRegistry inject(MethodRegistry methodRegistry) { return delegate.doInject(methodRegistry, methodAttributeAppenderFactory); } @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 ConstructorStrategy.Default.WithMethodAttributeAppenderFactory)) return false; final ConstructorStrategy.Default.WithMethodAttributeAppenderFactory other = (ConstructorStrategy.Default.WithMethodAttributeAppenderFactory) o; if (!other.canEqual((java.lang.Object) this)) return false; final java.lang.Object this$delegate = this.delegate; final java.lang.Object other$delegate = other.delegate; if (this$delegate == null ? other$delegate != null : !this$delegate.equals(other$delegate)) return false; final java.lang.Object this$methodAttributeAppenderFactory = this.methodAttributeAppenderFactory; final java.lang.Object other$methodAttributeAppenderFactory = other.methodAttributeAppenderFactory; if (this$methodAttributeAppenderFactory == null ? other$methodAttributeAppenderFactory != null : !this$methodAttributeAppenderFactory.equals(other$methodAttributeAppenderFactory)) return false; return true; } @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") protected boolean canEqual(final java.lang.Object other) { return other instanceof ConstructorStrategy.Default.WithMethodAttributeAppenderFactory; } @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 $delegate = this.delegate; result = result * PRIME + ($delegate == null ? 43 : $delegate.hashCode()); final java.lang.Object $methodAttributeAppenderFactory = this.methodAttributeAppenderFactory; result = result * PRIME + ($methodAttributeAppenderFactory == null ? 43 : $methodAttributeAppenderFactory.hashCode()); return result; } } } }