package ru.vyarus.dropwizard.guice.module.installer.bundle; import com.google.common.base.Preconditions; import com.google.inject.Module; import io.dropwizard.Application; import io.dropwizard.Configuration; import io.dropwizard.setup.Environment; import ru.vyarus.dropwizard.guice.module.context.ConfigurationContext; import ru.vyarus.dropwizard.guice.module.context.option.Option; import ru.vyarus.dropwizard.guice.module.installer.FeatureInstaller; import java.util.Arrays; import java.util.List; /** * Guicey configuration object. Provides almost the same configuration methods as * {@link ru.vyarus.dropwizard.guice.GuiceBundle.Builder}. Also, contains dropwizard configuration, * environment and application objects (in case if they are required). * * @author Vyacheslav Rusakov * @since 01.08.2015 */ @SuppressWarnings("PMD.AvoidFieldNameMatchingMethodName") public class GuiceyBootstrap { private final ConfigurationContext context; private final List<GuiceyBundle> iterationBundles; private final Configuration configuration; private final Environment environment; private final Application application; public GuiceyBootstrap(final ConfigurationContext context, final List<GuiceyBundle> iterationBundles, final Configuration configuration, final Environment environment, final Application application) { this.context = context; this.iterationBundles = iterationBundles; this.configuration = configuration; this.environment = environment; this.application = application; } /** * @param <T> configuration type * @return configuration instance */ @SuppressWarnings("unchecked") public <T extends Configuration> T configuration() { return (T) configuration; } /** * @return environment instance */ public Environment environment() { return environment; } /** * Application instance may be useful for complex (half manual) integrations where access for * injector is required. * For example, manually registered * {@link io.dropwizard.lifecycle.Managed} may access injector in it's start method by calling * {@link ru.vyarus.dropwizard.guice.injector.lookup.InjectorLookup#getInjector(Application)}. * <p> * NOTE: it will work in this example, because injector access will be after injector creation. * Directly inside bundle initialization method injector could not be obtained as it's not exists yet. * * @return dropwizard application instance */ public Application application() { return application; } /** * All registered modules must be of unique type (all modules registered). If two or more modules of the * same type registered, only first instance will be used. * <p> * NOTE: if module implements *AwareModule interfaces, objects will be set just before configuration start. * * @param modules one or more juice modules * @return configurer instance for chained calls * @see ru.vyarus.dropwizard.guice.module.support.BootstrapAwareModule * @see ru.vyarus.dropwizard.guice.module.support.ConfigurationAwareModule * @see ru.vyarus.dropwizard.guice.module.support.EnvironmentAwareModule * @see ru.vyarus.dropwizard.guice.module.support.DropwizardAwareModule */ public GuiceyBootstrap modules(final Module... modules) { Preconditions.checkState(modules.length > 0, "Specify at least one module"); context.registerModules(modules); return this; } /** * @param installers feature installer types to disable * @return configurer instance for chained calls */ @SafeVarargs public final GuiceyBootstrap disableInstallers(final Class<? extends FeatureInstaller>... installers) { context.disableInstallers(installers); return this; } /** * If bundle provides new installers then they must be declared here. * Optionally, core or other 3rd party installers may be declared also to indicate dependency * (duplicate installers registrations will be removed). * * @param installers feature installer classes to register * @return configurer instance for chained calls */ @SafeVarargs public final GuiceyBootstrap installers(final Class<? extends FeatureInstaller>... installers) { context.registerInstallers(installers); return this; } /** * Bundle should not rely on auto-scan mechanism and so must declare all extensions manually * (this better declares bundle content and speed ups startup). * <p> * NOTE: startup will fail if bean not recognized by installers. * <p> * NOTE: Don't register commands here: either enable auto scan, which will install commands automatically * or register command directly to bootstrap object and dependencies will be injected to them after * injector creation. * * @param extensionClasses extension bean classes to register * @return configurer instance for chained calls */ public GuiceyBootstrap extensions(final Class<?>... extensionClasses) { context.registerExtensions(extensionClasses); return this; } /** * Register other guicey bundles for installation. * <p> * Duplicate bundles will be filtered automatically: bundles of the same type considered duplicate * (if two or more bundles of the same type detected then only first instance will be processed). * * @param bundles guicey bundles * @return configurer instance for chained calls */ public GuiceyBootstrap bundles(final GuiceyBundle... bundles) { context.registerBundles(bundles); iterationBundles.addAll(Arrays.asList(bundles)); return this; } /** * Read option value. Options could be set only in application root * {@link ru.vyarus.dropwizard.guice.GuiceBundle.Builder#option(Enum, Object)}. * If value wasn't set there then default value will be returned. Null may return only if it was default value * and no new value were assigned. * <p> * Option access is tracked as option usage (all tracked data is available through * {@link ru.vyarus.dropwizard.guice.module.context.option.OptionsInfo}). * * @param option option enum * @param <V> option value type * @param <T> helper type to define option * @return assigned option value or default value * @see Option for more info about options * @see ru.vyarus.dropwizard.guice.GuiceyOptions for options example */ public <V, T extends Enum & Option> V option(final T option) { return context.option(option); } }