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 dagger.internal.Providers.asDaggerProvider; 20 import static dagger.producers.internal.Producers.entryPointViewOf; 21 import static dagger.producers.internal.Producers.nonCancellationPropagatingViewOf; 22 23 import com.google.common.base.Function; 24 import com.google.common.collect.ImmutableMap; 25 import com.google.common.collect.Maps; 26 import com.google.common.util.concurrent.Futures; 27 import com.google.common.util.concurrent.ListenableFuture; 28 import dagger.internal.Provider; 29 import dagger.producers.Producer; 30 import java.util.Map; 31 32 /** 33 * A {@link Producer} implementation used to implement {@link Map} bindings. This factory returns an 34 * immediate future of {@code Map<K, Producer<V>>} when calling {@link #get}. 35 */ 36 public final class MapOfProducerProducer<K, V> extends AbstractMapProducer<K, V, Producer<V>> { 37 /** Returns a new {@link Builder}. */ builder(int size)38 public static <K, V> Builder<K, V> builder(int size) { 39 return new Builder<>(size); 40 } 41 MapOfProducerProducer(ImmutableMap<K, Producer<V>> contributingMap)42 private MapOfProducerProducer(ImmutableMap<K, Producer<V>> contributingMap) { 43 super(contributingMap); 44 } 45 46 @Override compute()47 public ListenableFuture<Map<K, Producer<V>>> compute() { 48 return Futures.<Map<K, Producer<V>>>immediateFuture(contributingMap()); 49 } 50 51 /** A builder for {@link MapOfProducerProducer} */ 52 public static final class Builder<K, V> extends AbstractMapProducer.Builder<K, V, Producer<V>> { Builder(int size)53 private Builder(int size) { 54 super(size); 55 } 56 57 @Override put(K key, Producer<V> producerOfValue)58 public Builder<K, V> put(K key, Producer<V> producerOfValue) { 59 super.put(key, producerOfValue); 60 return this; 61 } 62 63 @Override put(K key, Provider<V> providerOfValue)64 public Builder<K, V> put(K key, Provider<V> providerOfValue) { 65 super.put(key, providerOfValue); 66 return this; 67 } 68 69 /** 70 * Legacy javax version of the method to support libraries compiled with an older version of 71 * Dagger. Do not use directly. 72 */ 73 @Deprecated put(K key, javax.inject.Provider<V> providerOfValue)74 public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { 75 return put(key, asDaggerProvider(providerOfValue)); 76 } 77 78 @Override putAll(Producer<Map<K, Producer<V>>> mapOfProducerProducer)79 public Builder<K, V> putAll(Producer<Map<K, Producer<V>>> mapOfProducerProducer) { 80 super.putAll(mapOfProducerProducer); 81 return this; 82 } 83 84 /** Returns a new {@link MapOfProducerProducer}. */ build()85 public MapOfProducerProducer<K, V> build() { 86 return new MapOfProducerProducer<>(mapBuilder.build()); 87 } 88 } 89 90 @Override newDependencyView()91 public Producer<Map<K, Producer<V>>> newDependencyView() { 92 return newTransformedValuesView(MapOfProducerProducer.<V>toDependencyView()); 93 } 94 95 @Override newEntryPointView( CancellationListener cancellationListener)96 public Producer<Map<K, Producer<V>>> newEntryPointView( 97 CancellationListener cancellationListener) { 98 return newTransformedValuesView( 99 MapOfProducerProducer.<V>toEntryPointView(cancellationListener)); 100 } 101 newTransformedValuesView( Function<Producer<V>, Producer<V>> valueTransformationFunction)102 private Producer<Map<K, Producer<V>>> newTransformedValuesView( 103 Function<Producer<V>, Producer<V>> valueTransformationFunction) { 104 return dagger.producers.Producers.<Map<K, Producer<V>>>immediateProducer( 105 ImmutableMap.copyOf(Maps.transformValues(contributingMap(), valueTransformationFunction))); 106 } 107 108 @SuppressWarnings("unchecked") toDependencyView()109 private static <T> Function<Producer<T>, Producer<T>> toDependencyView() { 110 return (Function) TO_DEPENDENCY_VIEW; 111 } 112 toEntryPointView( final CancellationListener cancellationListener)113 private static <T> Function<Producer<T>, Producer<T>> toEntryPointView( 114 final CancellationListener cancellationListener) { 115 return new Function<Producer<T>, Producer<T>>() { 116 @Override 117 public Producer<T> apply(Producer<T> input) { 118 return entryPointViewOf(input, cancellationListener); 119 } 120 }; 121 } 122 123 private static final Function<Producer<?>, Producer<?>> TO_DEPENDENCY_VIEW = 124 new Function<Producer<?>, Producer<?>>() { 125 @Override 126 public Producer<?> apply(Producer<?> input) { 127 return nonCancellationPropagatingViewOf(input); 128 } 129 }; 130 } 131