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

com.google.gwt.inject.client.multibindings.GinMultibinder Maven / Gradle / Ivy

/*
 * Copyright 2013 Google Inc.
 *
 * 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 com.google.gwt.inject.client.multibindings;

import static com.google.gwt.inject.client.multibindings.TypeLiterals.providerOf;
import static com.google.gwt.inject.client.multibindings.TypeLiterals.setOf;

import com.google.gwt.inject.client.binder.GinBinder;
import com.google.gwt.inject.client.binder.GinLinkedBindingBuilder;
import com.google.gwt.inject.client.multibindings.InternalModule.SingletonInternalModule;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;

import java.lang.annotation.Annotation;

/**
 * A utility that mimics the behavior and API of Guice Multibinder for GIN.
 *
 * 

Example usage: *

 *   interface X {};
 *
 *   class X1Impl implements X {};
 *
 *   class X2Impl implements X {};
 *
 *   class X3Provider implements Provider<X> { ... };
 *
 *   Set<X> multibinder = GinMultibinder.newSetBinder(binder(), X.class);
 *   multibinder.addBinding().to(X1Impl.class);
 *   multibinder.addBinding().to(X2Impl.class);
 *   multibinder.addBinding().toProvier(X3Provider.class);
 * 
* * @param type of value for Set */ public final class GinMultibinder { /** * Returns a new multibinder that collects instances of {@code type} in a {@link java.util.Set} * that is itself bound with no binding annotation. */ public static GinMultibinder newSetBinder(GinBinder binder, TypeLiteral type) { return newSetBinder(binder, type, Key.get(providerOf(type))); } /** * Returns a new multibinder that collects instances of {@code type} in a {@link java.util.Set} * that is itself bound with no binding annotation. */ public static GinMultibinder newSetBinder(GinBinder binder, Class type) { return newSetBinder(binder, TypeLiteral.get(type)); } /** * Returns a new multibinder that collects instances of {@code type} in a {@link java.util.Set} * that is itself bound with {@code annotation}. */ public static GinMultibinder newSetBinder( GinBinder binder, TypeLiteral type, Annotation annotation) { return newSetBinder(binder, type, Key.get(providerOf(type), annotation)); } /** * Returns a new multibinder that collects instances of {@code type} in a {@link java.util.Set} * that is itself bound with {@code annotation}. */ public static GinMultibinder newSetBinder( GinBinder binder, Class type, Annotation annotation) { return newSetBinder(binder, TypeLiteral.get(type), annotation); } /** * Returns a new multibinder that collects instances of {@code type} in a {@link java.util.Set} * that is itself bound with {@code annotationType}. */ public static GinMultibinder newSetBinder( GinBinder binder, TypeLiteral type, Class annotationType) { return newSetBinder(binder, type, Key.get(providerOf(type), annotationType)); } /** * Returns a new multibinder that collects instances of {@code type} in a {@link Set} that is * itself bound with {@code annotationType}. */ public static GinMultibinder newSetBinder( GinBinder binder, Class type, Class annotationType) { return newSetBinder(binder, TypeLiteral.get(type), annotationType); } private static GinMultibinder newSetBinder( GinBinder ginBinder, TypeLiteral elementType, Key> keyForMultibinding) { GinMultibinder multiBinder = new GinMultibinder(ginBinder, elementType, keyForMultibinding); multiBinder.install(); return multiBinder; } private final GinBinder ginBinder; private final TypeLiteral elementType; private final Key> multibindingKey; public GinMultibinder( GinBinder ginBinder, TypeLiteral elementType, Key> keyForMultibinding) { this.ginBinder = ginBinder; this.elementType = elementType; this.multibindingKey = keyForMultibinding; } private void install() { ginBinder.install(new RuntimeBindingsRegistryModule>(multibindingKey)); ginBinder.install(new SetModule()); } /** * Configures the bound set to silently discard duplicate elements. When multiple equal values are * bound, the one that gets included is arbitrary. When multiple modules contribute elements to * the set, this configuration option impacts all of them. */ public GinMultibinder permitDuplicates() { ginBinder.install(new PermitDuplicatesModule>(multibindingKey)); return this; } /** * Returns a binding builder used to add a new element in the set. Each bound element must have a * distinct value. Bound providers will be evaluated each time the set is injected. *

* It is an error to call this method without also calling one of the {@code to} methods on the * returned binding builder. *

* Scoping elements independently is supported. Use the {@code in} method to specify a binding * scope. */ public GinLinkedBindingBuilder addBinding() { return new BindingRecorder(ginBinder, multibindingKey).bind(elementType); } // TODO(user): not private due to http://code.google.com/p/google-gin/issues/detail?id=184 final class SetModule extends SingletonInternalModule> { public SetModule() { super(multibindingKey); } @Override protected void configure() { bindInternalBindingsRegistry(); bindAndExpose(setOf(elementType)).toProvider(Key.get(providerForSetOf(elementType))); } } @SuppressWarnings("unchecked") private static TypeLiteral> providerForSetOf(TypeLiteral type) { return TypeLiterals.newParameterizedType(ProviderForSet.class, type); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy