1 /* 2 * Copyright (C) 2016 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.producers.internal; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static dagger.internal.Providers.asDaggerProvider; 21 import static dagger.producers.internal.Producers.producerFromProvider; 22 23 import com.google.common.collect.ImmutableMap; 24 import dagger.internal.Provider; 25 import dagger.producers.Producer; 26 import java.util.Map; 27 28 /** 29 * An {@code abstract} {@link Producer} implementation used to implement {@link Map} bindings. 30 * 31 * @param <K>The key type of the map that this produces 32 * @param <V>The type that each contributing producer 33 * @param <V2>The value type of the map that this produces. For {@link MapProducer}, {@code V} and 34 * {@code V2} will be equivalent. 35 */ 36 abstract class AbstractMapProducer<K, V, V2> extends AbstractProducer<Map<K, V2>> { 37 private final ImmutableMap<K, Producer<V>> contributingMap; 38 AbstractMapProducer(ImmutableMap<K, Producer<V>> contributingMap)39 AbstractMapProducer(ImmutableMap<K, Producer<V>> contributingMap) { 40 this.contributingMap = contributingMap; 41 } 42 43 /** The map of {@link Producer}s that contribute to this map binding. */ contributingMap()44 final ImmutableMap<K, Producer<V>> contributingMap() { 45 return contributingMap; 46 } 47 48 /** A builder for {@link AbstractMapProducer} */ 49 public abstract static class Builder<K, V, V2> { 50 final ImmutableMap.Builder<K, Producer<V>> mapBuilder; 51 Builder(int size)52 Builder(int size) { 53 mapBuilder = ImmutableMap.builderWithExpectedSize(size); 54 } 55 56 // Unfortunately, we cannot return a self-type here because a raw Producer type passed to one of 57 // these methods affects the returned type of the method. The first put*() call erases the self 58 // type to the "raw" self type, and the second erases the type to the upper bound 59 // (AbstractMapProducer.Builder), which doesn't have a build() method. 60 // 61 // The methods are therefore not declared public so that each subtype will redeclare them and 62 // expand their accessibility 63 64 /** Associates {@code key} with {@code producerOfValue}. */ put(K key, Producer<V> producerOfValue)65 Builder<K, V, V2> put(K key, Producer<V> producerOfValue) { 66 checkNotNull(key, "key"); 67 checkNotNull(producerOfValue, "producer of value"); 68 mapBuilder.put(key, producerOfValue); 69 return this; 70 } 71 72 /** Associates {@code key} with {@code providerOfValue}. */ put(K key, Provider<V> providerOfValue)73 Builder<K, V, V2> put(K key, Provider<V> providerOfValue) { 74 checkNotNull(key, "key"); 75 checkNotNull(providerOfValue, "provider of value"); 76 mapBuilder.put(key, producerFromProvider(providerOfValue)); 77 return this; 78 } 79 80 /** 81 * Legacy javax version of the method to support libraries compiled with an older version of 82 * Dagger. Do not use directly. 83 */ 84 @Deprecated put(K key, javax.inject.Provider<V> providerOfValue)85 Builder<K, V, V2> put(K key, javax.inject.Provider<V> providerOfValue) { 86 return put(key, asDaggerProvider(providerOfValue)); 87 } 88 89 /** Adds contributions from a super-implementation of a component into this builder. */ putAll(Producer<Map<K, V2>> mapOfProducers)90 Builder<K, V, V2> putAll(Producer<Map<K, V2>> mapOfProducers) { 91 if (mapOfProducers instanceof DelegateProducer) { 92 @SuppressWarnings("unchecked") 93 DelegateProducer<Map<K, V2>> asDelegateProducer = (DelegateProducer) mapOfProducers; 94 return putAll(asDelegateProducer.getDelegate()); 95 } 96 @SuppressWarnings("unchecked") 97 AbstractMapProducer<K, V, ?> asAbstractMapProducer = 98 ((AbstractMapProducer<K, V, ?>) (Producer) mapOfProducers); 99 mapBuilder.putAll(asAbstractMapProducer.contributingMap); 100 return this; 101 } 102 } 103 } 104