15d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/* 25d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Copyright (C) 2014 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; 175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.base.Objects; 195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.internal.Beta; 205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.concurrent.ExecutionException; 215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport javax.annotation.Nullable; 225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 235d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull; 245d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/** 265d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * An interface that represents the result of a {@linkplain Producer production} of type {@code T}, 275d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * or an exception that was thrown during that production. For any type {@code T} that can be 285d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * injected, you can also inject {@code Produced<T>}, which enables handling of any exceptions that 295d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * were thrown during the production of {@code T}. 305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 315d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * <p>For example: <pre><code> 325d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * {@literal @}Produces Html getResponse( 335d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * UserInfo criticalInfo, {@literal Produced<ExtraInfo>} noncriticalInfo) { 345d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * try { 355d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * return new Html(criticalInfo, noncriticalInfo.get()); 365d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * } catch (ExecutionException e) { 375d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * logger.warning(e, "Noncritical info"); 385d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * return new Html(criticalInfo); 395d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * } 405d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * } 415d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * </code></pre> 425d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 435d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * @author Jesse Beder 445d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 455d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin@Beta 465d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpublic abstract class Produced<T> { 475d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** 485d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Returns the result of a production. 495d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 505d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * @throws ExecutionException if the production threw an exception 515d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 525d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public abstract T get() throws ExecutionException; 535d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 545d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** 555d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Two {@code Produced} objects compare equal if both are successful with equal values, or both 565d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * are failed with equal exceptions. 575d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 585d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override 595d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public abstract boolean equals(Object o); 605d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 615d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** Returns an appropriate hash code to match {@link #equals). */ 625d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override 635d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public abstract int hashCode(); 645d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 655d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** Returns a successful {@code Produced}, whose {@link #get} will return the given value. */ 665d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public static <T> Produced<T> successful(@Nullable T value) { 6787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin return new Successful<T>(value); 685d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 695d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 705d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin /** 715d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Returns a failed {@code Produced}, whose {@link #get} will throw an 725d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * {@code ExecutionException} with the given cause. 735d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 745d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public static <T> Produced<T> failed(Throwable throwable) { 7587182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin return new Failed<T>(checkNotNull(throwable)); 765d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 775d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 785d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private static final class Successful<T> extends Produced<T> { 795d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Nullable private final T value; 805d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 815d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private Successful(@Nullable T value) { 825d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.value = value; 835d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 845d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 855d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public T get() { 865d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return value; 875d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 885d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 895d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public boolean equals(Object o) { 905d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (o == this) { 915d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return true; 925d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } else if (o instanceof Successful) { 9387182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin Successful<?> that = (Successful<?>) o; 945d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return Objects.equal(this.value, that.value); 955d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } else { 965d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return false; 975d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 985d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 995d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1005d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public int hashCode() { 1015d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return value == null ? 0 : value.hashCode(); 1025d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1035d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1045d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1055d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private static final class Failed<T> extends Produced<T> { 1065d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private final Throwable throwable; 1075d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1085d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private Failed(Throwable throwable) { 1095d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.throwable = checkNotNull(throwable); 1105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1115d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public T get() throws ExecutionException { 1135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin throw new ExecutionException(throwable); 1145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public boolean equals(Object o) { 1175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (o == this) { 1185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return true; 1195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } else if (o instanceof Failed) { 12087182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin Failed<?> that = (Failed<?>) o; 1215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return this.throwable.equals(that.throwable); 1225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } else { 1235d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return false; 1245d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1265d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1275d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public int hashCode() { 1285d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return throwable.hashCode(); 1295d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1315d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1325d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private Produced() {} 1335d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin} 134