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.Provider; 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.InjectionPoint; 28 import com.google.inject.spi.ProviderInstanceBinding; 29 import com.google.inject.spi.ProviderWithExtensionVisitor; 30 import com.google.inject.util.Providers; 31 32 import java.util.Set; 33 34 final class ProviderInstanceBindingImpl<T> extends BindingImpl<T> 35 implements ProviderInstanceBinding<T> { 36 37 final javax.inject.Provider<? extends T> providerInstance; 38 final ImmutableSet<InjectionPoint> injectionPoints; 39 40 public ProviderInstanceBindingImpl(InjectorImpl injector, Key<T> key, 41 Object source, InternalFactory<? extends T> internalFactory, Scoping scoping, 42 javax.inject.Provider<? extends T> providerInstance, 43 Set<InjectionPoint> injectionPoints) { 44 super(injector, key, source, internalFactory, scoping); 45 this.providerInstance = providerInstance; 46 this.injectionPoints = ImmutableSet.copyOf(injectionPoints); 47 } 48 49 public ProviderInstanceBindingImpl(Object source, Key<T> key, Scoping scoping, 50 Set<InjectionPoint> injectionPoints, javax.inject.Provider<? extends T> providerInstance) { 51 super(source, key, scoping); 52 this.injectionPoints = ImmutableSet.copyOf(injectionPoints); 53 this.providerInstance = providerInstance; 54 } 55 56 @SuppressWarnings("unchecked") // the extension type is always consistent with the provider type 57 public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) { 58 if(providerInstance instanceof ProviderWithExtensionVisitor) { 59 return ((ProviderWithExtensionVisitor<? extends T>) providerInstance) 60 .acceptExtensionVisitor(visitor, this); 61 } else { 62 return visitor.visit(this); 63 } 64 } 65 66 public Provider<? extends T> getProviderInstance() { 67 return Providers.guicify(providerInstance); 68 } 69 70 public javax.inject.Provider<? extends T> getUserSuppliedProvider() { 71 return providerInstance; 72 } 73 74 public Set<InjectionPoint> getInjectionPoints() { 75 return injectionPoints; 76 } 77 78 public Set<Dependency<?>> getDependencies() { 79 return providerInstance instanceof HasDependencies 80 ? ImmutableSet.copyOf(((HasDependencies) providerInstance).getDependencies()) 81 : Dependency.forInjectionPoints(injectionPoints); 82 } 83 84 public BindingImpl<T> withScoping(Scoping scoping) { 85 return new ProviderInstanceBindingImpl<T>( 86 getSource(), getKey(), scoping, injectionPoints, providerInstance); 87 } 88 89 public BindingImpl<T> withKey(Key<T> key) { 90 return new ProviderInstanceBindingImpl<T>( 91 getSource(), key, getScoping(), injectionPoints, providerInstance); 92 } 93 94 public void applyTo(Binder binder) { 95 getScoping().applyTo( 96 binder.withSource(getSource()).bind(getKey()).toProvider(getUserSuppliedProvider())); 97 } 98 99 @Override 100 public String toString() { 101 return Objects.toStringHelper(ProviderInstanceBinding.class) 102 .add("key", getKey()) 103 .add("source", getSource()) 104 .add("scope", getScoping()) 105 .add("provider", providerInstance) 106 .toString(); 107 } 108 109 @Override 110 public boolean equals(Object obj) { 111 if(obj instanceof ProviderInstanceBindingImpl) { 112 ProviderInstanceBindingImpl<?> o = (ProviderInstanceBindingImpl<?>)obj; 113 return getKey().equals(o.getKey()) 114 && getScoping().equals(o.getScoping()) 115 && Objects.equal(providerInstance, o.providerInstance); 116 } else { 117 return false; 118 } 119 } 120 121 @Override 122 public int hashCode() { 123 return Objects.hashCode(getKey(), getScoping()); 124 } 125 } 126