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