Home | History | Annotate | Download | only in internal
      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