Renaming ExternalContext to InjectionPoint, and changing how it's used in ProvisionException. Also changing LoggerProvider to LoggerFactory.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@378 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/BinderImpl.java b/src/com/google/inject/BinderImpl.java
index 0ba96ee..6e58b43 100644
--- a/src/com/google/inject/BinderImpl.java
+++ b/src/com/google/inject/BinderImpl.java
@@ -16,7 +16,6 @@
package com.google.inject;
-import static com.google.inject.Nullability.NULLABLE;
import com.google.inject.InjectorImpl.SingleMemberInjector;
import static com.google.inject.Scopes.SINGLETON;
import com.google.inject.internal.Annotations;
@@ -94,7 +93,7 @@
bindScope(Singleton.class, SINGLETON);
bind(Logger.class, SourceProviders.UNKNOWN_SOURCE)
- .toProvider(new LoggerProvider());
+ .toInternalFactory(new LoggerFactory());
bind(Stage.class, SourceProviders.UNKNOWN_SOURCE).toInstance(stage);
this.proxyFactoryBuilder = new ProxyFactoryBuilder();
@@ -674,14 +673,19 @@
}
public Void call(InternalContext context) {
- context.pushExternalContext(ExternalContext.newInstance(
- null, NULLABLE, key, context.getInjectorImpl()));
+ InjectionPoint<?> injectionPoint
+ = InjectionPoint.newInstance(key, context.getInjectorImpl());
+ context.setInjectionPoint(injectionPoint);
try {
- factory.get(context);
+ factory.get(context, injectionPoint);
return null;
}
+ catch(ProvisionException provisionException) {
+ provisionException.addContext(injectionPoint);
+ throw provisionException;
+ }
finally {
- context.popExternalContext();
+ context.setInjectionPoint(null);
}
}
}
@@ -744,12 +748,10 @@
return (Provider<T>) ILLEGAL_PROVIDER;
}
- static class LoggerProvider implements Provider<Logger> {
+ static class LoggerFactory implements InternalFactory<Logger> {
- @Inject Injector injector;
- public Logger get() {
- InternalContext context = ((InjectorImpl) injector).getContext();
- Member member = context.getExternalContext().getMember();
+ public Logger get(InternalContext context, InjectionPoint<?> injectionPoint) {
+ Member member = injectionPoint.getMember();
return member == null
? Logger.getAnonymousLogger()
: Logger.getLogger(member.getDeclaringClass().getName());
diff --git a/src/com/google/inject/BindingBuilderImpl.java b/src/com/google/inject/BindingBuilderImpl.java
index 8b0fb6b..dfe4942 100644
--- a/src/com/google/inject/BindingBuilderImpl.java
+++ b/src/com/google/inject/BindingBuilderImpl.java
@@ -166,6 +166,17 @@
return this;
}
+ public BindingBuilderImpl<T> toInternalFactory(InternalFactory<T> internalFactory) {
+ ensureImplementationIsNotSet();
+ this.factory = internalFactory;
+ this.providerInstance = new Provider<T>() {
+ public T get() {
+ throw new UnsupportedOperationException("?");
+ }
+ };
+ return this;
+ }
+
public BindingBuilderImpl<T> toProvider(
Class<? extends Provider<? extends T>> providerType) {
return toProvider(Key.get(providerType));
@@ -411,8 +422,8 @@
});
}
- public T get(InternalContext context) {
- return targetFactory.get(context);
+ public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
+ return targetFactory.get(context, injectionPoint);
}
public String toString() {
diff --git a/src/com/google/inject/BoundProviderFactory.java b/src/com/google/inject/BoundProviderFactory.java
index 8cb9a4c..f0708e0 100644
--- a/src/com/google/inject/BoundProviderFactory.java
+++ b/src/com/google/inject/BoundProviderFactory.java
@@ -56,15 +56,14 @@
return providerKey.toString();
}
- public T get(InternalContext context) {
- Provider<? extends T> provider = providerFactory.get(context);
+ public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
+ Provider<? extends T> provider = providerFactory.get(context, injectionPoint);
try {
- return context.checkForNull(provider.get(), source);
+ return injectionPoint.checkForNull(provider.get(), source);
} catch(ProvisionException e) {
throw e;
} catch(RuntimeException e) {
- throw new ProvisionException(context.getExternalContextStack(),
- e, ErrorMessages.ERROR_IN_PROVIDER);
+ throw new ProvisionException(e, ErrorMessages.ERROR_IN_PROVIDER);
}
}
}
diff --git a/src/com/google/inject/ClassBindingImpl.java b/src/com/google/inject/ClassBindingImpl.java
index cb727c1..edf776f 100644
--- a/src/com/google/inject/ClassBindingImpl.java
+++ b/src/com/google/inject/ClassBindingImpl.java
@@ -53,7 +53,7 @@
if (constructor.parameterInjectors != null) {
for (SingleParameterInjector<?> parameterInjector
: constructor.parameterInjectors) {
- injectors.add(parameterInjector.externalContext);
+ injectors.add(parameterInjector.injectionPoint);
}
}
return injectors;
diff --git a/src/com/google/inject/ConstantFactory.java b/src/com/google/inject/ConstantFactory.java
index 31a1b95..6d743fa 100644
--- a/src/com/google/inject/ConstantFactory.java
+++ b/src/com/google/inject/ConstantFactory.java
@@ -16,7 +16,6 @@
package com.google.inject;
-import com.google.inject.internal.Objects;
import com.google.inject.internal.ToStringBuilder;
/**
@@ -30,7 +29,7 @@
this.value = value;
}
- public T get(InternalContext context) {
+ public T get(InternalContext context, InjectionPoint injectionPoint) {
return value;
}
diff --git a/src/com/google/inject/ConstructorInjector.java b/src/com/google/inject/ConstructorInjector.java
index 35c0757..5375154 100644
--- a/src/com/google/inject/ConstructorInjector.java
+++ b/src/com/google/inject/ConstructorInjector.java
@@ -159,8 +159,8 @@
}
catch (InvocationTargetException e) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
- throw new ProvisionException(context.getExternalContextStack(),
- cause, ErrorMessages.ERROR_INJECTING_CONSTRUCTOR);
+ throw new ProvisionException(cause,
+ ErrorMessages.ERROR_INJECTING_CONSTRUCTOR);
}
finally {
constructionContext.removeCurrentReference();
diff --git a/src/com/google/inject/ExternalContext.java b/src/com/google/inject/ExternalContext.java
deleted file mode 100644
index c5617d3..0000000
--- a/src/com/google/inject/ExternalContext.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Copyright (C) 2006 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.inject;
-
-import java.lang.reflect.Member;
-import java.util.LinkedHashMap;
-import com.google.inject.internal.Objects;
-import com.google.inject.spi.Dependency;
-
-/**
- * An immutable snapshot of the current context which is safe to expose to
- * client code.
- *
- * @author crazybob@google.com (Bob Lee)
- */
-class ExternalContext<T> implements Dependency<T> {
-
- final Member member;
- final Key<T> key;
- final InjectorImpl injector;
- final int parameterIndex;
- final Nullability nullability;
-
- public ExternalContext(Member member, int paramterIndex,
- Nullability nullability, Key<T> key, InjectorImpl injector) {
- this.member = member;
- this.parameterIndex = paramterIndex;
- this.nullability = Objects.nonNull(nullability, "nullability");
- this.key = key;
- this.injector = injector;
- }
-
- public Key<T> getKey() {
- return this.key;
- }
-
- public Binding<T> getBinding() {
- return injector.getBinding(key);
- }
-
- public boolean allowsNull() {
- return getNullability() == Nullability.NULLABLE;
- }
-
- public Injector getInjector() {
- return injector;
- }
-
- public Member getMember() {
- return member;
- }
-
- public int getParameterIndex() {
- return parameterIndex;
- }
-
- public Nullability getNullability() {
- return nullability;
- }
-
- public String toString() {
- return "Context" + new LinkedHashMap<String, Object>() {{
- put("member", member);
- put("key", getKey());
- put("injector", injector);
- }}.toString();
- }
-
- static <T> ExternalContext<T> newInstance(Member member,
- Nullability nullability, Key<T> key, InjectorImpl injector) {
- return new ExternalContext<T>(member, -1, nullability, key, injector);
- }
-
- static <T> ExternalContext<T> newInstance(Member member, int parameterIndex,
- Nullability nullability, Key<T> key, InjectorImpl injector) {
- return new ExternalContext<T>(member, parameterIndex, nullability, key,
- injector);
- }
-}
diff --git a/src/com/google/inject/InjectionPoint.java b/src/com/google/inject/InjectionPoint.java
new file mode 100644
index 0000000..378bfa4
--- /dev/null
+++ b/src/com/google/inject/InjectionPoint.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Field;
+import java.util.LinkedHashMap;
+import com.google.inject.internal.Objects;
+import com.google.inject.spi.Dependency;
+
+/**
+ * An immutable snapshot of where the value is to be injected.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+class InjectionPoint<T> implements Dependency<T> {
+
+ final Member member;
+ final Key<T> key;
+ final InjectorImpl injector;
+ final int parameterIndex;
+ final Nullability nullability;
+
+ private InjectionPoint(Member member, int paramterIndex,
+ Nullability nullability, Key<T> key, InjectorImpl injector) {
+ this.member = member;
+ this.parameterIndex = paramterIndex;
+ this.nullability = Objects.nonNull(nullability, "nullability");
+ this.key = key;
+ this.injector = injector;
+ }
+
+ public Key<T> getKey() {
+ return this.key;
+ }
+
+ public Binding<T> getBinding() {
+ return injector.getBinding(key);
+ }
+
+ public boolean allowsNull() {
+ return getNullability() == Nullability.NULLABLE;
+ }
+
+ public Injector getInjector() {
+ return injector;
+ }
+
+ public Member getMember() {
+ return member;
+ }
+
+ public int getParameterIndex() {
+ return parameterIndex;
+ }
+
+ public Nullability getNullability() {
+ return nullability;
+ }
+
+ public String toString() {
+ return "Context" + new LinkedHashMap<String, Object>() {{
+ put("member", member);
+ put("key", getKey());
+ put("injector", injector);
+ }}.toString();
+ }
+
+ <T> T checkForNull(T value, Object source) {
+ if (value != null
+ || getNullability() == Nullability.NULLABLE
+ || allowNullsBadBadBad()) {
+ return value;
+ }
+
+ String message = getMember() != null
+ ? String.format(ErrorMessages.CANNOT_INJECT_NULL_INTO_MEMBER, source,
+ getMember())
+ : String.format(ErrorMessages.CANNOT_INJECT_NULL, source);
+
+ throw new ProvisionException(new NullPointerException(message),
+ String.format(ErrorMessages.CANNOT_INJECT_NULL, source));
+ }
+
+ // TODO(kevinb): gee, ya think we might want to remove this?
+ private static boolean allowNullsBadBadBad() {
+ return "I'm a bad hack".equals(
+ System.getProperty("guice.allow.nulls.bad.bad.bad"));
+ }
+
+ static <T> InjectionPoint<T> newInstance(Field field,
+ Nullability nullability, Key<T> key, InjectorImpl injector) {
+ return new InjectionPoint<T>(field, -1, nullability, key, injector);
+ }
+
+ static <T> InjectionPoint<T> newInstance(Key<T> key, InjectorImpl injector) {
+ return new InjectionPoint<T>(null, -1, Nullability.NULLABLE, key, injector);
+ }
+
+ static <T> InjectionPoint<T> newInstance(Member member, int parameterIndex,
+ Nullability nullability, Key<T> key, InjectorImpl injector) {
+ return new InjectionPoint<T>(member, parameterIndex, nullability, key,
+ injector);
+ }
+}
diff --git a/src/com/google/inject/InjectorImpl.java b/src/com/google/inject/InjectorImpl.java
index 52cc5f9..a9ff505 100644
--- a/src/com/google/inject/InjectorImpl.java
+++ b/src/com/google/inject/InjectorImpl.java
@@ -16,16 +16,16 @@
package com.google.inject;
+import com.google.inject.internal.Classes;
import com.google.inject.internal.GuiceFastClass;
import com.google.inject.internal.ReferenceCache;
import com.google.inject.internal.StackTraceElements;
import com.google.inject.internal.ToStringBuilder;
-import com.google.inject.internal.Classes;
-import com.google.inject.spi.SourceProviders;
-import com.google.inject.spi.ProviderBinding;
import com.google.inject.spi.BindingVisitor;
import com.google.inject.spi.ConvertedConstantBinding;
import com.google.inject.spi.Dependency;
+import com.google.inject.spi.ProviderBinding;
+import com.google.inject.spi.SourceProviders;
import com.google.inject.util.Providers;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
@@ -39,12 +39,12 @@
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Collection;
import java.util.concurrent.Callable;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastMethod;
@@ -252,7 +252,8 @@
Binding<T> providedBinding) {
final Provider<T> provider = providedBinding.getProvider();
return new InternalFactory<Provider<T>>() {
- public Provider<T> get(InternalContext context) {
+ public Provider<T> get(InternalContext context,
+ InjectionPoint injectionPoint) {
return provider;
}
};
@@ -506,12 +507,12 @@
}
@SuppressWarnings("unchecked")
- public T get(InternalContext context) {
+ public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
// This may not actually be safe because it could return a super type
// of T (if that's all the client needs), but it should be OK in
// practice thanks to the wonders of erasure.
return (T) constructorInjector.construct(
- context, context.getExpectedType());
+ context, injectionPoint.getKey().getRawType());
}
}
@@ -547,8 +548,9 @@
}
InternalFactory<T> internalFactory = new InternalFactory<T>() {
- public T get(InternalContext context) {
- Provider<?> provider = providerBinding.internalFactory.get(context);
+ public T get(InternalContext context, InjectionPoint injectionPoint) {
+ Provider<?> provider
+ = providerBinding.internalFactory.get(context, injectionPoint);
Object o = provider.get();
try {
return type.cast(o);
@@ -604,8 +606,8 @@
}
InternalFactory<T> internalFactory = new InternalFactory<T>() {
- public T get(InternalContext context) {
- return targetBinding.internalFactory.get(context);
+ public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
+ return targetBinding.internalFactory.get(context, injectionPoint);
}
};
@@ -786,7 +788,7 @@
final Field field;
final InternalFactory<?> factory;
- final ExternalContext<?> externalContext;
+ final InjectionPoint<?> injectionPoint;
public SingleFieldInjector(final InjectorImpl injector, Field field)
throws MissingDependencyException {
@@ -809,18 +811,18 @@
throw new MissingDependencyException(key, field);
}
- this.externalContext = ExternalContext.newInstance(field,
+ this.injectionPoint = InjectionPoint.newInstance(field,
Nullability.forAnnotations(field.getAnnotations()), key, injector);
}
public Collection<Dependency<?>> getDependencies() {
- return Collections.<Dependency<?>>singleton(externalContext);
+ return Collections.<Dependency<?>>singleton(injectionPoint);
}
public void inject(InternalContext context, Object o) {
- context.pushExternalContext(externalContext);
+ context.setInjectionPoint(injectionPoint);
try {
- Object value = factory.get(context);
+ Object value = factory.get(context, injectionPoint);
field.set(o, value);
}
catch (IllegalAccessException e) {
@@ -830,14 +832,15 @@
throw e;
}
catch (ProvisionException provisionException) {
+ provisionException.addContext(injectionPoint);
throw provisionException;
}
catch (RuntimeException runtimeException) {
- throw new ProvisionException(context.getExternalContextStack(),
- runtimeException, ErrorMessages.ERROR_INJECTING_FIELD);
+ throw new ProvisionException(runtimeException,
+ ErrorMessages.ERROR_INJECTING_FIELD);
}
finally {
- context.popExternalContext();
+ context.setInjectionPoint(null);
}
}
}
@@ -886,9 +889,9 @@
throw new MissingDependencyException(key, member);
}
- ExternalContext<T> externalContext = ExternalContext.newInstance(
+ InjectionPoint<T> injectionPoint = InjectionPoint.newInstance(
member, index, Nullability.forAnnotations(annotations), key, this);
- return new SingleParameterInjector<T>(externalContext, factory);
+ return new SingleParameterInjector<T>(injectionPoint, factory);
}
static class SingleMethodInjector implements SingleMemberInjector {
@@ -940,15 +943,15 @@
}
catch (InvocationTargetException e) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
- throw new ProvisionException(context.getExternalContextStack(),
- cause, ErrorMessages.ERROR_INJECTING_METHOD);
+ throw new ProvisionException(cause,
+ ErrorMessages.ERROR_INJECTING_METHOD);
}
}
public Collection<Dependency<?>> getDependencies() {
List<Dependency<?>> dependencies = new ArrayList<Dependency<?>>();
for (SingleParameterInjector<?> parameterInjector : parameterInjectors) {
- dependencies.add(parameterInjector.externalContext);
+ dependencies.add(parameterInjector.injectionPoint);
}
return Collections.unmodifiableList(dependencies);
}
@@ -1003,32 +1006,33 @@
static class SingleParameterInjector<T> {
- final ExternalContext<T> externalContext;
+ final InjectionPoint<T> injectionPoint;
final InternalFactory<? extends T> factory;
- public SingleParameterInjector(ExternalContext<T> externalContext,
+ public SingleParameterInjector(InjectionPoint<T> injectionPoint,
InternalFactory<? extends T> factory) {
- this.externalContext = externalContext;
+ this.injectionPoint = injectionPoint;
this.factory = factory;
}
T inject(InternalContext context) {
- context.pushExternalContext(externalContext);
+ context.setInjectionPoint(injectionPoint);
try {
- return factory.get(context);
+ return factory.get(context, injectionPoint);
}
catch (ConfigurationException e) {
throw e;
}
- catch (ProvisionException e) {
- throw e;
+ catch (ProvisionException provisionException) {
+ provisionException.addContext(injectionPoint);
+ throw provisionException;
}
catch (RuntimeException runtimeException) {
- throw new ProvisionException(context.getExternalContextStack(),
- runtimeException, ErrorMessages.ERROR_INJECTING_METHOD);
+ throw new ProvisionException(runtimeException,
+ ErrorMessages.ERROR_INJECTING_METHOD);
}
finally {
- context.popExternalContext();
+ context.setInjectionPoint(injectionPoint);
}
}
}
@@ -1086,13 +1090,18 @@
public T get() {
return callInContext(new ContextualCallable<T>() {
public T call(InternalContext context) {
- context.pushExternalContext(ExternalContext.newInstance(
- null, Nullability.NOT_NULLABLE, key, InjectorImpl.this));
+ InjectionPoint<T> injectionPoint
+ = InjectionPoint.newInstance(key, InjectorImpl.this);
+ context.setInjectionPoint(injectionPoint);
try {
- return factory.get(context);
+ return factory.get(context, injectionPoint);
+ }
+ catch(ProvisionException provisionException) {
+ provisionException.addContext(injectionPoint);
+ throw provisionException;
}
finally {
- context.popExternalContext();
+ context.setInjectionPoint(null);
}
}
});
@@ -1131,14 +1140,6 @@
};
/**
- * Gets context for the current thread. Returns null if no context has been
- * set up.
- */
- InternalContext getContext() {
- return localContext.get()[0];
- }
-
- /**
* Looks up thread local context. Creates (and removes) a new context if
* necessary.
*/
diff --git a/src/com/google/inject/InternalContext.java b/src/com/google/inject/InternalContext.java
index 2fae544..3f94320 100644
--- a/src/com/google/inject/InternalContext.java
+++ b/src/com/google/inject/InternalContext.java
@@ -32,8 +32,7 @@
final InjectorImpl injector;
Map<Object, ConstructionContext<?>> constructionContexts;
- final List<ExternalContext<?>> externalContextStack =
- new ArrayList<ExternalContext<?>>(5);
+ InjectionPoint injectionPoint;
InternalContext(InjectorImpl injector) {
this.injector = injector;
@@ -62,60 +61,11 @@
}
}
- @SuppressWarnings("unchecked")
- <T> ExternalContext<T> getExternalContext() {
- if (externalContextStack.isEmpty()) {
- throw new IllegalStateException("No external context on stack");
- }
- return (ExternalContext<T>) externalContextStack.get(
- externalContextStack.size() - 1);
+ public InjectionPoint getInjectionPoint() {
+ return injectionPoint;
}
- public List<ExternalContext<?>> getExternalContextStack() {
- return Collections.unmodifiableList(
- new ArrayList<ExternalContext<?>>(externalContextStack));
- }
-
- Class<?> getExpectedType() {
- return getExternalContext().getKey().getRawType();
- }
-
- /**
- * Push a new external context onto the stack. Each call to {@code #push()}
- * requires a matching call to {@code #pop()} so that the contexts are
- * balanced.
- */
- void pushExternalContext(ExternalContext<?> externalContext) {
- externalContextStack.add(externalContext);
- }
-
- /**
- * Pop the external context off the stack.
- */
- void popExternalContext() {
- externalContextStack.remove(externalContextStack.size() - 1);
- }
-
- <T> T checkForNull(T value, Object source) {
- if (value != null
- || getExternalContext().getNullability() == Nullability.NULLABLE
- || allowNullsBadBadBad()) {
- return value;
- }
-
- String message = getExternalContext().getMember() != null
- ? String.format(ErrorMessages.CANNOT_INJECT_NULL_INTO_MEMBER, source,
- getExternalContext().getMember())
- : String.format(ErrorMessages.CANNOT_INJECT_NULL, source);
-
- throw new ProvisionException(getExternalContextStack(),
- new NullPointerException(message),
- String.format(ErrorMessages.CANNOT_INJECT_NULL, source));
- }
-
- // TODO(kevinb): gee, ya think we might want to remove this?
- private static boolean allowNullsBadBadBad() {
- return "I'm a bad hack".equals(
- System.getProperty("guice.allow.nulls.bad.bad.bad"));
+ public void setInjectionPoint(InjectionPoint injectionPoint) {
+ this.injectionPoint = injectionPoint;
}
}
diff --git a/src/com/google/inject/InternalFactory.java b/src/com/google/inject/InternalFactory.java
index ffb58ba..8af2bfb 100644
--- a/src/com/google/inject/InternalFactory.java
+++ b/src/com/google/inject/InternalFactory.java
@@ -29,5 +29,5 @@
* @param context of this injection
* @return instance to be injected; never null
*/
- T get(InternalContext context);
+ T get(InternalContext context, InjectionPoint<?> injectionPoint);
}
diff --git a/src/com/google/inject/InternalFactoryToProviderAdapter.java b/src/com/google/inject/InternalFactoryToProviderAdapter.java
index 67fb9d9..8037910 100644
--- a/src/com/google/inject/InternalFactoryToProviderAdapter.java
+++ b/src/com/google/inject/InternalFactoryToProviderAdapter.java
@@ -37,9 +37,9 @@
this.source = Objects.nonNull(source, "source");
}
- public T get(InternalContext context) {
+ public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
T provided = provider.get();
- return context.checkForNull(provided, source);
+ return injectionPoint.checkForNull(provided, source);
}
public String toString() {
diff --git a/src/com/google/inject/InvalidBindingImpl.java b/src/com/google/inject/InvalidBindingImpl.java
index ffa5278..a833143 100644
--- a/src/com/google/inject/InvalidBindingImpl.java
+++ b/src/com/google/inject/InvalidBindingImpl.java
@@ -22,7 +22,7 @@
InvalidBindingImpl(InjectorImpl injector, Key<T> key, Object source) {
super(injector, key, source, new InternalFactory<T>() {
- public T get(InternalContext context) {
+ public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
throw new AssertionError();
}
}, Scopes.NO_SCOPE);
diff --git a/src/com/google/inject/ProviderToInternalFactoryAdapter.java b/src/com/google/inject/ProviderToInternalFactoryAdapter.java
index 08b5484..9229b4f 100644
--- a/src/com/google/inject/ProviderToInternalFactoryAdapter.java
+++ b/src/com/google/inject/ProviderToInternalFactoryAdapter.java
@@ -34,7 +34,8 @@
public T get() {
return injector.callInContext(new ContextualCallable<T>() {
public T call(InternalContext context) {
- return internalFactory.get(context);
+ InjectionPoint injectionPoint = context.getInjectionPoint();
+ return internalFactory.get(context, injectionPoint);
}
});
}
diff --git a/src/com/google/inject/ProvisionException.java b/src/com/google/inject/ProvisionException.java
index 87e75f1..26a044d 100644
--- a/src/com/google/inject/ProvisionException.java
+++ b/src/com/google/inject/ProvisionException.java
@@ -35,14 +35,20 @@
public class ProvisionException extends RuntimeException {
private final String errorMessage;
- private final List<ExternalContext<?>> contexts;
+ private final List<InjectionPoint<?>> contexts
+ = new ArrayList<InjectionPoint<?>>(5);
- ProvisionException(List<ExternalContext<?>> externalContextStack,
- Throwable cause, String errorMessage) {
+ ProvisionException(Throwable cause, String errorMessage) {
super(errorMessage, cause);
this.errorMessage = errorMessage;
- this.contexts = Collections.unmodifiableList(
- new ArrayList<ExternalContext<?>>(externalContextStack));
+ }
+
+ /**
+ * Add an injection point that was being resolved when this exception
+ * occurred.
+ */
+ public void addContext(InjectionPoint<?> injectionPoint) {
+ this.contexts.add(injectionPoint);
}
@Override
@@ -51,9 +57,9 @@
result.append(errorMessage);
for (int i = contexts.size() - 1; i >= 0; i--) {
- ExternalContext externalContext = contexts.get(i);
+ InjectionPoint injectionPoint = contexts.get(i);
result.append(String.format("%n"));
- result.append(contextToSnippet(externalContext));
+ result.append(contextToSnippet(injectionPoint));
}
return result.toString();
@@ -63,10 +69,10 @@
* Returns a snippet to include in the stacktrace message that describes the
* specified context.
*/
- private String contextToSnippet(ExternalContext externalContext) {
- Key<?> key = externalContext.getKey();
+ private String contextToSnippet(InjectionPoint injectionPoint) {
+ Key<?> key = injectionPoint.getKey();
Object keyDescription = ErrorMessages.convert(key);
- Member member = externalContext.getMember();
+ Member member = injectionPoint.getMember();
if (member instanceof Field) {
return String.format(ERROR_WHILE_LOCATING_FIELD,
@@ -74,7 +80,7 @@
} else if (member instanceof Method || member instanceof Constructor) {
return String.format(ERROR_WHILE_LOCATING_PARAMETER,
- keyDescription, externalContext.getParameterIndex(),
+ keyDescription, injectionPoint.getParameterIndex(),
StackTraceElements.forMember(member));
} else {