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

com.google.inject.spi.ModuleSource Maven / Gradle / Ivy

package com.google.inject.spi;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.internal.util.StackTraceElements;
import com.google.inject.internal.util.StackTraceElements.InMemoryStackTraceElement;

import java.util.List;

/**
 * Associated to a {@link Module module}, provides the module class name, the parent module {@link
 * ModuleSource source}, and the call stack that ends just before the module {@link
 * Module#configure(Binder)} method invocation.
 */
final class ModuleSource {

    /**
     * The class name of module that this {@link ModuleSource} associated to.
     */
    private final String moduleClassName;

    /**
     * The parent {@link ModuleSource module source}.
     */
    private final ModuleSource parent;

    /**
     * The chunk of call stack that starts from the parent module {@link Module#configure(Binder)
     * configure(Binder)} call and ends just before the module {@link Module#configure(Binder)
     * configure(Binder)} method invocation. For a module without a parent module the chunk starts
     * from the bottom of call stack. The array is non-empty if stack trace collection is on.
     */
    private final InMemoryStackTraceElement[] partialCallStack;

    /**
     * Creates a new {@link ModuleSource} with a {@literal null} parent.
     *
     * @param module           the corresponding module
     * @param partialCallStack the chunk of call stack that starts from the parent module {@link
     *                         Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
     *                         Module#configure(Binder) configure(Binder)} method invocation
     */
    ModuleSource(Object module, StackTraceElement[] partialCallStack) {
        this(null, module, partialCallStack);
    }

    /**
     * Creates a new {@link ModuleSource} Object.
     *
     * @param parent           the parent module {@link ModuleSource source}
     * @param module           the corresponding module
     * @param partialCallStack the chunk of call stack that starts from the parent module {@link
     *                         Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
     *                         Module#configure(Binder) configure(Binder)} method invocation
     */
    private ModuleSource(
      /* @Nullable */ ModuleSource parent, Object module, StackTraceElement[] partialCallStack) {
        Preconditions.checkNotNull(module, "module cannot be null.");
        Preconditions.checkNotNull(partialCallStack, "partialCallStack cannot be null.");
        this.parent = parent;
        this.moduleClassName = module.getClass().getName();
        this.partialCallStack = StackTraceElements.convertToInMemoryStackTraceElement(partialCallStack);
    }

    /**
     * Returns the corresponding module class name.
     *
     * @see Class#getName()
     */
    String getModuleClassName() {
        return moduleClassName;
    }

    /**
     * Returns the chunk of call stack that starts from the parent module {@link
     * Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
     * Module#configure(Binder) configure(Binder)} method invocation. The return array is non-empty
     * only if stack trace collection is on.
     */
    StackTraceElement[] getPartialCallStack() {
        return StackTraceElements.convertToStackTraceElement(partialCallStack);
    }

    /**
     * Returns the size of partial call stack if stack trace collection is on otherwise zero.
     */
    int getPartialCallStackSize() {
        return partialCallStack.length;
    }

    /**
     * Creates and returns a child {@link ModuleSource} corresponding to the {@link Module module}.
     *
     * @param module           the corresponding module
     * @param partialCallStack the chunk of call stack that starts from the parent module {@link
     *                         Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
     *                         Module#configure(Binder) configure(Binder)} method invocation
     */
    ModuleSource createChild(Object module, StackTraceElement[] partialCallStack) {
        return new ModuleSource(this, module, partialCallStack);
    }

    /**
     * Returns the parent module {@link ModuleSource source}.
     */
    ModuleSource getParent() {
        return parent;
    }

    /**
     * Returns the class names of modules in this module source. The first element (index 0) is filled
     * by this object {@link #getModuleClassName()}. The second element is filled by the parent's
     * {@link #getModuleClassName()} and so on.
     */
    List getModuleClassNames() {
        ImmutableList.Builder classNames = ImmutableList.builder();
        ModuleSource current = this;
        while (current != null) {
            String className = current.moduleClassName;
            classNames.add(className);
            current = current.parent;
        }
        return classNames.build();
    }

    /**
     * Returns the size of {@link ModuleSource ModuleSources} chain (all parents) that ends at this
     * object.
     */
    int size() {
        if (parent == null) {
            return 1;
        }
        return parent.size() + 1;
    }

    /**
     * Returns the size of call stack that ends just before the module {@link Module#configure(Binder)
     * configure(Binder)} method invocation (see {@link #getStackTrace()}).
     */
    int getStackTraceSize() {
        if (parent == null) {
            return partialCallStack.length;
        }
        return parent.getStackTraceSize() + partialCallStack.length;
    }

    /**
     * Returns the full call stack that ends just before the module {@link Module#configure(Binder)
     * configure(Binder)} method invocation. The return array is non-empty if stack trace collection
     * on.
     */
    StackTraceElement[] getStackTrace() {
        int stackTraceSize = getStackTraceSize();
        StackTraceElement[] callStack = new StackTraceElement[stackTraceSize];
        int cursor = 0;
        ModuleSource current = this;
        while (current != null) {
            StackTraceElement[] chunk =
                    StackTraceElements.convertToStackTraceElement(current.partialCallStack);
            int chunkSize = chunk.length;
            System.arraycopy(chunk, 0, callStack, cursor, chunkSize);
            current = current.parent;
            cursor = cursor + chunkSize;
        }
        return callStack;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy