All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dagger.producers.internal.Producers Maven / Gradle / Ivy

There is a newer version: 2.52
Show newest version
/*
 * Copyright (C) 2014 The Dagger Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dagger.producers.internal;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Futures.catchingAsync;
import static com.google.common.util.concurrent.Futures.transform;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import dagger.producers.Produced;
import dagger.producers.Producer;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Provider;

/**
 * Utility methods for use in generated producer code.
 */
public final class Producers {
  /**
   * Returns a future of {@link Produced} that represents the completion (either success or failure)
   * of the given future. If the input future succeeds, then the resulting future also succeeds with
   * a successful {@code Produced}; if the input future fails, then the resulting future succeeds
   * with a failing {@code Produced}.
   *
   * 

Cancelling the resulting future will propagate the cancellation to the input future; but * cancelling the input future will trigger the resulting future to succeed with a failing * {@code Produced}. */ // TODO(beder): Document what happens with an InterruptedException after you figure out how to // trigger one in a test. public static ListenableFuture> createFutureProduced(ListenableFuture future) { return catchingAsync( transform(future, Producers.resultToProduced(), directExecutor()), Throwable.class, Producers.futureFallbackForProduced(), directExecutor()); } private static final Function> RESULT_TO_PRODUCED = new Function>() { @Override public Produced apply(Object result) { return Produced.successful(result); } }; @SuppressWarnings({"unchecked", "rawtypes"}) // bivariant implementation private static Function> resultToProduced() { return (Function) RESULT_TO_PRODUCED; } private static final AsyncFunction> FUTURE_FALLBACK_FOR_PRODUCED = new AsyncFunction>() { @Override public ListenableFuture> apply(Throwable t) throws Exception { Produced produced = Produced.failed(t); return Futures.immediateFuture(produced); } }; @SuppressWarnings({"unchecked", "rawtypes"}) // bivariant implementation private static AsyncFunction> futureFallbackForProduced() { return (AsyncFunction) FUTURE_FALLBACK_FOR_PRODUCED; } /** * Returns a future of a {@code Set} that contains a single element: the result of the input * future. */ public static ListenableFuture> createFutureSingletonSet(ListenableFuture future) { return transform( future, new Function>() { @Override public Set apply(T value) { return ImmutableSet.of(value); } }, directExecutor()); } /** * Creates a new {@code ListenableFuture} whose value is a set containing the values of all its * input futures, if all succeed. If any input fails, the returned future fails immediately. * *

This is the set equivalent of {@link Futures#allAsList}. */ public static ListenableFuture> allAsSet( Iterable> futures) { return transform( Futures.allAsList(futures), new Function, Set>() { @Override public Set apply(List values) { return ImmutableSet.copyOf(values); } }, directExecutor()); } /** * Returns a producer that immediately executes the binding logic for the given provider every * time it is called. */ public static Producer producerFromProvider(final Provider provider) { checkNotNull(provider); return new Producer() { @Override public ListenableFuture get() { return Futures.immediateFuture(provider.get()); } }; } /** Returns a producer that succeeds with the given value. */ public static Producer immediateProducer(final T value) { return new Producer() { @Override public ListenableFuture get() { return Futures.immediateFuture(value); } }; } /** Returns a producer that fails with the given exception. */ public static Producer immediateFailedProducer(final Throwable throwable) { return new Producer() { @Override public ListenableFuture get() { return Futures.immediateFailedFuture(throwable); } }; } private static final Producer> EMPTY_MAP_PRODUCER = Producers.>immediateProducer(ImmutableMap.of()); @SuppressWarnings("unchecked") // safe contravariant cast public static Producer> emptyMapProducer() { return (Producer>) (Producer) EMPTY_MAP_PRODUCER; } private Producers() {} }