• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Dagger Authors.
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 dagger;
18 
19 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
20 import static java.lang.annotation.RetentionPolicy.RUNTIME;
21 
22 import java.lang.annotation.Documented;
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.Target;
25 import java.util.Map;
26 
27 /**
28  * Identifies annotation types that are used to associate keys with values returned by {@linkplain
29  * Provides provider methods} in order to compose a {@linkplain dagger.multibindings.IntoMap map}.
30  *
31  * <p>Every provider method annotated with {@code @Provides} and {@code @IntoMap} must also have an
32  * annotation that identifies the key for that map entry. That annotation's type must be annotated
33  * with {@code @MapKey}.
34  *
35  * <p>Typically, the key annotation has a single member, whose value is used as the map key.
36  *
37  * <p>For example, to add an entry to a {@code Map<SomeEnum, Integer>} with key {@code
38  * SomeEnum.FOO}, you could use an annotation called {@code @SomeEnumKey}:
39  *
40  * <pre><code>
41  * {@literal @}MapKey
42  * {@literal @}interface SomeEnumKey {
43  *   SomeEnum value();
44  * }
45  *
46  * {@literal @}Module
47  * class SomeModule {
48  *   {@literal @}Provides
49  *   {@literal @}IntoMap
50  *   {@literal @}SomeEnumKey(SomeEnum.FOO)
51  *   Integer provideFooValue() {
52  *     return 2;
53  *   }
54  * }
55  *
56  * class SomeInjectedType {
57  *   {@literal @}Inject
58  *   SomeInjectedType({@literal Map<SomeEnum, Integer>} map) {
59  *     assert map.get(SomeEnum.FOO) == 2;
60  *   }
61  * }
62  * </code></pre>
63  *
64  * <p>If {@code unwrapValue} is true, the annotation's single member can be any type except an
65  * array.
66  *
67  * <p>See {@link dagger.multibindings} for standard unwrapped map key annotations for keys that are
68  * boxed primitives, strings, or classes.
69  *
70  * <h2>Annotations as keys</h2>
71  *
72  * <p>If {@link #unwrapValue} is false, then the annotation itself is used as the map key. For
73  * example, to add an entry to a {@code Map<MyMapKey, Integer>} map:
74  *
75  * <pre><code>
76  * {@literal @}MapKey(unwrapValue = false)
77  * {@literal @}interface MyMapKey {
78  *   String someString();
79  *   MyEnum someEnum();
80  * }
81  *
82  * {@literal @}Module
83  * class SomeModule {
84  *   {@literal @}Provides
85  *   {@literal @}IntoMap
86  *   {@literal @}MyMapKey(someString = "foo", someEnum = BAR)
87  *   Integer provideFooBarValue() {
88  *     return 2;
89  *   }
90  * }
91  *
92  * class SomeInjectedType {
93  *   {@literal @}Inject
94  *   SomeInjectedType({@literal Map<MyMapKey, Integer>} map) {
95  *     assert map.get(new MyMapKeyImpl("foo", MyEnum.BAR)) == 2;
96  *   }
97  * }
98  * </code></pre>
99  *
100  * <p>(Note that there must be a class {@code MyMapKeyImpl} that implements {@code MyMapKey} in
101  * order to call {@link Map#get(Object)} on the provided map.)
102  *
103  * @see <a href="https://dagger.dev/multibindings#map-multibindings">Map multibinding</a>
104  */
105 @Documented
106 @Target(ANNOTATION_TYPE)
107 @Retention(RUNTIME)
108 public @interface MapKey {
109   /**
110    * True to use the value of the single member of the annotated annotation as the map key; false
111    * to use the annotation instance as the map key.
112    *
113    * <p>If true, the single member must not be an array.
114    */
unwrapValue()115   boolean unwrapValue() default true;
116 }
117