1 /*
2  * Copyright (C) 2007 Google Inc.
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 com.google.inject.internal;
18 
19 import com.google.common.base.MoreObjects;
20 import com.google.common.base.Objects;
21 import com.google.common.collect.ImmutableSet;
22 import com.google.inject.Binder;
23 import com.google.inject.Key;
24 import com.google.inject.spi.BindingTargetVisitor;
25 import com.google.inject.spi.Dependency;
26 import com.google.inject.spi.HasDependencies;
27 import com.google.inject.spi.ProviderKeyBinding;
28 import java.util.Set;
29 
30 final class LinkedProviderBindingImpl<T> extends BindingImpl<T>
31     implements ProviderKeyBinding<T>, HasDependencies, DelayedInitialize {
32 
33   final Key<? extends javax.inject.Provider<? extends T>> providerKey;
34   final DelayedInitialize delayedInitializer;
35 
LinkedProviderBindingImpl( InjectorImpl injector, Key<T> key, Object source, InternalFactory<? extends T> internalFactory, Scoping scoping, Key<? extends javax.inject.Provider<? extends T>> providerKey, DelayedInitialize delayedInitializer)36   private LinkedProviderBindingImpl(
37       InjectorImpl injector,
38       Key<T> key,
39       Object source,
40       InternalFactory<? extends T> internalFactory,
41       Scoping scoping,
42       Key<? extends javax.inject.Provider<? extends T>> providerKey,
43       DelayedInitialize delayedInitializer) {
44     super(injector, key, source, internalFactory, scoping);
45     this.providerKey = providerKey;
46     this.delayedInitializer = delayedInitializer;
47   }
48 
LinkedProviderBindingImpl( InjectorImpl injector, Key<T> key, Object source, InternalFactory<? extends T> internalFactory, Scoping scoping, Key<? extends javax.inject.Provider<? extends T>> providerKey)49   public LinkedProviderBindingImpl(
50       InjectorImpl injector,
51       Key<T> key,
52       Object source,
53       InternalFactory<? extends T> internalFactory,
54       Scoping scoping,
55       Key<? extends javax.inject.Provider<? extends T>> providerKey) {
56     this(injector, key, source, internalFactory, scoping, providerKey, null);
57   }
58 
LinkedProviderBindingImpl( Object source, Key<T> key, Scoping scoping, Key<? extends javax.inject.Provider<? extends T>> providerKey)59   LinkedProviderBindingImpl(
60       Object source,
61       Key<T> key,
62       Scoping scoping,
63       Key<? extends javax.inject.Provider<? extends T>> providerKey) {
64     super(source, key, scoping);
65     this.providerKey = providerKey;
66     this.delayedInitializer = null;
67   }
68 
createWithInitializer( InjectorImpl injector, Key<T> key, Object source, InternalFactory<? extends T> internalFactory, Scoping scoping, Key<? extends javax.inject.Provider<? extends T>> providerKey, DelayedInitialize delayedInitializer)69   static <T> LinkedProviderBindingImpl<T> createWithInitializer(
70       InjectorImpl injector,
71       Key<T> key,
72       Object source,
73       InternalFactory<? extends T> internalFactory,
74       Scoping scoping,
75       Key<? extends javax.inject.Provider<? extends T>> providerKey,
76       DelayedInitialize delayedInitializer) {
77     return new LinkedProviderBindingImpl<T>(
78         injector, key, source, internalFactory, scoping, providerKey, delayedInitializer);
79   }
80 
81   @Override
acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor)82   public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
83     return visitor.visit(this);
84   }
85 
86   @Override
getProviderKey()87   public Key<? extends javax.inject.Provider<? extends T>> getProviderKey() {
88     return providerKey;
89   }
90 
91   @Override
initialize(InjectorImpl injector, Errors errors)92   public void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
93     if (delayedInitializer != null) {
94       delayedInitializer.initialize(injector, errors);
95     }
96   }
97 
98   @Override
getDependencies()99   public Set<Dependency<?>> getDependencies() {
100     return ImmutableSet.<Dependency<?>>of(Dependency.get(providerKey));
101   }
102 
103   @Override
withScoping(Scoping scoping)104   public BindingImpl<T> withScoping(Scoping scoping) {
105     return new LinkedProviderBindingImpl<T>(getSource(), getKey(), scoping, providerKey);
106   }
107 
108   @Override
withKey(Key<T> key)109   public BindingImpl<T> withKey(Key<T> key) {
110     return new LinkedProviderBindingImpl<T>(getSource(), key, getScoping(), providerKey);
111   }
112 
113   @Override
applyTo(Binder binder)114   public void applyTo(Binder binder) {
115     getScoping()
116         .applyTo(binder.withSource(getSource()).bind(getKey()).toProvider(getProviderKey()));
117   }
118 
119   @Override
toString()120   public String toString() {
121     return MoreObjects.toStringHelper(ProviderKeyBinding.class)
122         .add("key", getKey())
123         .add("source", getSource())
124         .add("scope", getScoping())
125         .add("provider", providerKey)
126         .toString();
127   }
128 
129   @Override
equals(Object obj)130   public boolean equals(Object obj) {
131     if (obj instanceof LinkedProviderBindingImpl) {
132       LinkedProviderBindingImpl<?> o = (LinkedProviderBindingImpl<?>) obj;
133       return getKey().equals(o.getKey())
134           && getScoping().equals(o.getScoping())
135           && Objects.equal(providerKey, o.providerKey);
136     } else {
137       return false;
138     }
139   }
140 
141   @Override
hashCode()142   public int hashCode() {
143     return Objects.hashCode(getKey(), getScoping(), providerKey);
144   }
145 }
146