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