1 /** 2 * Copyright (C) 2006 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.inject.Binding; 21 import com.google.inject.Key; 22 import com.google.inject.Provider; 23 import com.google.inject.spi.BindingScopingVisitor; 24 import com.google.inject.spi.ElementVisitor; 25 import com.google.inject.spi.InstanceBinding; 26 27 /** 28 * @author crazybob (at) google.com (Bob Lee) 29 */ 30 public abstract class BindingImpl<T> implements Binding<T> { 31 32 private final InjectorImpl injector; 33 private final Key<T> key; 34 private final Object source; 35 private final Scoping scoping; 36 private final InternalFactory<? extends T> internalFactory; 37 38 public BindingImpl(InjectorImpl injector, Key<T> key, Object source, 39 InternalFactory<? extends T> internalFactory, Scoping scoping) { 40 this.injector = injector; 41 this.key = key; 42 this.source = source; 43 this.internalFactory = internalFactory; 44 this.scoping = scoping; 45 } 46 47 protected BindingImpl(Object source, Key<T> key, Scoping scoping) { 48 this.internalFactory = null; 49 this.injector = null; 50 this.source = source; 51 this.key = key; 52 this.scoping = scoping; 53 } 54 55 public Key<T> getKey() { 56 return key; 57 } 58 59 public Object getSource() { 60 return source; 61 } 62 63 private volatile Provider<T> provider; 64 65 public Provider<T> getProvider() { 66 if (provider == null) { 67 if (injector == null) { 68 throw new UnsupportedOperationException("getProvider() not supported for module bindings"); 69 } 70 71 provider = injector.getProvider(key); 72 } 73 return provider; 74 } 75 76 public InternalFactory<? extends T> getInternalFactory() { 77 return internalFactory; 78 } 79 80 public Scoping getScoping() { 81 return scoping; 82 } 83 84 /** 85 * Is this a constant binding? This returns true for constant bindings as 86 * well as toInstance() bindings. 87 */ 88 public boolean isConstant() { 89 return this instanceof InstanceBinding; 90 } 91 92 public <V> V acceptVisitor(ElementVisitor<V> visitor) { 93 return visitor.visit(this); 94 } 95 96 public <V> V acceptScopingVisitor(BindingScopingVisitor<V> visitor) { 97 return scoping.acceptVisitor(visitor); 98 } 99 100 protected BindingImpl<T> withScoping(Scoping scoping) { 101 throw new AssertionError(); 102 } 103 104 protected BindingImpl<T> withKey(Key<T> key) { 105 throw new AssertionError(); 106 } 107 108 @Override public String toString() { 109 return Objects.toStringHelper(Binding.class) 110 .add("key", key) 111 .add("scope", scoping) 112 .add("source", source) 113 .toString(); 114 } 115 116 public InjectorImpl getInjector() { 117 return injector; 118 } 119 } 120