ljacqu/DependencyInjector

View on GitHub
injector/src/main/java/ch/jalu/injector/InjectorBuilder.java

Summary

Maintainability
A
0 mins
Test Coverage
package ch.jalu.injector;

import ch.jalu.injector.handlers.Handler;
import ch.jalu.injector.handlers.dependency.CyclicDependenciesDetector;
import ch.jalu.injector.handlers.dependency.FactoryDependencyHandler;
import ch.jalu.injector.handlers.dependency.SavedAnnotationsHandler;
import ch.jalu.injector.handlers.dependency.SingletonStoreDependencyHandler;
import ch.jalu.injector.handlers.instantiation.DefaultInjectionProvider;
import ch.jalu.injector.handlers.postconstruct.PostConstructMethodInvoker;
import ch.jalu.injector.handlers.instantiation.ProviderHandler;
import ch.jalu.injector.utils.InjectorUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * Configures and creates an {@link Injector}.
 */
public class InjectorBuilder {

    private InjectorConfig config;

    /**
     * Creates a new builder.
     */
    public InjectorBuilder() {
        config = new InjectorConfig();
    }

    /**
     * Returns all handlers that are added to the injector by default.
     *
     * @param rootPackage the root package of the project (to limit injection and scanning to)
     * @return all default handlers
     * @see #addDefaultHandlers(String)
     */
    public static List<Handler> createDefaultHandlers(String rootPackage) {
        InjectorUtils.checkNotNull(rootPackage, "root package may not be null");
        return new ArrayList<>(Arrays.asList(
            // (Annotation, Object) handler
            new SavedAnnotationsHandler(),
            // Provider / Factory / SingletonStore
            new ProviderHandler(),
            new FactoryDependencyHandler(),
            new SingletonStoreDependencyHandler(),
            // Instantiation provider
            new CyclicDependenciesDetector(),
            new DefaultInjectionProvider(rootPackage),
            // PostConstruct
            new PostConstructMethodInvoker()));
    }

    /**
     * Creates all default handlers implementing {@link Handler#resolve}. Useful if you want to create your own
     * preconstruct (etc.) handlers but want to use the default instantiation providers.
     * <p>
     * Use {@link #createDefaultHandlers(String)} or {@link #addDefaultHandlers(String)} otherwise.
     *
     * @param rootPackage the root package of the project
     * @return default instantiation providers
     */
    public static List<Handler> createInstantiationProviders(String rootPackage) {
        InjectorUtils.checkNotNull(rootPackage, "root package may not be null");
        return new ArrayList<>(Arrays.asList(
            new ProviderHandler(),
            new FactoryDependencyHandler(),
            new SingletonStoreDependencyHandler(),
            new DefaultInjectionProvider(rootPackage)));
    }

    /**
     * Convenience method for adding all default handlers to the injector configuration.
     * To obtain an injector with all defaults, you can simply do:
     * <code>
     *   Injector injector = new InjectorBuilder().addDefaultHandlers("your.package.here").create();
     * </code>
     *
     * @param rootPackage the root package of the project
     * @return the builder
     */
    public InjectorBuilder addDefaultHandlers(String rootPackage) {
        return addHandlers(createDefaultHandlers(rootPackage));
    }

    /**
     * Add handlers to the config. Note that <b>the order of the handlers matters.</b> Handlers are
     * separated by their subtype and then executed in the order as provided.
     *
     * @param handlers the handlers to add to the injector
     * @return the builder
     */
    public InjectorBuilder addHandlers(Handler... handlers) {
        return addHandlers(Arrays.asList(handlers));
    }

    /**
     * Add handlers to the config. Note that <b>the order of the handlers matters.</b> Handlers are
     * separated by their subtype and then executed in the order as provided.
     *
     * @param handlers the handlers to add to the injector
     * @return the builder
     */
    public InjectorBuilder addHandlers(Collection<? extends Handler> handlers) {
        config.addHandlers(handlers);
        return this;
    }

    /**
     * Creates an injector with the configurations set to the builder.
     *
     * @return the injector
     */
    public Injector create() {
        return new InjectorImpl(config);
    }
}