15d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/* 25d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Copyright (C) 2015 Google, Inc. 35d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 45d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 55d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * you may not use this file except in compliance with the License. 65d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * You may obtain a copy of the License at 75d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 85d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 95d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Unless required by applicable law or agreed to in writing, software 115d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * See the License for the specific language governing permissions and 145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * limitations under the License. 155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpackage dagger.producers.internal; 175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.base.Function; 195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.collect.ImmutableSet; 205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.util.concurrent.Futures; 215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.util.concurrent.ListenableFuture; 225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.producers.Producer; 2387182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport dagger.producers.monitoring.ProducerMonitor; 245d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.ArrayList; 255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.List; 265d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.Set; 275d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 285d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/** 295d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * A {@link Producer} implementation used to implement {@link Set} bindings. This producer returns 305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * a future {@link Set} whose elements are populated by subsequent calls to the delegate 315d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * {@link Producer#get} methods. 325d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 335d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * @author Jesse Beder 345d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * @since 2.0 355d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 365d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpublic final class SetProducer<T> extends AbstractProducer<Set<T>> { 375d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** 385d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Returns a new producer that creates {@link Set} futures from the union of the given 395d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * {@link Producer} instances. 405d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 4187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin @SafeVarargs 4287182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin public static <T> Producer<Set<T>> create(Producer<Set<T>>... producers) { 435d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return new SetProducer<T>(ImmutableSet.copyOf(producers)); 445d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 455d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 465d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private final Set<Producer<Set<T>>> contributingProducers; 475d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 485d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private SetProducer(Set<Producer<Set<T>>> contributingProducers) { 495d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin super(); 505d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.contributingProducers = contributingProducers; 515d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 525d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 535d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** 545d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Returns a future {@link Set} whose iteration order is that of the elements given by each of the 555d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * producers, which are invoked in the order given at creation. 565d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 575d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * <p>If any of the delegate sets, or any elements therein, are null, then this future will fail 585d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * with a NullPointerException. 595d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 605d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * <p>Canceling this future will attempt to cancel all of the component futures, and if any of the 615d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * delegate futures fails or is canceled, this one is, too. 625d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 635d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * @throws NullPointerException if any of the delegate producers return null 645d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 655d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override 6687182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin public ListenableFuture<Set<T>> compute(ProducerMonitor unusedMonitor) { 675d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin List<ListenableFuture<Set<T>>> futureSets = 685d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin new ArrayList<ListenableFuture<Set<T>>>(contributingProducers.size()); 695d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin for (Producer<Set<T>> producer : contributingProducers) { 705d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ListenableFuture<Set<T>> futureSet = producer.get(); 715d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (futureSet == null) { 725d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin throw new NullPointerException(producer + " returned null"); 735d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 745d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin futureSets.add(futureSet); 755d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 765d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return Futures.transform(Futures.allAsList(futureSets), new Function<List<Set<T>>, Set<T>>() { 775d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public Set<T> apply(List<Set<T>> sets) { 785d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ImmutableSet.Builder<T> builder = ImmutableSet.builder(); 795d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin for (Set<T> set : sets) { 805d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin builder.addAll(set); 815d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 825d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return builder.build(); 835d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 845d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin }); 855d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 865d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin} 87