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