}, and to each contribute
* bindings to the snacks map. When that map is injected, it will contain
* entries from both modules.
*
* The map's iteration order is consistent with the binding order. This is
* convenient when multiple elements are contributed by the same module because
* that module can order its bindings appropriately. Avoid relying on the
* iteration order of elements contributed by different modules, since there is
* no equivalent mechanism to order modules.
*
*
The map is unmodifiable. Elements can only be added to the map by
* configuring the MapBinder. Elements can never be removed from the map.
*
*
Values are resolved at map injection time. If a value is bound to a
* provider, that provider's get method will be called each time the map is
* injected (unless the binding is also scoped, or a map of providers is injected).
*
*
Annotations are used to create different maps of the same key/value
* type. Each distinct annotation gets its own independent map.
*
*
Keys must be distinct. If the same key is bound more than
* once, map injection will fail. However, use {@link #permitDuplicates()} in
* order to allow duplicate keys; extra bindings to {@code Map>} and
* {@code Map>} will be added.
*
* Keys must be non-null. {@code addBinding(null)} will
* throw an unchecked exception.
*
*
Values must be non-null to use map injection. If any
* value is null, map injection will fail (although injecting a map of providers
* will not).
*
* @author [email protected] (David P. Baker)
*/
public abstract class MapBinder {
private MapBinder() {}
/**
* Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
* {@link Map} that is itself bound with no binding annotation.
*/
public static MapBinder newMapBinder(Binder binder,
TypeLiteral keyType, TypeLiteral valueType) {
binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
return newMapBinder(binder, keyType, valueType,
Key.get(mapOf(keyType, valueType)),
Key.get(mapOfProviderOf(keyType, valueType)),
Key.get(mapOf(keyType, setOf(valueType))),
Key.get(mapOfSetOfProviderOf(keyType, valueType)),
Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType)));
}
/**
* Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
* {@link Map} that is itself bound with no binding annotation.
*/
public static MapBinder newMapBinder(Binder binder,
Class keyType, Class valueType) {
return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType));
}
/**
* Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
* {@link Map} that is itself bound with {@code annotation}.
*/
public static MapBinder newMapBinder(Binder binder,
TypeLiteral keyType, TypeLiteral valueType, Annotation annotation) {
binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
return newMapBinder(binder, keyType, valueType,
Key.get(mapOf(keyType, valueType), annotation),
Key.get(mapOfProviderOf(keyType, valueType), annotation),
Key.get(mapOf(keyType, setOf(valueType)), annotation),
Key.get(mapOfSetOfProviderOf(keyType, valueType), annotation),
Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType), annotation));
}
/**
* Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
* {@link Map} that is itself bound with {@code annotation}.
*/
public static MapBinder newMapBinder(Binder binder,
Class keyType, Class valueType, Annotation annotation) {
return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotation);
}
/**
* Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
* {@link Map} that is itself bound with {@code annotationType}.
*/
public static MapBinder newMapBinder(Binder binder, TypeLiteral keyType,
TypeLiteral valueType, Class extends Annotation> annotationType) {
binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
return newMapBinder(binder, keyType, valueType,
Key.get(mapOf(keyType, valueType), annotationType),
Key.get(mapOfProviderOf(keyType, valueType), annotationType),
Key.get(mapOf(keyType, setOf(valueType)), annotationType),
Key.get(mapOfSetOfProviderOf(keyType, valueType), annotationType),
Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType), annotationType));
}
/**
* Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a
* {@link Map} that is itself bound with {@code annotationType}.
*/
public static MapBinder newMapBinder(Binder binder, Class keyType,
Class valueType, Class extends Annotation> annotationType) {
return newMapBinder(
binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotationType);
}
@SuppressWarnings("unchecked") // a map of is safely a Map
static TypeLiteral