• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.functional.jdk8;
18 
19 import static java.lang.annotation.RetentionPolicy.RUNTIME;
20 
21 import com.google.auto.value.AutoValue;
22 import dagger.BindsOptionalOf;
23 import dagger.Component;
24 import dagger.Lazy;
25 import dagger.Module;
26 import dagger.Provides;
27 import dagger.Subcomponent;
28 import java.lang.annotation.Retention;
29 import java.util.Optional;
30 import javax.annotation.Nullable;
31 import javax.inject.Inject;
32 import javax.inject.Provider;
33 import javax.inject.Qualifier;
34 
35 /** Classes to support testing {@code BindsOptionalOf} functionality. */
36 public final class OptionalBindingComponents {
37 
38   /** A qualifier. */
39   @Qualifier
40   @Retention(RUNTIME)
41   public @interface SomeQualifier {}
42 
43   /** A value object that contains various optionally-bound objects. */
44   @AutoValue
45   public abstract static class Values {
optionalInstance()46     abstract Optional<Value> optionalInstance();
47 
optionalProvider()48     abstract Optional<Provider<Value>> optionalProvider();
49 
optionalLazy()50     abstract Optional<Lazy<Value>> optionalLazy();
51 
optionalLazyProvider()52     abstract Optional<Provider<Lazy<Value>>> optionalLazyProvider();
53   }
54 
55   // Default access so that it's inaccessible to OptionalBindingComponentsWithInaccessibleTypes.
56   enum Value {
57     VALUE,
58     QUALIFIED_VALUE
59   }
60 
61   static final class InjectedThing {
62     @Inject
InjectedThing()63     InjectedThing() {}
64   }
65 
66   /** Binds optionals and {@link Values}. */
67   @Module
68   public abstract static class OptionalBindingModule {
69     @BindsOptionalOf
value()70     abstract Value value();
71 
72     @BindsOptionalOf
qualifiedValue()73     @SomeQualifier abstract Value qualifiedValue();
74 
75     // Valid because it's qualified.
76     @BindsOptionalOf
qualifiedInjectedThing()77     @SomeQualifier abstract InjectedThing qualifiedInjectedThing();
78 
79     @BindsOptionalOf
nullableObject()80     abstract Object nullableObject();
81 
82     @Provides
values( Optional<Value> optionalInstance, Optional<Provider<Value>> optionalProvider, Optional<Lazy<Value>> optionalLazy, Optional<Provider<Lazy<Value>>> optionalLazyProvider)83     static Values values(
84         Optional<Value> optionalInstance,
85         Optional<Provider<Value>> optionalProvider,
86         Optional<Lazy<Value>> optionalLazy,
87         Optional<Provider<Lazy<Value>>> optionalLazyProvider) {
88       return new AutoValue_OptionalBindingComponents_Values(
89           optionalInstance, optionalProvider, optionalLazy, optionalLazyProvider);
90     }
91 
92     @Provides
93     @SomeQualifier
qualifiedValues( @omeQualifier Optional<Value> optionalInstance, @SomeQualifier Optional<Provider<Value>> optionalProvider, @SomeQualifier Optional<Lazy<Value>> optionalLazy, @SomeQualifier Optional<Provider<Lazy<Value>>> optionalLazyProvider)94     static Values qualifiedValues(
95         @SomeQualifier Optional<Value> optionalInstance,
96         @SomeQualifier Optional<Provider<Value>> optionalProvider,
97         @SomeQualifier Optional<Lazy<Value>> optionalLazy,
98         @SomeQualifier Optional<Provider<Lazy<Value>>> optionalLazyProvider) {
99       return new AutoValue_OptionalBindingComponents_Values(
100           optionalInstance, optionalProvider, optionalLazy, optionalLazyProvider);
101     }
102   }
103 
104   /** Binds {@link Value}. */
105   @Module
106   public abstract static class ConcreteBindingModule {
107     /** @param cycle to demonstrate that optional {@link Provider} injection can break cycles */
108     @Provides
value(Optional<Provider<Value>> cycle)109     static Value value(Optional<Provider<Value>> cycle) {
110       return Value.VALUE;
111     }
112 
113     @Provides
qualifiedValue()114     @SomeQualifier static Value qualifiedValue() {
115       return Value.QUALIFIED_VALUE;
116     }
117 
118     @Provides
119     @Nullable
nullableObject()120     static Object nullableObject() {
121       return null;
122     }
123   }
124 
125   /** Interface for components used to test optional bindings. */
126   public interface OptionalBindingComponent {
values()127     Values values();
128 
129     @SomeQualifier
qualifiedValues()130     Values qualifiedValues();
131 
132     // Nullable bindings can satisfy optional bindings except for Optional<Foo>.
133 
optionalNullableProvider()134     Optional<Provider<Object>> optionalNullableProvider();
135 
optionalNullableLazy()136     Optional<Lazy<Object>> optionalNullableLazy();
137 
optionalNullableLazyProvider()138     Optional<Provider<Lazy<Object>>> optionalNullableLazyProvider();
139   }
140 
141   @Component(modules = OptionalBindingModule.class)
142   interface EmptyOptionalBindingComponent extends OptionalBindingComponent {
presentChild()143     PresentOptionalBindingSubcomponent presentChild();
144   }
145 
146   @Component(modules = {OptionalBindingModule.class, ConcreteBindingModule.class})
147   interface PresentOptionalBindingComponent extends OptionalBindingComponent {}
148 
149   @Subcomponent(modules = ConcreteBindingModule.class)
150   interface PresentOptionalBindingSubcomponent extends OptionalBindingComponent {}
151 }
152