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