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

ratpack.guice.BindingsSpec Maven / Gradle / Ivy

Go to download

Integration with Google Guice for Ratpack applications - https://code.google.com/p/google-guice/

There is a newer version: 2.0.0-rc-1
Show newest version
/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ratpack.guice;

import com.google.common.reflect.TypeToken;
import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import ratpack.func.Action;
import ratpack.guice.internal.GuiceUtil;
import ratpack.registry.RegistrySpec;
import ratpack.registry.internal.TypeCaching;
import ratpack.server.ServerConfig;
import ratpack.util.Types;

import java.util.function.Supplier;

import static ratpack.util.Exceptions.uncheck;

/**
 * A buildable specification of Guice bindings.
 * 

* This type is used when bootstrapping a Guice based application to add {@link Module modules} and bindings. *

* It is recommended to become familiar with Guice bindings, scopes and other concerns before using Guice with Ratpack. *

Module order and overrides

*

* The order in which modules are added is significant. * Subsequent modules can override the bindings of previous modules. * This is a very useful technique for augmenting/customising the functionality provided by modules. * Many modules provide extensive bindings to facilitate such overriding. *

* Bindings added via the {@code bind()} and {@code provider()} methods always have the highest precedence, regardless of order. * That is, non module bindings can always override module bindings regardless of whether the module is added before or after the non module binding. */ public interface BindingsSpec extends RegistrySpec { /** * The launch config for the application. * * @return the launch config for the application */ ServerConfig getServerConfig(); /** * Adds the bindings from the given module. * * @param module module whose bindings should be added * @return this */ BindingsSpec module(Module module); /** * Adds the bindings from the given module. * * @param moduleClass type of the module whose bindings should be added * @return this */ @SuppressWarnings("unchecked") BindingsSpec module(Class moduleClass); /** * Adds the bindings from the given configurable module. * * @param moduleClass type of the module whose bindings should be added * @param configurer action to customize the module's config object * @param the type of the module's config object * @param the type of the module * @return this */ > BindingsSpec module(Class moduleClass, Action configurer); /** * Adds the bindings from the given configurable module. * * @param module module whose bindings should be added * @param configurer action to customize the module's config object * @param the type of the module's config object * @return this */ BindingsSpec module(ConfigurableModule module, Action configurer); /** * Adds the bindings from the given configurable module. * * @param moduleClass type of the module whose bindings should be added * @param config config object for the module * @param configurer action to customize the module's config object * @param the type of the module's config object * @param the type of the module * @return this */ > BindingsSpec moduleConfig(Class moduleClass, C config, Action configurer); default > BindingsSpec moduleConfig(Class moduleClass, C config) { return moduleConfig(moduleClass, config, Action.noop()); } /** * Adds the bindings from the given configurable module. * * @param module module whose bindings should be added * @param config config object for the module * @param configurer action to customize the module's config object * @param the type of the module's config object * @return this */ BindingsSpec moduleConfig(ConfigurableModule module, C config, Action configurer); default > BindingsSpec moduleConfig(T moduleClass, C config) { return moduleConfig(moduleClass, config, Action.noop()); } /** * Adds bindings by directly configuring a {@link Binder}. * * @param action the binder configuration * @return this */ BindingsSpec binder(Action action); default BindingsSpec multiBinder(TypeToken type, Action> action) throws Exception { return binder(b -> action.execute(Multibinder.newSetBinder(b, GuiceUtil.toTypeLiteral(type)))); } default BindingsSpec multiBinder(TypeLiteral type, Action> action) throws Exception { return multiBinder(GuiceUtil.toTypeToken(type), action); } default BindingsSpec multiBinder(Class type, Action> action) throws Exception { return multiBinder(TypeCaching.typeToken(type), action); } /** * Add a binding for the given type. * * @param type the type to add a binding for * @return this */ default BindingsSpec bind(Class type) { return binder(binder -> binder.bind(type)); } default BindingsSpec multiBind(Class type) { return uncheck(() -> multiBinder(type, b -> b.addBinding().to(type))); } /** * Add a binding for the given public type, to the given implementation type. * * @param publicType the public type of the binding * @param implType the class implementing the public type * @param the public type of the binding * @return this */ default BindingsSpec bind(Class publicType, Class implType) { return bind(TypeLiteral.get(publicType), implType); } default BindingsSpec bind(TypeToken publicType, Class implType) { return bind(GuiceUtil.toTypeLiteral(publicType), implType); } default BindingsSpec bind(TypeLiteral publicType, Class implType) { return binder(binder -> binder.bind(publicType).to(implType)); } default BindingsSpec multiBind(TypeLiteral publicType, Class implType) { return uncheck(() -> multiBinder(publicType, b -> b.addBinding().to(implType))); } default BindingsSpec multiBind(Class publicType, Class implType) { return multiBind(TypeLiteral.get(publicType), implType); } default BindingsSpec multiBind(TypeToken publicType, Class implType) { return multiBind(GuiceUtil.toTypeLiteral(publicType), implType); } /** * Add a binding for the given public type, to the given implementing instance. * * @param publicType the public type of the binding * @param instance the instance that implements the public type * @param the public type of the binding * @return this */ default BindingsSpec bindInstance(TypeLiteral publicType, T instance) { return binder(b -> b.bind(publicType).toInstance(instance)); } default BindingsSpec bindInstance(TypeToken publicType, T instance) { return bindInstance(GuiceUtil.toTypeLiteral(publicType), instance); } default BindingsSpec bindInstance(Class publicType, T instance) { return bindInstance(TypeLiteral.get(publicType), instance); } /** * Add a binding for the given object to its concrete type. * * @param instance the instance to bind * @param the type of the binding * @return this */ default BindingsSpec bindInstance(T instance) { if (instance instanceof Class) { throw new IllegalArgumentException("cannot use bindInstance() with a class object (use bind(Class) instead)"); } Class type = Types.cast(instance.getClass()); return binder(binder -> binder.bind(type).toInstance(instance)); } default BindingsSpec multiBindInstance(Class publicType, T instance) { return uncheck(() -> multiBinder(publicType, b -> b.addBinding().toInstance(instance))); } default BindingsSpec multiBindInstance(TypeLiteral publicType, T instance) { return uncheck(() -> multiBinder(publicType, b -> b.addBinding().toInstance(instance))); } default BindingsSpec multiBindInstance(TypeToken publicType, T instance) { return uncheck(() -> multiBinder(publicType, b -> b.addBinding().toInstance(instance))); } default BindingsSpec multiBindInstance(T instance) { if (instance instanceof Class) { throw new IllegalArgumentException("cannot use multiBindInstance() with a class object (use multiBind(Class) instead)"); } Class type = Types.cast(instance.getClass()); return multiBindInstance(type, instance); } /** * Add a binding for the given public type, to the given provider. * * @param publicType the public type of the object * @param provider the provider for the object * @param The public type of the object * @return this */ default BindingsSpec provider(TypeLiteral publicType, Provider provider) { return binder(b -> b.bind(publicType).toProvider(provider)); } default BindingsSpec provider(TypeToken publicType, Provider provider) { return provider(GuiceUtil.toTypeLiteral(publicType), provider); } default BindingsSpec provider(Class publicType, Provider provider) { return provider(TypeLiteral.get(publicType), provider); } default BindingsSpec multiBindProvider(TypeLiteral publicType, Provider provider) { return uncheck(() -> multiBinder(publicType, b -> b.addBinding().toProvider(provider))); } default BindingsSpec multiBindProvider(TypeToken publicType, Provider provider) { return multiBindProvider(GuiceUtil.toTypeLiteral(publicType), provider); } default BindingsSpec multiBindProvider(Class publicType, Provider provider) { return multiBindProvider(TypeLiteral.get(publicType), provider); } /** * Add a binding for the given public type, to the given provider type. * * @param publicType the public type of the object * @param providerType the type of the provider for the object * @param The public type of the object * @return this */ default BindingsSpec providerType(TypeLiteral publicType, Class> providerType) { return binder(binder -> binder.bind(publicType).toProvider(providerType)); } default BindingsSpec providerType(Class publicType, Class> providerType) { return providerType(TypeLiteral.get(publicType), providerType); } default BindingsSpec providerType(TypeToken publicType, Class> providerType) { return providerType(GuiceUtil.toTypeLiteral(publicType), providerType); } default BindingsSpec multiBindProviderType(Class publicType, Class> providerType) { return uncheck(() -> multiBinder(publicType, b -> b.addBinding().toProvider(providerType))); } @Override default RegistrySpec add(TypeToken type, O object) { return multiBindInstance(type, object); } @SuppressWarnings({"Anonymous2MethodRef", "Convert2Lambda"}) @Override default RegistrySpec addLazy(TypeToken type, Supplier supplier) { return multiBindProvider(type, new Provider() { @Override public O get() { return supplier.get(); } }); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy