1 /*
2  * Copyright (C) 2018 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.Preconditions.checkNotNull;
20 
21 import com.google.common.util.concurrent.ListenableFuture;
22 import dagger.internal.DoubleCheck;
23 import dagger.producers.Producer;
24 import javax.inject.Provider;
25 
26 /**
27  * A DelegateProducer that is used to stitch Producer indirection during initialization across
28  * partial subcomponent implementations.
29  */
30 public final class DelegateProducer<T> implements CancellableProducer<T> {
31   private CancellableProducer<T> delegate;
32 
33   @Override
get()34   public ListenableFuture<T> get() {
35     return delegate.get();
36   }
37 
38   // TODO(ronshapiro): remove this once we can reasonably expect generated code is no longer using
39   // this method
40   @Deprecated
setDelegatedProducer(Producer<T> delegate)41   public void setDelegatedProducer(Producer<T> delegate) {
42     setDelegate(this, delegate);
43   }
44 
45   /**
46    * Sets {@code delegateProducer}'s delegate producer to {@code delegate}.
47    *
48    * <p>{@code delegateProducer} must be an instance of {@link DelegateProducer}, otherwise this
49    * method will throw a {@link ClassCastException}.
50    */
setDelegate(Producer<T> delegateProducer, Producer<T> delegate)51   public static <T> void setDelegate(Producer<T> delegateProducer, Producer<T> delegate) {
52     checkNotNull(delegate);
53     DelegateProducer<T> asDelegateProducer = (DelegateProducer<T>) delegateProducer;
54     if (asDelegateProducer.delegate != null) {
55       throw new IllegalStateException();
56     }
57     asDelegateProducer.delegate = (CancellableProducer<T>) delegate;
58   }
59 
60   /**
61    * Returns the factory's delegate.
62    *
63    * @throws NullPointerException if the delegate has not been set
64    */
getDelegate()65   CancellableProducer<T> getDelegate() {
66     return checkNotNull(delegate);
67   }
68 
69   @Override
cancel(boolean mayInterruptIfRunning)70   public void cancel(boolean mayInterruptIfRunning) {
71     delegate.cancel(mayInterruptIfRunning);
72   }
73 
74   @Override
newDependencyView()75   public Producer<T> newDependencyView() {
76     return new ProducerView<T>() {
77       @Override
78       Producer<T> createDelegate() {
79         return delegate.newDependencyView();
80       }
81     };
82   }
83 
84   @Override
85   public Producer<T> newEntryPointView(final CancellationListener cancellationListener) {
86     return new ProducerView<T>() {
87       @Override
88       Producer<T> createDelegate() {
89         return delegate.newEntryPointView(cancellationListener);
90       }
91     };
92   }
93 
94   private abstract static class ProducerView<T> implements Producer<T> {
95     private final Provider<Producer<T>> delegate =
96         DoubleCheck.provider(
97             new Provider<Producer<T>>() {
98               @Override
99               public Producer<T> get() {
100                 return createDelegate();
101               }
102             });
103 
104     abstract Producer<T> createDelegate();
105 
106     @Override
107     public ListenableFuture<T> get() {
108       return delegate.get().get();
109     }
110   }
111 }
112