All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ui4j.bytebuddy.asm.ClassVisitorWrapper Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
package com.ui4j.bytebuddy.asm;

import com.ui4j.bytebuddy.jar.asm.ClassVisitor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * A class visitor wrapper is used in order to register an intermediate ASM {@link com.ui4j.bytebuddy.jar.asm.ClassVisitor} which
 * is applied to the main type created by a {@link com.ui4j.bytebuddy.dynamic.DynamicType.Builder} but not
 * to any {@link com.ui4j.bytebuddy.instrumentation.type.auxiliary.AuxiliaryType}s, if any.
 */
public interface ClassVisitorWrapper {

    /**
     * Applies a {@code ClassVisitorWrapper} to the creation of a {@link com.ui4j.bytebuddy.dynamic.DynamicType}.
     *
     * @param classVisitor A {@code ClassVisitor} to become the new primary class visitor to which the created
     *                     {@link com.ui4j.bytebuddy.dynamic.DynamicType} is written to.
     * @return A new {@code ClassVisitor} that usually delegates to the {@code ClassVisitor} delivered in the argument.
     */
    ClassVisitor wrap(ClassVisitor classVisitor);

    /**
     * An ordered, immutable chain of {@link com.ui4j.bytebuddy.asm.ClassVisitorWrapper}s.
     */
    static class Chain implements ClassVisitorWrapper {

        /**
         * The class visitor wrappers that are represented by this chain in their order. This list must not be mutated.
         */
        private final List classVisitorWrappers;

        /**
         * Creates an immutable empty chain.
         */
        public Chain() {
            this.classVisitorWrappers = Collections.emptyList();
        }

        /**
         * Creates a new immutable chain based on an existing list of {@link com.ui4j.bytebuddy.asm.ClassVisitorWrapper}s
         * where no copy of the received list is made.
         *
         * @param classVisitorWrappers A list of {@link com.ui4j.bytebuddy.asm.ClassVisitorWrapper}s where elements
         *                             at the beginning of the list are applied first, i.e. will be at the bottom of the generated
         *                             {@link com.ui4j.bytebuddy.jar.asm.ClassVisitor}.
         */
        protected Chain(List classVisitorWrappers) {
            this.classVisitorWrappers = classVisitorWrappers;
        }

        /**
         * Adds a {@code ClassVisitorWrapper} to the beginning of the chain such that the wrapped
         * ASM {@code ClassVisitor} will be applied before the other class visitors.
         *
         * @param classVisitorWrapper The {@code ClassVisitorWrapper} to add to the beginning of the chain.
         * @return A new chain incorporating the {@code ClassVisitorWrapper}.
         */
        public Chain prepend(ClassVisitorWrapper classVisitorWrapper) {
            List appendedList = new ArrayList(classVisitorWrappers.size() + 1);
            appendedList.add(classVisitorWrapper);
            appendedList.addAll(classVisitorWrappers);
            return new Chain(appendedList);
        }

        /**
         * Adds a {@code ClassVisitorWrapper} to the end of the chain such that the wrapped
         * ASM {@code ClassVisitor} will be applied after the other class visitors.
         *
         * @param classVisitorWrapper The {@code ClassVisitorWrapper} to add to the end of the chain.
         * @return A new chain incorporating the {@code ClassVisitorWrapper}.
         */
        public Chain append(ClassVisitorWrapper classVisitorWrapper) {
            List appendedList = new ArrayList(classVisitorWrappers.size() + 1);
            appendedList.addAll(classVisitorWrappers);
            appendedList.add(classVisitorWrapper);
            return new Chain(appendedList);
        }

        @Override
        public ClassVisitor wrap(ClassVisitor classVisitor) {
            for (ClassVisitorWrapper classVisitorWrapper : classVisitorWrappers) {
                classVisitor = classVisitorWrapper.wrap(classVisitor);
            }
            return classVisitor;
        }

        @Override
        public boolean equals(Object other) {
            return this == other || !(other == null || getClass() != other.getClass())
                    && classVisitorWrappers.equals(((Chain) other).classVisitorWrappers);
        }

        @Override
        public int hashCode() {
            return classVisitorWrappers.hashCode();
        }

        @Override
        public String toString() {
            return "ClassVisitorWrapper.Chain{classVisitorWrappers=" + classVisitorWrappers + '}';
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy