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 17package com.google.inject.internal; 18 19import static com.google.common.base.Preconditions.checkNotNull; 20 21import com.google.inject.Key; 22import com.google.inject.internal.InjectorImpl.JitLimitation; 23import com.google.inject.spi.Dependency; 24 25import javax.inject.Provider; 26 27/** 28 * Delegates to a custom factory which is also bound in the injector. 29 */ 30final class BoundProviderFactory<T> extends ProviderInternalFactory<T> implements CreationListener { 31 32 private final ProvisionListenerStackCallback<T> provisionCallback; 33 private final InjectorImpl injector; 34 final Key<? extends javax.inject.Provider<? extends T>> providerKey; 35 private InternalFactory<? extends javax.inject.Provider<? extends T>> providerFactory; 36 37 BoundProviderFactory( 38 InjectorImpl injector, 39 Key<? extends javax.inject.Provider<? extends T>> providerKey, 40 Object source, 41 ProvisionListenerStackCallback<T> provisionCallback) { 42 super(source); 43 this.provisionCallback = checkNotNull(provisionCallback, "provisionCallback"); 44 this.injector = injector; 45 this.providerKey = providerKey; 46 } 47 48 public void notify(Errors errors) { 49 try { 50 providerFactory = injector.getInternalFactory(providerKey, errors.withSource(source), JitLimitation.NEW_OR_EXISTING_JIT); 51 } catch (ErrorsException e) { 52 errors.merge(e.getErrors()); 53 } 54 } 55 56 public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked) 57 throws ErrorsException { 58 context.pushState(providerKey, source); 59 try { 60 errors = errors.withSource(providerKey); 61 javax.inject.Provider<? extends T> provider = providerFactory.get(errors, context, dependency, true); 62 return circularGet(provider, errors, context, dependency, provisionCallback); 63 } finally { 64 context.popState(); 65 } 66 } 67 68 @Override 69 protected T provision(Provider<? extends T> provider, Errors errors, Dependency<?> dependency, 70 ConstructionContext<T> constructionContext) throws ErrorsException { 71 try { 72 return super.provision(provider, errors, dependency, constructionContext); 73 } catch(RuntimeException userException) { 74 throw errors.errorInProvider(userException).toException(); 75 } 76 } 77 78 @Override public String toString() { 79 return providerKey.toString(); 80 } 81} 82