1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2016 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.producers.internal; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import static com.google.common.base.Preconditions.checkNotNull; 20*f585d8a3SJacky Wang import static dagger.internal.Providers.asDaggerProvider; 21*f585d8a3SJacky Wang import static dagger.producers.internal.Producers.producerFromProvider; 22*f585d8a3SJacky Wang 23*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap; 24*f585d8a3SJacky Wang import dagger.internal.Provider; 25*f585d8a3SJacky Wang import dagger.producers.Producer; 26*f585d8a3SJacky Wang import java.util.Map; 27*f585d8a3SJacky Wang 28*f585d8a3SJacky Wang /** 29*f585d8a3SJacky Wang * An {@code abstract} {@link Producer} implementation used to implement {@link Map} bindings. 30*f585d8a3SJacky Wang * 31*f585d8a3SJacky Wang * @param <K>The key type of the map that this produces 32*f585d8a3SJacky Wang * @param <V>The type that each contributing producer 33*f585d8a3SJacky Wang * @param <V2>The value type of the map that this produces. For {@link MapProducer}, {@code V} and 34*f585d8a3SJacky Wang * {@code V2} will be equivalent. 35*f585d8a3SJacky Wang */ 36*f585d8a3SJacky Wang abstract class AbstractMapProducer<K, V, V2> extends AbstractProducer<Map<K, V2>> { 37*f585d8a3SJacky Wang private final ImmutableMap<K, Producer<V>> contributingMap; 38*f585d8a3SJacky Wang AbstractMapProducer(ImmutableMap<K, Producer<V>> contributingMap)39*f585d8a3SJacky Wang AbstractMapProducer(ImmutableMap<K, Producer<V>> contributingMap) { 40*f585d8a3SJacky Wang this.contributingMap = contributingMap; 41*f585d8a3SJacky Wang } 42*f585d8a3SJacky Wang 43*f585d8a3SJacky Wang /** The map of {@link Producer}s that contribute to this map binding. */ contributingMap()44*f585d8a3SJacky Wang final ImmutableMap<K, Producer<V>> contributingMap() { 45*f585d8a3SJacky Wang return contributingMap; 46*f585d8a3SJacky Wang } 47*f585d8a3SJacky Wang 48*f585d8a3SJacky Wang /** A builder for {@link AbstractMapProducer} */ 49*f585d8a3SJacky Wang public abstract static class Builder<K, V, V2> { 50*f585d8a3SJacky Wang final ImmutableMap.Builder<K, Producer<V>> mapBuilder; 51*f585d8a3SJacky Wang Builder(int size)52*f585d8a3SJacky Wang Builder(int size) { 53*f585d8a3SJacky Wang mapBuilder = ImmutableMap.builderWithExpectedSize(size); 54*f585d8a3SJacky Wang } 55*f585d8a3SJacky Wang 56*f585d8a3SJacky Wang // Unfortunately, we cannot return a self-type here because a raw Producer type passed to one of 57*f585d8a3SJacky Wang // these methods affects the returned type of the method. The first put*() call erases the self 58*f585d8a3SJacky Wang // type to the "raw" self type, and the second erases the type to the upper bound 59*f585d8a3SJacky Wang // (AbstractMapProducer.Builder), which doesn't have a build() method. 60*f585d8a3SJacky Wang // 61*f585d8a3SJacky Wang // The methods are therefore not declared public so that each subtype will redeclare them and 62*f585d8a3SJacky Wang // expand their accessibility 63*f585d8a3SJacky Wang 64*f585d8a3SJacky Wang /** Associates {@code key} with {@code producerOfValue}. */ put(K key, Producer<V> producerOfValue)65*f585d8a3SJacky Wang Builder<K, V, V2> put(K key, Producer<V> producerOfValue) { 66*f585d8a3SJacky Wang checkNotNull(key, "key"); 67*f585d8a3SJacky Wang checkNotNull(producerOfValue, "producer of value"); 68*f585d8a3SJacky Wang mapBuilder.put(key, producerOfValue); 69*f585d8a3SJacky Wang return this; 70*f585d8a3SJacky Wang } 71*f585d8a3SJacky Wang 72*f585d8a3SJacky Wang /** Associates {@code key} with {@code providerOfValue}. */ put(K key, Provider<V> providerOfValue)73*f585d8a3SJacky Wang Builder<K, V, V2> put(K key, Provider<V> providerOfValue) { 74*f585d8a3SJacky Wang checkNotNull(key, "key"); 75*f585d8a3SJacky Wang checkNotNull(providerOfValue, "provider of value"); 76*f585d8a3SJacky Wang mapBuilder.put(key, producerFromProvider(providerOfValue)); 77*f585d8a3SJacky Wang return this; 78*f585d8a3SJacky Wang } 79*f585d8a3SJacky Wang 80*f585d8a3SJacky Wang /** 81*f585d8a3SJacky Wang * Legacy javax version of the method to support libraries compiled with an older version of 82*f585d8a3SJacky Wang * Dagger. Do not use directly. 83*f585d8a3SJacky Wang */ 84*f585d8a3SJacky Wang @Deprecated put(K key, javax.inject.Provider<V> providerOfValue)85*f585d8a3SJacky Wang Builder<K, V, V2> put(K key, javax.inject.Provider<V> providerOfValue) { 86*f585d8a3SJacky Wang return put(key, asDaggerProvider(providerOfValue)); 87*f585d8a3SJacky Wang } 88*f585d8a3SJacky Wang 89*f585d8a3SJacky Wang /** Adds contributions from a super-implementation of a component into this builder. */ putAll(Producer<Map<K, V2>> mapOfProducers)90*f585d8a3SJacky Wang Builder<K, V, V2> putAll(Producer<Map<K, V2>> mapOfProducers) { 91*f585d8a3SJacky Wang if (mapOfProducers instanceof DelegateProducer) { 92*f585d8a3SJacky Wang @SuppressWarnings("unchecked") 93*f585d8a3SJacky Wang DelegateProducer<Map<K, V2>> asDelegateProducer = (DelegateProducer) mapOfProducers; 94*f585d8a3SJacky Wang return putAll(asDelegateProducer.getDelegate()); 95*f585d8a3SJacky Wang } 96*f585d8a3SJacky Wang @SuppressWarnings("unchecked") 97*f585d8a3SJacky Wang AbstractMapProducer<K, V, ?> asAbstractMapProducer = 98*f585d8a3SJacky Wang ((AbstractMapProducer<K, V, ?>) (Producer) mapOfProducers); 99*f585d8a3SJacky Wang mapBuilder.putAll(asAbstractMapProducer.contributingMap); 100*f585d8a3SJacky Wang return this; 101*f585d8a3SJacky Wang } 102*f585d8a3SJacky Wang } 103*f585d8a3SJacky Wang } 104