1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject.multibindings;
18 
19 import com.google.inject.Binding;
20 import com.google.inject.Key;
21 import com.google.inject.TypeLiteral;
22 import com.google.inject.spi.Element;
23 import com.google.inject.spi.Elements;
24 import java.util.List;
25 import java.util.Map;
26 
27 /**
28  * A binding for a MapBinder.
29  *
30  * <p>Although MapBinders may be injected through a variety of generic types (Map&lt;K, V>, Map
31  * &lt;K, Provider&lt;V>>, Map&lt;K, Set&lt;V>>, Map<K, Set&lt; Provider&lt;V>>, and even
32  * Set&lt;Map.Entry&lt;K, Provider&lt;V>>), a MapBinderBinding exists only on the Binding associated
33  * with the Map&lt;K, V> key. Other bindings can be validated to be derived from this
34  * MapBinderBinding using {@link #containsElement(Element)}.
35  *
36  * @param <T> The fully qualified type of the map, including Map. For example: <code>
37  *     MapBinderBinding&lt;Map&lt;String, Snack>></code>
38  * @since 3.0
39  * @author sameb@google.com (Sam Berlin)
40  */
41 public interface MapBinderBinding<T> {
42 
43   /** Returns the {@link Key} for the map. */
getMapKey()44   Key<T> getMapKey();
45 
46   /**
47    * Returns the TypeLiteral describing the keys of the map.
48    *
49    * <p>The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
50    * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a <code>
51    * TypeLiteral&lt;String></code>.
52    */
getKeyTypeLiteral()53   TypeLiteral<?> getKeyTypeLiteral();
54 
55   /**
56    * Returns the TypeLiteral describing the values of the map.
57    *
58    * <p>The TypeLiteral will always match the type Map's generic type. For example, if getMapKey
59    * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a <code>
60    * TypeLiteral&lt;Snack></code>.
61    */
getValueTypeLiteral()62   TypeLiteral<?> getValueTypeLiteral();
63 
64   /**
65    * Returns all entries in the Map. The returned list of Map.Entries contains the key and a binding
66    * to the value. Duplicate keys or values will exist as separate Map.Entries in the returned list.
67    * This is only supported on bindings returned from an injector. This will throw {@link
68    * UnsupportedOperationException} if it is called on an element retrieved from {@link
69    * Elements#getElements}.
70    *
71    * <p>The elements will always match the type Map's generic type. For example, if getMapKey
72    * returns a key of <code>Map&lt;String, Snack></code>, then this will always return a list of
73    * type <code>List&lt;Map.Entry&lt;String, Binding&lt;Snack>>></code>.
74    */
getEntries()75   List<Map.Entry<?, Binding<?>>> getEntries();
76 
77   /**
78    * Similar to {@link #getEntries()}, but can be used on a MapBinderBinding retrieved from {@link
79    * Elements#getElements}.
80    *
81    * <p>One way to use this is to pass in the results of {@link Elements#getElements} as the {@code
82    * elements} parameter.
83    *
84    * <p>This differs from {@link #getEntries()} in that it will return duplicates if they are
85    * present in the {@code elements} passed in. This does not run the normal Guice de-duplication
86    * that {@link #getEntries()} does.
87    *
88    * @throws IllegalArgumentException if the provided elements contain partial map entries. If the
89    *     elements come from {@link Elements#getElements} on a module with a MapBinder, there will be
90    *     a 1:1 relationship and no exception will be thrown.
91    * @since 4.2
92    */
getEntries(Iterable<? extends Element> elements)93   List<Map.Entry<?, Binding<?>>> getEntries(Iterable<? extends Element> elements);
94 
95   /**
96    * Returns true if the MapBinder permits duplicates. This is only supported on bindings returned
97    * from an injector. This will throw {@link UnsupportedOperationException} if it is called on a
98    * MapBinderBinding retrieved from {@link Elements#getElements}.
99    */
permitsDuplicates()100   boolean permitsDuplicates();
101 
102   /**
103    * Returns true if this MapBinder contains the given Element in order to build the map or uses the
104    * given Element in order to support building and injecting the map. This will work for
105    * MapBinderBindings retrieved from an injector and {@link Elements#getElements}. Usually this is
106    * only necessary if you are working with elements retrieved from modules (without an Injector),
107    * otherwise {@link #getEntries} and {@link #permitsDuplicates} are better options.
108    *
109    * <p>If you need to introspect the details of the map, such as the keys, values or if it permits
110    * duplicates, it is necessary to pass the elements through an Injector and use {@link
111    * #getEntries()} and {@link #permitsDuplicates()}.
112    */
containsElement(Element element)113   boolean containsElement(Element element);
114 }
115