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

com.hubspot.dropwizard.guice.GuiceBundle Maven / Gradle / Ivy

There is a newer version: 1.3.5.0
Show newest version
package com.hubspot.dropwizard.guice;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Stage;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;
import com.squarespace.jersey2.guice.JerseyGuiceModule;
import com.squarespace.jersey2.guice.JerseyGuiceUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.dropwizard.Configuration;
import io.dropwizard.ConfiguredBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import java.util.List;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.extension.ServiceLocatorGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GuiceBundle implements ConfiguredBundle {

    final Logger logger = LoggerFactory.getLogger(GuiceBundle.class);

    private final AutoConfig autoConfig;
    private final List modules;
    private final InjectorFactory injectorFactory;
    private Injector baseInjector;
    private DropwizardEnvironmentModule dropwizardEnvironmentModule;
    private Optional> configurationClass;
    private Stage stage;

    public static class Builder {
        private AutoConfig autoConfig;
        private List modules = Lists.newArrayList();
        private Optional> configurationClass = Optional.absent();
        private InjectorFactory injectorFactory = new InjectorFactoryImpl();

        public Builder addModule(Module module) {
            Preconditions.checkNotNull(module);
            modules.add(module);
            return this;
        }

        public Builder addModules(Module moduleOne, Module moduleTwo,
                                     Module... moreModules) {
            addModule(moduleOne);
            addModule(moduleTwo);
            for (Module module : moreModules) {
                addModule(module);
            }
            return this;
        }

        public Builder setConfigClass(Class clazz) {
            configurationClass = Optional.of(clazz);
            return this;
        }

        public Builder setInjectorFactory(InjectorFactory factory) {
            Preconditions.checkNotNull(factory);
            injectorFactory = factory;
            return this;
        }

        public Builder enableAutoConfig(String... basePackages) {
            Preconditions.checkArgument(basePackages.length > 0, "at least one package must be specified for AutoConfig");
            Preconditions.checkArgument(autoConfig == null, "autoConfig already enabled!");
            autoConfig = new AutoConfig(basePackages);
            return this;
        }

        public GuiceBundle build() {
            return build(Stage.PRODUCTION);
        }

        public GuiceBundle build(Stage s) {
            return new GuiceBundle<>(s, autoConfig, modules, configurationClass, injectorFactory);
        }

    }

    public static  Builder newBuilder() {
        return new Builder<>();
    }

    private GuiceBundle(Stage stage, AutoConfig autoConfig, List modules, Optional> configurationClass, InjectorFactory injectorFactory) {
        Preconditions.checkNotNull(modules);
        Preconditions.checkArgument(!modules.isEmpty());
        Preconditions.checkNotNull(stage);
        this.modules = modules;
        this.autoConfig = autoConfig;
        this.configurationClass = configurationClass;
        this.injectorFactory = injectorFactory;
        this.stage = stage;
    }

    @Override
    public void initialize(Bootstrap bootstrap) {
        if (configurationClass.isPresent()) {
            dropwizardEnvironmentModule = new DropwizardEnvironmentModule<>(configurationClass.get());
        } else {
            dropwizardEnvironmentModule = new DropwizardEnvironmentModule<>(Configuration.class);
        }
        modules.add(dropwizardEnvironmentModule);
        modules.add(new ServletModule());

        initInjector();
        JerseyGuiceUtils.install(new ServiceLocatorGenerator() {
            @Override
            public ServiceLocator create(String name, ServiceLocator parent) {
                if (!name.startsWith("__HK2_Generated_")) {
                    return null;
                }

                return baseInjector.createChildInjector(new JerseyGuiceModule(name))
                        .getInstance(ServiceLocator.class);
            }
        });

        if (autoConfig != null) {
            autoConfig.initialize(bootstrap, baseInjector.createChildInjector(new JerseyGuiceModule(JerseyGuiceUtils.newServiceLocator())));
        }
    }

    @SuppressFBWarnings("DM_EXIT")
    private void initInjector() {
        try {
            baseInjector = injectorFactory.create(this.stage,ImmutableList.copyOf(this.modules));
        } catch(Exception ie) {
            logger.error("Exception occurred when creating Guice Injector - exiting", ie);
            System.exit(1);
        }
    }

    @Override
    public void run(final T configuration, final Environment environment) {
        JerseyUtil.registerGuiceBound(baseInjector, environment.jersey());
        JerseyUtil.registerGuiceFilter(environment);
        environment.servlets().addServletListeners(new GuiceServletContextListener() {
            @Override
            protected Injector getInjector() {
                return baseInjector;
            }
        });
        setEnvironment(configuration, environment);

        if (autoConfig != null) {
            autoConfig.run(environment, baseInjector);
        }
    }

    @SuppressWarnings("unchecked")
    private void setEnvironment(final T configuration, final Environment environment) {
        dropwizardEnvironmentModule.setEnvironmentData(configuration, environment);
    }

    public Injector getInjector() {
        Preconditions.checkState(baseInjector != null, "injector is only available after com.hubspot.dropwizard.guice.GuiceBundle.initialize() is called");
        return baseInjector.createChildInjector(new JerseyGuiceModule(JerseyGuiceUtils.newServiceLocator()));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy