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.util.concurrent.MoreExecutors.directExecutor; 20*f585d8a3SJacky Wang import static dagger.internal.Providers.asDaggerProvider; 21*f585d8a3SJacky Wang 22*f585d8a3SJacky Wang import com.google.common.base.Function; 23*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap; 24*f585d8a3SJacky Wang import com.google.common.collect.Maps; 25*f585d8a3SJacky Wang import com.google.common.util.concurrent.Futures; 26*f585d8a3SJacky Wang import com.google.common.util.concurrent.ListenableFuture; 27*f585d8a3SJacky Wang import dagger.internal.Provider; 28*f585d8a3SJacky Wang import dagger.producers.Producer; 29*f585d8a3SJacky Wang import java.util.ArrayList; 30*f585d8a3SJacky Wang import java.util.List; 31*f585d8a3SJacky Wang import java.util.Map; 32*f585d8a3SJacky Wang import java.util.Map.Entry; 33*f585d8a3SJacky Wang 34*f585d8a3SJacky Wang /** 35*f585d8a3SJacky Wang * A {@link Producer} implementation used to implement {@link Map} bindings. This producer returns a 36*f585d8a3SJacky Wang * {@code Map<K, V>} which is populated by calls to the delegate {@link Producer#get} methods. 37*f585d8a3SJacky Wang */ 38*f585d8a3SJacky Wang public final class MapProducer<K, V> extends AbstractMapProducer<K, V, V> { MapProducer(ImmutableMap<K, Producer<V>> contributingMap)39*f585d8a3SJacky Wang private MapProducer(ImmutableMap<K, Producer<V>> contributingMap) { 40*f585d8a3SJacky Wang super(contributingMap); 41*f585d8a3SJacky Wang } 42*f585d8a3SJacky Wang 43*f585d8a3SJacky Wang /** Returns a new {@link Builder}. */ builder(int size)44*f585d8a3SJacky Wang public static <K, V> Builder<K, V> builder(int size) { 45*f585d8a3SJacky Wang return new Builder<>(size); 46*f585d8a3SJacky Wang } 47*f585d8a3SJacky Wang 48*f585d8a3SJacky Wang /** A builder for {@link MapProducer} */ 49*f585d8a3SJacky Wang public static final class Builder<K, V> extends AbstractMapProducer.Builder<K, V, V> { Builder(int size)50*f585d8a3SJacky Wang private Builder(int size) { 51*f585d8a3SJacky Wang super(size); 52*f585d8a3SJacky Wang } 53*f585d8a3SJacky Wang 54*f585d8a3SJacky Wang @Override put(K key, Producer<V> producerOfValue)55*f585d8a3SJacky Wang public Builder<K, V> put(K key, Producer<V> producerOfValue) { 56*f585d8a3SJacky Wang super.put(key, producerOfValue); 57*f585d8a3SJacky Wang return this; 58*f585d8a3SJacky Wang } 59*f585d8a3SJacky Wang 60*f585d8a3SJacky Wang @Override put(K key, Provider<V> providerOfValue)61*f585d8a3SJacky Wang public Builder<K, V> put(K key, Provider<V> providerOfValue) { 62*f585d8a3SJacky Wang super.put(key, providerOfValue); 63*f585d8a3SJacky Wang return this; 64*f585d8a3SJacky Wang } 65*f585d8a3SJacky Wang 66*f585d8a3SJacky Wang /** 67*f585d8a3SJacky Wang * Legacy javax version of the method to support libraries compiled with an older version of 68*f585d8a3SJacky Wang * Dagger. Do not use directly. 69*f585d8a3SJacky Wang */ 70*f585d8a3SJacky Wang @Deprecated put(K key, javax.inject.Provider<V> providerOfValue)71*f585d8a3SJacky Wang public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { 72*f585d8a3SJacky Wang return put(key, asDaggerProvider(providerOfValue)); 73*f585d8a3SJacky Wang } 74*f585d8a3SJacky Wang 75*f585d8a3SJacky Wang @Override putAll(Producer<Map<K, V>> mapProducer)76*f585d8a3SJacky Wang public Builder<K, V> putAll(Producer<Map<K, V>> mapProducer) { 77*f585d8a3SJacky Wang super.putAll(mapProducer); 78*f585d8a3SJacky Wang return this; 79*f585d8a3SJacky Wang } 80*f585d8a3SJacky Wang 81*f585d8a3SJacky Wang /** Returns a new {@link MapProducer}. */ build()82*f585d8a3SJacky Wang public MapProducer<K, V> build() { 83*f585d8a3SJacky Wang return new MapProducer<>(mapBuilder.build()); 84*f585d8a3SJacky Wang } 85*f585d8a3SJacky Wang } 86*f585d8a3SJacky Wang 87*f585d8a3SJacky Wang @Override compute()88*f585d8a3SJacky Wang protected ListenableFuture<Map<K, V>> compute() { 89*f585d8a3SJacky Wang final List<ListenableFuture<Map.Entry<K, V>>> listOfEntries = new ArrayList<>(); 90*f585d8a3SJacky Wang for (final Entry<K, Producer<V>> entry : contributingMap().entrySet()) { 91*f585d8a3SJacky Wang listOfEntries.add( 92*f585d8a3SJacky Wang Futures.transform( 93*f585d8a3SJacky Wang entry.getValue().get(), 94*f585d8a3SJacky Wang new Function<V, Entry<K, V>>() { 95*f585d8a3SJacky Wang @Override 96*f585d8a3SJacky Wang public Entry<K, V> apply(V computedValue) { 97*f585d8a3SJacky Wang return Maps.immutableEntry(entry.getKey(), computedValue); 98*f585d8a3SJacky Wang } 99*f585d8a3SJacky Wang }, 100*f585d8a3SJacky Wang directExecutor())); 101*f585d8a3SJacky Wang } 102*f585d8a3SJacky Wang 103*f585d8a3SJacky Wang return Futures.transform( 104*f585d8a3SJacky Wang Futures.allAsList(listOfEntries), 105*f585d8a3SJacky Wang new Function<List<Map.Entry<K, V>>, Map<K, V>>() { 106*f585d8a3SJacky Wang @Override 107*f585d8a3SJacky Wang public Map<K, V> apply(List<Map.Entry<K, V>> entries) { 108*f585d8a3SJacky Wang return ImmutableMap.copyOf(entries); 109*f585d8a3SJacky Wang } 110*f585d8a3SJacky Wang }, 111*f585d8a3SJacky Wang directExecutor()); 112*f585d8a3SJacky Wang } 113*f585d8a3SJacky Wang } 114