xref: /aosp_15_r20/external/dagger2/java/dagger/producers/Produced.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2014 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;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import static com.google.common.base.Preconditions.checkNotNull;
20*f585d8a3SJacky Wang 
21*f585d8a3SJacky Wang import com.google.common.base.Objects;
22*f585d8a3SJacky Wang import com.google.errorprone.annotations.CheckReturnValue;
23*f585d8a3SJacky Wang import dagger.internal.Beta;
24*f585d8a3SJacky Wang import java.util.concurrent.ExecutionException;
25*f585d8a3SJacky Wang import org.checkerframework.checker.nullness.compatqual.NullableDecl;
26*f585d8a3SJacky Wang 
27*f585d8a3SJacky Wang /**
28*f585d8a3SJacky Wang  * An interface that represents the result of a {@linkplain Producer production} of type {@code T},
29*f585d8a3SJacky Wang  * or an exception that was thrown during that production. For any type {@code T} that can be
30*f585d8a3SJacky Wang  * injected, you can also inject {@code Produced<T>}, which enables handling of any exceptions that
31*f585d8a3SJacky Wang  * were thrown during the production of {@code T}.
32*f585d8a3SJacky Wang  *
33*f585d8a3SJacky Wang  * <p>For example: <pre><code>
34*f585d8a3SJacky Wang  *   {@literal @}Produces Html getResponse(
35*f585d8a3SJacky Wang  *       UserInfo criticalInfo, {@literal Produced<ExtraInfo>} noncriticalInfo) {
36*f585d8a3SJacky Wang  *     try {
37*f585d8a3SJacky Wang  *       return new Html(criticalInfo, noncriticalInfo.get());
38*f585d8a3SJacky Wang  *     } catch (ExecutionException e) {
39*f585d8a3SJacky Wang  *       logger.warning(e, "Noncritical info");
40*f585d8a3SJacky Wang  *       return new Html(criticalInfo);
41*f585d8a3SJacky Wang  *     }
42*f585d8a3SJacky Wang  *   }
43*f585d8a3SJacky Wang  * </code></pre>
44*f585d8a3SJacky Wang  *
45*f585d8a3SJacky Wang  * @since 2.0
46*f585d8a3SJacky Wang  */
47*f585d8a3SJacky Wang @Beta
48*f585d8a3SJacky Wang @CheckReturnValue
49*f585d8a3SJacky Wang public abstract class Produced<T> {
50*f585d8a3SJacky Wang   /**
51*f585d8a3SJacky Wang    * Returns the result of a production.
52*f585d8a3SJacky Wang    *
53*f585d8a3SJacky Wang    * @throws ExecutionException if the production threw an exception
54*f585d8a3SJacky Wang    */
get()55*f585d8a3SJacky Wang   public abstract T get() throws ExecutionException;
56*f585d8a3SJacky Wang 
57*f585d8a3SJacky Wang   /**
58*f585d8a3SJacky Wang    * Two {@code Produced} objects compare equal if both are successful with equal values, or both
59*f585d8a3SJacky Wang    * are failed with equal exceptions.
60*f585d8a3SJacky Wang    */
61*f585d8a3SJacky Wang   @Override
equals(Object o)62*f585d8a3SJacky Wang   public abstract boolean equals(Object o);
63*f585d8a3SJacky Wang 
64*f585d8a3SJacky Wang   /** Returns an appropriate hash code to match {@link #equals(Object)}. */
65*f585d8a3SJacky Wang   @Override
hashCode()66*f585d8a3SJacky Wang   public abstract int hashCode();
67*f585d8a3SJacky Wang 
68*f585d8a3SJacky Wang   /** Returns a successful {@code Produced}, whose {@link #get} will return the given value. */
successful(@ullableDecl T value)69*f585d8a3SJacky Wang   public static <T> Produced<T> successful(@NullableDecl T value) {
70*f585d8a3SJacky Wang     return new Successful<T>(value);
71*f585d8a3SJacky Wang   }
72*f585d8a3SJacky Wang 
73*f585d8a3SJacky Wang   /**
74*f585d8a3SJacky Wang    * Returns a failed {@code Produced}, whose {@link #get} will throw an
75*f585d8a3SJacky Wang    * {@code ExecutionException} with the given cause.
76*f585d8a3SJacky Wang    */
failed(Throwable throwable)77*f585d8a3SJacky Wang   public static <T> Produced<T> failed(Throwable throwable) {
78*f585d8a3SJacky Wang     return new Failed<T>(checkNotNull(throwable));
79*f585d8a3SJacky Wang   }
80*f585d8a3SJacky Wang 
81*f585d8a3SJacky Wang   private static final class Successful<T> extends Produced<T> {
82*f585d8a3SJacky Wang     @NullableDecl private final T value;
83*f585d8a3SJacky Wang 
Successful(@ullableDecl T value)84*f585d8a3SJacky Wang     private Successful(@NullableDecl T value) {
85*f585d8a3SJacky Wang       this.value = value;
86*f585d8a3SJacky Wang     }
87*f585d8a3SJacky Wang 
88*f585d8a3SJacky Wang     @Override
89*f585d8a3SJacky Wang     @NullableDecl
get()90*f585d8a3SJacky Wang     public T get() {
91*f585d8a3SJacky Wang       return value;
92*f585d8a3SJacky Wang     }
93*f585d8a3SJacky Wang 
94*f585d8a3SJacky Wang     @Override
equals(Object o)95*f585d8a3SJacky Wang     public boolean equals(Object o) {
96*f585d8a3SJacky Wang       if (o == this) {
97*f585d8a3SJacky Wang         return true;
98*f585d8a3SJacky Wang       } else if (o instanceof Successful) {
99*f585d8a3SJacky Wang         Successful<?> that = (Successful<?>) o;
100*f585d8a3SJacky Wang         return Objects.equal(this.value, that.value);
101*f585d8a3SJacky Wang       } else {
102*f585d8a3SJacky Wang         return false;
103*f585d8a3SJacky Wang       }
104*f585d8a3SJacky Wang     }
105*f585d8a3SJacky Wang 
106*f585d8a3SJacky Wang     @Override
hashCode()107*f585d8a3SJacky Wang     public int hashCode() {
108*f585d8a3SJacky Wang       return value == null ? 0 : value.hashCode();
109*f585d8a3SJacky Wang     }
110*f585d8a3SJacky Wang 
111*f585d8a3SJacky Wang     @Override
toString()112*f585d8a3SJacky Wang     public String toString() {
113*f585d8a3SJacky Wang       return "Produced[" + value + "]";
114*f585d8a3SJacky Wang     }
115*f585d8a3SJacky Wang   }
116*f585d8a3SJacky Wang 
117*f585d8a3SJacky Wang   private static final class Failed<T> extends Produced<T> {
118*f585d8a3SJacky Wang     private final Throwable throwable;
119*f585d8a3SJacky Wang 
Failed(Throwable throwable)120*f585d8a3SJacky Wang     private Failed(Throwable throwable) {
121*f585d8a3SJacky Wang       this.throwable = checkNotNull(throwable);
122*f585d8a3SJacky Wang     }
123*f585d8a3SJacky Wang 
124*f585d8a3SJacky Wang     @Override
get()125*f585d8a3SJacky Wang     public T get() throws ExecutionException {
126*f585d8a3SJacky Wang       throw new ExecutionException(throwable);
127*f585d8a3SJacky Wang     }
128*f585d8a3SJacky Wang 
129*f585d8a3SJacky Wang     @Override
equals(Object o)130*f585d8a3SJacky Wang     public boolean equals(Object o) {
131*f585d8a3SJacky Wang       if (o == this) {
132*f585d8a3SJacky Wang         return true;
133*f585d8a3SJacky Wang       } else if (o instanceof Failed) {
134*f585d8a3SJacky Wang         Failed<?> that = (Failed<?>) o;
135*f585d8a3SJacky Wang         return this.throwable.equals(that.throwable);
136*f585d8a3SJacky Wang       } else {
137*f585d8a3SJacky Wang         return false;
138*f585d8a3SJacky Wang       }
139*f585d8a3SJacky Wang     }
140*f585d8a3SJacky Wang 
141*f585d8a3SJacky Wang     @Override
hashCode()142*f585d8a3SJacky Wang     public int hashCode() {
143*f585d8a3SJacky Wang       return throwable.hashCode();
144*f585d8a3SJacky Wang     }
145*f585d8a3SJacky Wang 
146*f585d8a3SJacky Wang     @Override
toString()147*f585d8a3SJacky Wang     public String toString() {
148*f585d8a3SJacky Wang       return "Produced[failed with " + throwable.getClass().getCanonicalName() + "]";
149*f585d8a3SJacky Wang     }
150*f585d8a3SJacky Wang   }
151*f585d8a3SJacky Wang 
Produced()152*f585d8a3SJacky Wang   private Produced() {}
153*f585d8a3SJacky Wang }
154