4 new revisions:
Revision: e5ed5b4fee89
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 16:45:21 2013
Log: Add an @Inject constructor to DefaultFilterPipeline so services
which ...
http://code.google.com/p/google-guice/source/detail?r=e5ed5b4fee89
Revision: 23030077f4b7
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 17:32:52 2013
Log: Upgrade to cglib 3.0 adn ASM 4.0....
http://code.google.com/p/google-guice/source/detail?r=23030077f4b7
Revision: a1867f8bcfac
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 17:52:45 2013
Log: update cglib dependency in poms.
http://code.google.com/p/google-guice/source/detail?r=a1867f8bcfac
Revision: bf2b16c06a5f
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 18:39:15 2013
Log: Add support for ProvisionListeners to notify on toInstance &
constant ...
http://code.google.com/p/google-guice/source/detail?r=bf2b16c06a5f
==============================================================================
Revision: e5ed5b4fee89
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 16:45:21 2013
Log: Add an @Inject constructor to DefaultFilterPipeline so services
which depend upon it can be used with
Modules.requireAtInjectOnConstructorsModule()
----------------
Manually synced.
COMMIT=33399588
http://code.google.com/p/google-guice/source/detail?r=e5ed5b4fee89
Modified:
/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java
=======================================
---
/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java
Sun Oct 16 15:35:11 2011
+++
/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java
Wed May 15 16:45:21 2013
@@ -17,6 +17,7 @@
import java.io.IOException;
+import javax.inject.Inject;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -30,6 +31,9 @@
* @see com.google.inject.servlet.ManagedFilterPipeline See Also
ManagedFilterPipeline.
*/
class DefaultFilterPipeline implements FilterPipeline {
+ @Inject DefaultFilterPipeline() {
+ }
+
public void initPipeline(ServletContext context) {
}
==============================================================================
Revision: 23030077f4b7
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 17:32:52 2013
Log: Upgrade to cglib 3.0 adn ASM 4.0.
------------------
Manually synced.
COMMIT=35272017
http://code.google.com/p/google-guice/source/detail?r=23030077f4b7
Added:
/extensions/persist/lib/cglib-nodep-3.0.jar
/lib/build/asm-4.0.jar
/lib/build/asm-util-4.0.jar
/lib/build/cglib-3.0.jar
Deleted:
/extensions/persist/lib/cglib-nodep-2.2.jar
/lib/build/asm-3.3.1.jar
/lib/build/cglib-2.2.2.jar
Modified:
/build.xml
/common.xml
/core/src/com/google/inject/internal/util/LineNumbers.java
=======================================
--- /dev/null
+++ /extensions/persist/lib/cglib-nodep-3.0.jar Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /dev/null
+++ /lib/build/asm-4.0.jar Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /dev/null
+++ /lib/build/asm-util-4.0.jar Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /dev/null
+++ /lib/build/cglib-3.0.jar Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /extensions/persist/lib/cglib-nodep-2.2.jar Fri Sep 10 19:10:20 2010
+++ /dev/null
Binary file, no diff available.
=======================================
--- /lib/build/asm-3.3.1.jar Wed Apr 20 09:57:24 2011
+++ /dev/null
Binary file, no diff available.
=======================================
--- /lib/build/cglib-2.2.2.jar Wed Apr 20 09:57:24 2011
+++ /dev/null
Binary file, no diff available.
=======================================
--- /build.xml Thu Jul 7 17:34:16 2011
+++ /build.xml Wed May 15 17:32:52 2013
@@ -236,13 +236,16 @@
<arg value="-DNO_AOP" />
</munge>
<replace file="build/no_aop/common.xml" value="">
- <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/asm-3.3.1.jar"/>]]></replacetoken>
+ <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/asm-4.0.jar"/>]]></replacetoken>
</replace>
<replace file="build/no_aop/common.xml" value="">
- <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/cglib-2.2.2.jar"/>]]></replacetoken>
+ <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/asm-util-4.0.jar"/>]]></replacetoken>
+ </replace>
+ <replace file="build/no_aop/common.xml" value="">
+ <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/cglib-3.0.jar"/>]]></replacetoken>
</replace>
<replace file="build/no_aop/common.xml" value="">
- <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/cglib-2.2.2.jar">
+ <replacetoken><![CDATA[<zipfileset
src="${common.basedir}/lib/build/cglib-3.0.jar">
<include name="LICENSE"/>
<include name="NOTICE"/>
</zipfileset>]]></replacetoken>
=======================================
--- /common.xml Fri Jan 13 15:32:04 2012
+++ /common.xml Wed May 15 17:32:52 2013
@@ -148,8 +148,9 @@
classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
<jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
<fileset dir="${build.dir}/classes"/>
- <zipfileset src="${common.basedir}/lib/build/cglib-2.2.2.jar"/>
- <zipfileset src="${common.basedir}/lib/build/asm-3.3.1.jar"/>
+ <zipfileset src="${common.basedir}/lib/build/cglib-3.0.jar"/>
+ <zipfileset src="${common.basedir}/lib/build/asm-4.0.jar"/>
+ <zipfileset src="${common.basedir}/lib/build/asm-util-4.0.jar"/>
<zipfileset src="${common.basedir}/lib/build/guava-11.0.1.jar"/>
<rule pattern="net.sf.cglib.*"
result="com.google.inject.internal.cglib.$@1"/>
<rule pattern="net.sf.cglib.**.*"
result="com.google.inject.internal.cglib.@1.$@2"/>
@@ -171,7 +172,7 @@
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
<jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
- <zipfileset src="${common.basedir}/lib/build/cglib-2.2.2.jar">
+ <zipfileset src="${common.basedir}/lib/build/cglib-3.0.jar">
<include name="LICENSE"/>
<include name="NOTICE"/>
</zipfileset>
=======================================
--- /core/src/com/google/inject/internal/util/LineNumbers.java Thu Jul 7
17:34:16 2011
+++ /core/src/com/google/inject/internal/util/LineNumbers.java Wed May 15
17:32:52 2013
@@ -22,7 +22,6 @@
import com.google.common.collect.Maps;
import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
@@ -123,12 +122,16 @@
end[NO_AOP]*/
}
- private class LineNumberReader implements ClassVisitor, MethodVisitor,
AnnotationVisitor {
+ private class LineNumberReader extends ClassVisitor {
private int line = -1;
private String pendingMethod;
private String name;
+ LineNumberReader() {
+ super(Opcodes.ASM4);
+ }
+
public void visit(int version, int access, String name, String
signature,
String superName, String[] interfaces) {
this.name = name;
@@ -141,7 +144,7 @@
}
pendingMethod = name + desc;
line = -1;
- return this;
+ return new LineNumberMethodVisitor();
}
public void visitSource(String source, String debug) {
@@ -159,27 +162,6 @@
pendingMethod = null;
}
}
-
- public void visitFieldInsn(int opcode, String owner, String name,
- String desc) {
- if (opcode == Opcodes.PUTFIELD && this.name.equals(owner)
- && !lines.containsKey(name) && line != -1) {
- lines.put(name, line);
- }
- }
-
- public void visitEnd() {
- }
-
- public void visitInnerClass(String name, String outerName, String
innerName,
- int access) {
- }
-
- public void visitOuterClass(String owner, String name, String desc) {
- }
-
- public void visitAttribute(Attribute attr) {
- }
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
@@ -187,86 +169,55 @@
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
{
- return this;
- }
-
- public AnnotationVisitor visitAnnotation(String name, String desc) {
- return this;
- }
-
- public AnnotationVisitor visitAnnotationDefault() {
- return this;
+ return new LineNumberAnnotationVisitor();
}
public AnnotationVisitor visitParameterAnnotation(int parameter,
String desc, boolean visible) {
- return this;
+ return new LineNumberAnnotationVisitor();
}
- public AnnotationVisitor visitArray(String name) {
- return this;
+ class LineNumberMethodVisitor extends MethodVisitor {
+ LineNumberMethodVisitor() {
+ super(Opcodes.ASM4);
}
- public void visitEnum(String name, String desc, String value) {
+ public AnnotationVisitor visitAnnotation(String desc, boolean
visible) {
+ return new LineNumberAnnotationVisitor();
}
- public void visit(String name, Object value) {
+ public AnnotationVisitor visitAnnotationDefault() {
+ return new LineNumberAnnotationVisitor();
}
- public void visitCode() {
- }
-
- public void visitFrame(int type, int nLocal, Object[] local, int
nStack,
- Object[] stack) {
+ public void visitFieldInsn(int opcode, String owner, String name,
+ String desc) {
+ if (opcode == Opcodes.PUTFIELD &&
LineNumberReader.this.name.equals(owner)
+ && !lines.containsKey(name) && line != -1) {
+ lines.put(name, line);
}
-
- public void visitIincInsn(int var, int increment) {
}
- public void visitInsn(int opcode) {
+ public void visitLineNumber(int line, Label start) {
+ LineNumberReader.this.visitLineNumber(line, start);
}
-
- public void visitIntInsn(int opcode, int operand) {
}
- public void visitJumpInsn(int opcode, Label label) {
+ class LineNumberAnnotationVisitor extends AnnotationVisitor {
+ LineNumberAnnotationVisitor() {
+ super(Opcodes.ASM4);
}
-
- public void visitLabel(Label label) {
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ return this;
}
-
- public void visitLdcInsn(Object cst) {
+ public AnnotationVisitor visitArray(String name) {
+ return this;
}
-
public void visitLocalVariable(String name, String desc, String
signature,
Label start, Label end, int index) {
}
- public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[]
labels) {
- }
-
- public void visitMaxs(int maxStack, int maxLocals) {
- }
-
- public void visitMethodInsn(int opcode, String owner, String name,
- String desc) {
- }
-
- public void visitMultiANewArrayInsn(String desc, int dims) {
- }
-
- public void visitTableSwitchInsn(int min, int max, Label dflt,
- Label[] labels) {
- }
-
- public void visitTryCatchBlock(Label start, Label end, Label handler,
- String type) {
- }
-
- public void visitTypeInsn(int opcode, String desc) {
}
- public void visitVarInsn(int opcode, int var) {
- }
}
}
==============================================================================
Revision: a1867f8bcfac
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 17:52:45 2013
Log: update cglib dependency in poms.
http://code.google.com/p/google-guice/source/detail?r=a1867f8bcfac
Modified:
/core/pom.xml
=======================================
--- /core/pom.xml Fri Aug 31 02:41:33 2012
+++ /core/pom.xml Wed May 15 17:52:45 2013
@@ -14,7 +14,7 @@
<name>Google Guice - Core Library</name>
<properties>
- <cglib.version>2.2.2</cglib.version>
+ <cglib.version>3.0</cglib.version>
</properties>
<dependencies>
==============================================================================
Revision: bf2b16c06a5f
Author: Christian Edward Gruber <[email protected]>
Date: Wed May 15 18:39:15 2013
Log: Add support for ProvisionListeners to notify on toInstance &
constant bindings.
---------------------
Manually synced.
COMMIT=41634417
http://code.google.com/p/google-guice/source/detail?r=bf2b16c06a5f
Modified:
/core/src/com/google/inject/internal/AbstractBindingProcessor.java
/core/src/com/google/inject/internal/BindingProcessor.java
/core/src/com/google/inject/internal/Initializer.java
/core/src/com/google/inject/internal/InjectorShell.java
/core/src/com/google/inject/internal/MembersInjectorImpl.java
/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
/core/src/com/google/inject/spi/ProvisionListener.java
/core/test/com/google/inject/BinderTest.java
/core/test/com/google/inject/BindingTest.java
/core/test/com/google/inject/ProvisionListenerTest.java
/core/test/com/google/inject/TypeListenerTest.java
/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
=======================================
--- /core/src/com/google/inject/internal/AbstractBindingProcessor.java Thu
Jul 7 17:34:16 2011
+++ /core/src/com/google/inject/internal/AbstractBindingProcessor.java Wed
May 15 18:39:15 2013
@@ -26,6 +26,7 @@
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.Scope;
+import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.DefaultBindingTargetVisitor;
@@ -51,8 +52,8 @@
Module.class,
Provider.class,
Scope.class,
+ Stage.class,
TypeLiteral.class);
- // TODO(jessewilson): fix BuiltInModule, then add Stage
protected final ProcessedBindingData bindingData;
=======================================
--- /core/src/com/google/inject/internal/BindingProcessor.java Thu May 31
16:54:04 2012
+++ /core/src/com/google/inject/internal/BindingProcessor.java Wed May 15
18:39:15 2013
@@ -87,8 +87,10 @@
prepareBinding();
Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
T instance = binding.getInstance();
+ @SuppressWarnings("unchecked") // safe to cast to binding<T>
because
+ // the processor was constructed w/
it
Initializable<T> ref = initializer.requestInjection(
- injector, instance, key, source, injectionPoints);
+ injector, instance, (Binding<T>) binding, source,
injectionPoints);
ConstantFactory<? extends T> factory = new ConstantFactory<T>(ref);
InternalFactory<? extends T> scopedFactory
= Scoping.scope(key, injector, factory, source, scoping);
=======================================
--- /core/src/com/google/inject/internal/Initializer.java Mon Oct 31
13:34:57 2011
+++ /core/src/com/google/inject/internal/Initializer.java Wed May 15
18:39:15 2013
@@ -21,6 +21,7 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
@@ -57,21 +58,25 @@
*
* @param instance an instance that optionally has members to be
injected (each annotated with
* @Inject).
- * @param key a key to use for keeping the state of the dependency chain
+ * @param binding the binding that caused this initializable to be
created, if it exists.
* @param source the source location that this injection was requested
*/
- <T> Initializable<T> requestInjection(InjectorImpl injector, T instance,
Key<T> key,
+ <T> Initializable<T> requestInjection(InjectorImpl injector, T instance,
Binding<T> binding,
Object source, Set<InjectionPoint> injectionPoints) {
checkNotNull(source);
- // short circuit if the object has no injections
- if (instance == null
- || (injectionPoints.isEmpty()
&& !injector.membersInjectorStore.hasTypeListeners())) {
+ ProvisionListenerStackCallback<T> provisionCallback =
+ binding == null ? null :
injector.provisionListenerStore.get(binding);
+
+ // short circuit if the object has no injections or listeners.
+ if (instance == null || (injectionPoints.isEmpty()
+ && !injector.membersInjectorStore.hasTypeListeners()
+ && (provisionCallback == null |
| !provisionCallback.hasListeners()))) {
return Initializables.of(instance);
}
- InjectableReference<T> initializable =
- new InjectableReference<T>(injector, instance, key, source);
+ InjectableReference<T> initializable = new InjectableReference<T>(
+ injector, instance, binding == null ? null : binding.getKey(),
provisionCallback, source);
pendingInjection.put(instance, initializable);
return initializable;
}
@@ -118,10 +123,13 @@
private final T instance;
private final Object source;
private final Key<T> key;
+ private final ProvisionListenerStackCallback<T> provisionCallback;
- public InjectableReference(InjectorImpl injector, T instance, Key<T>
key, Object source) {
+ public InjectableReference(InjectorImpl injector, T instance, Key<T>
key,
+ ProvisionListenerStackCallback<T> provisionCallback, Object
source) {
this.injector = injector;
this.key = key; // possibly null!
+ this.provisionCallback = provisionCallback; // possibly null!
this.instance = checkNotNull(instance, "instance");
this.source = checkNotNull(source, "source");
}
@@ -163,7 +171,11 @@
// if in Stage.TOOL, we only want to inject & notify toolable
injection points.
// (otherwise we'll inject all of them)
- membersInjector.injectAndNotify(instance,
errors.withSource(source), key, source,
+ membersInjector.injectAndNotify(instance,
+ errors.withSource(source),
+ key,
+ provisionCallback,
+ source,
injector.options.stage == Stage.TOOL);
}
=======================================
--- /core/src/com/google/inject/internal/InjectorShell.java Thu Jul 7
17:34:16 2011
+++ /core/src/com/google/inject/internal/InjectorShell.java Wed May 15
18:39:15 2013
@@ -129,9 +129,9 @@
checkState(privateElements == null || parent !=
null, "PrivateElements with no parent");
checkState(state != null, "no state. Did you remember to lock() ?");
- // bind Stage and Singleton if this is a top-level injector
+ // bind Singleton if this is a top-level injector
if (parent == null) {
- modules.add(0, new RootModule(stage));
+ modules.add(0, new RootModule());
}
elements.addAll(Elements.getElements(stage, modules));
@@ -174,6 +174,7 @@
new TypeConverterBindingProcessor(errors).process(injector,
elements);
stopwatch.resetAndLog("Converters creation");
+ bindStage(injector, stage);
bindInjector(injector);
bindLogger(injector);
@@ -270,16 +271,21 @@
}
}
- private static class RootModule implements Module {
- final Stage stage;
-
- private RootModule(Stage stage) {
- this.stage = checkNotNull(stage, "stage");
+ private static void bindStage(InjectorImpl injector, Stage stage) {
+ Key<Stage> key = Key.get(Stage.class);
+ InstanceBindingImpl<Stage> stageBinding = new
InstanceBindingImpl<Stage>(
+ injector,
+ key,
+ SourceProvider.UNKNOWN_SOURCE,
+ new ConstantFactory<Stage>(Initializables.of(stage)),
+ ImmutableSet.<InjectionPoint>of(),
+ stage);
+ injector.state.putBinding(key, stageBinding);
}
+ private static class RootModule implements Module {
public void configure(Binder binder) {
binder = binder.withSource(SourceProvider.UNKNOWN_SOURCE);
- binder.bind(Stage.class).toInstance(stage);
binder.bindScope(Singleton.class, SINGLETON);
binder.bindScope(javax.inject.Singleton.class, SINGLETON);
}
=======================================
--- /core/src/com/google/inject/internal/MembersInjectorImpl.java Thu Jul
7 17:34:16 2011
+++ /core/src/com/google/inject/internal/MembersInjectorImpl.java Wed May
15 18:39:15 2013
@@ -21,6 +21,7 @@
import com.google.inject.Key;
import com.google.inject.MembersInjector;
import com.google.inject.TypeLiteral;
+import
com.google.inject.internal.ProvisionListenerStackCallback.ProvisionCallback;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.InjectionPoint;
@@ -58,7 +59,7 @@
public void injectMembers(T instance) {
Errors errors = new Errors(typeLiteral);
try {
- injectAndNotify(instance, errors, null, typeLiteral, false);
+ injectAndNotify(instance, errors, null, null, typeLiteral, false);
} catch (ErrorsException e) {
errors.merge(e.getErrors());
}
@@ -66,18 +67,31 @@
errors.throwProvisionExceptionIfErrorsExist();
}
- void injectAndNotify(final T instance, final Errors errors,
- final Key<T> key, final Object source, final boolean toolableOnly)
- throws ErrorsException {
+ void injectAndNotify(final T instance,
+ final Errors errors,
+ final Key<T> key, // possibly null!
+ final ProvisionListenerStackCallback<T> provisionCallback, //
possibly null!
+ final Object source,
+ final boolean toolableOnly) throws ErrorsException {
if (instance == null) {
return;
}
injector.callInContext(new ContextualCallable<Void>() {
- public Void call(InternalContext context) throws ErrorsException {
+ @Override
+ public Void call(final InternalContext context) throws
ErrorsException {
context.pushState(key, source);
try {
+ if (provisionCallback != null &&
provisionCallback.hasListeners()) {
+ provisionCallback.provision(errors, context, new
ProvisionCallback<T>() {
+ @Override public T call() {
injectMembers(instance, errors, context, toolableOnly);
+ return instance;
+ }
+ });
+ } else {
+ injectMembers(instance, errors, context, toolableOnly);
+ }
} finally {
context.popState();
}
=======================================
---
/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
Sun Feb 26 18:23:19 2012
+++
/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
Wed May 15 18:39:15 2013
@@ -18,15 +18,20 @@
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.inject.Binding;
+import com.google.inject.Injector;
import com.google.inject.Key;
+import com.google.inject.Stage;
import com.google.inject.spi.ProvisionListener;
import com.google.inject.spi.ProvisionListenerBinding;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
/**
* {@link ProvisionListenerStackCallback} for each key.
@@ -34,6 +39,12 @@
* @author [email protected] (Sam Berlin)
*/
final class ProvisionListenerCallbackStore {
+
+ // TODO(sameb): Consider exposing this in the API somehow? Maybe?
+ // Lots of code often want to skip over the internal stuffs.
+ private static final Set<Key<?>> INTERNAL_BINDINGS =
+ ImmutableSet.of(Key.get(Injector.class), Key.get(Stage.class),
Key.get(Logger.class));
+
private final ImmutableList<ProvisionListenerBinding> listenerBindings;
private final Map<KeyBinding, ProvisionListenerStackCallback<?>> cache
@@ -52,7 +63,12 @@
*/
@SuppressWarnings("unchecked") // the ProvisionListenerStackCallback
type always agrees with the passed type
public <T> ProvisionListenerStackCallback<T> get(Binding<T> binding) {
- return (ProvisionListenerStackCallback<T>) cache.get(new
KeyBinding(binding.getKey(), binding));
+ // Never notify any listeners for internal bindings.
+ if (!INTERNAL_BINDINGS.contains(binding.getKey())) {
+ return (ProvisionListenerStackCallback<T>) cache.get(
+ new KeyBinding(binding.getKey(), binding));
+ }
+ return ProvisionListenerStackCallback.emptyListener();
}
/**
@@ -82,8 +98,10 @@
listeners.addAll(provisionBinding.getListeners());
}
}
- if (listeners == null) {
- listeners = ImmutableList.of();
+ if (listeners == null || listeners.isEmpty()) {
+ // Optimization: don't bother constructing the callback if there are
+ // no listeners.
+ return ProvisionListenerStackCallback.emptyListener();
}
return new ProvisionListenerStackCallback<T>(binding, listeners);
}
=======================================
---
/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
Sun Feb 26 18:23:19 2012
+++
/core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
Wed May 15 18:39:15 2013
@@ -16,6 +16,7 @@
package com.google.inject.internal;
+import com.google.common.collect.ImmutableList;
import com.google.inject.Binding;
import com.google.inject.ProvisionException;
import com.google.inject.spi.DependencyAndSource;
@@ -31,8 +32,17 @@
final class ProvisionListenerStackCallback<T> {
private static final ProvisionListener EMPTY_LISTENER[] = new
ProvisionListener[0];
+ @SuppressWarnings("rawtypes")
+ private static final ProvisionListenerStackCallback<?> EMPTY_CALLBACK =
+ new ProvisionListenerStackCallback(null /* unused, so ok */,
ImmutableList.of());
+
private final ProvisionListener[] listeners;
private final Binding<T> binding;
+
+ @SuppressWarnings("unchecked")
+ public static <T> ProvisionListenerStackCallback<T> emptyListener() {
+ return (ProvisionListenerStackCallback<T>) EMPTY_CALLBACK;
+ }
public ProvisionListenerStackCallback(Binding<T> binding,
List<ProvisionListener> listeners) {
this.binding = binding;
=======================================
--- /core/src/com/google/inject/spi/ProvisionListener.java Sun Feb 26
18:23:19 2012
+++ /core/src/com/google/inject/spi/ProvisionListener.java Wed May 15
18:39:15 2013
@@ -35,7 +35,9 @@
* Invoked by Guice when an object requires provisioning. Provisioning
occurs
* when Guice locates and injects the dependencies for a binding. For
types
* bound to a Provider, provisioning encapsulates the {@link
Provider#get}
- * method. For other types, provisioning encapsulates the construction
of the
+ * method. For toInstance or constant bindings, provisioning encapsulates
+ * the injecting of {@literal @}{@code Inject}ed fields or methods.
+ * For other types, provisioning encapsulates the construction of the
* object. If a type is bound within a {@link Scope}, provisioning
depends on
* the scope. Types bound in Singleton scope will only be provisioned
once.
* Types bound in no scope will be provisioned every time they are
injected.
=======================================
--- /core/test/com/google/inject/BinderTest.java Tue Sep 13 10:41:32 2011
+++ /core/test/com/google/inject/BinderTest.java Wed May 15 18:39:15 2013
@@ -456,6 +456,7 @@
bind(Module.class).annotatedWith(red).toProvider(Providers.<Module>of(null));
bind(Provider.class).annotatedWith(red).toProvider(Providers.<Provider>of(null));
bind(Scope.class).annotatedWith(red).toProvider(Providers.<Scope>of(null));
+
bind(Stage.class).annotatedWith(red).toProvider(Providers.<Stage>of(null));
bind(TypeLiteral.class).annotatedWith(red).toProvider(Providers.<TypeLiteral>of(null));
bind(new TypeLiteral<Key<String>>()
{}).toProvider(Providers.<Key<String>>of(null));
}
@@ -471,6 +472,7 @@
"Binding to core guice framework type is not allowed: Module.",
"Binding to Provider is not allowed.",
"Binding to core guice framework type is not allowed: Scope.",
+ "Binding to core guice framework type is not allowed: Stage.",
"Binding to core guice framework type is not allowed:
TypeLiteral.",
"Binding to core guice framework type is not allowed: Key.");
}
=======================================
--- /core/test/com/google/inject/BindingTest.java Thu Jul 7 17:34:16 2011
+++ /core/test/com/google/inject/BindingTest.java Wed May 15 18:39:15 2013
@@ -370,8 +370,7 @@
}
});
- assertEquals(ImmutableSet.of(TypeLiteral.get(Stage.class),
TypeLiteral.get(D.class)),
- heardTypes);
+ assertEquals(ImmutableSet.of(TypeLiteral.get(D.class)), heardTypes);
}
public void testInterfaceToImplementationConstructor() throws
NoSuchMethodException {
=======================================
--- /core/test/com/google/inject/ProvisionListenerTest.java Sun Feb 26
18:23:19 2012
+++ /core/test/com/google/inject/ProvisionListenerTest.java Wed May 15
18:39:15 2013
@@ -21,17 +21,21 @@
import static com.google.inject.name.Names.named;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;
import com.google.inject.matcher.Matchers;
import com.google.inject.name.Named;
import com.google.inject.spi.DependencyAndSource;
+import com.google.inject.spi.InstanceBinding;
import com.google.inject.spi.ProvisionListener;
+import com.google.inject.util.Providers;
import junit.framework.TestCase;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -244,6 +248,8 @@
throw new RuntimeException(ex);
}
bind(LinkedFoo.class).to(Foo.class);
+ bind(Interface.class).toInstance(new Implementation());
+ bindConstant().annotatedWith(named("constant")).to("MyConstant");
}
@Provides @Named("pi") Foo provideFooBar() {
@@ -251,6 +257,11 @@
}
});
+ // toInstance & constant bindings are notified in random order, at the
very beginning.
+ assertEquals(
+ ImmutableSet.of(Key.get(Interface.class), Key.get(String.class,
named("constant"))),
+ capturer.getAsSetAndClear());
+
// simple binding
assertNotNull(injector.getInstance(Foo.class));
assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
@@ -333,6 +344,9 @@
// We don't really care what kind of error you get, we only care you
get an error.
}
}
+
+ interface Interface {}
+ class Implementation implements Interface {}
@Singleton static class Sole {}
static class Many {}
@@ -370,8 +384,24 @@
public <T> void onProvision(ProvisionInvocation<T> provision) {
keys.add(provision.getBinding().getKey());
T provisioned = provision.provision();
+ // InstanceBindings are the only kind of binding where the key can
+ // be an instanceof the provisioned, because it isn't linked to any
+ // direct implementation. I guess maybe it'd also be possible
+ // with a toConstructor binding... but we don't use that in our
tests.
+ if (provision.getBinding() instanceof InstanceBinding) {
+ Class<? super T> expected =
provision.getBinding().getKey().getRawType();
+ assertTrue("expected instanceof: " + expected + ", but was: " +
provisioned,
+ expected.isInstance(provisioned));
+ } else {
assertEquals(provision.getBinding().getKey().getRawType(),
provisioned.getClass());
}
+ }
+
+ Set<Key> getAsSetAndClear() {
+ Set<Key> copy = ImmutableSet.copyOf(keys);
+ keys.clear();
+ return copy;
+ }
List<Key> getAndClear() {
List<Key> copy = ImmutableList.copyOf(keys);
@@ -454,8 +484,10 @@
// Build up a list of asserters for our dependency chains.
ImmutableList.Builder<Class<?>> chain = ImmutableList.builder();
+ chain.add(Instance.class);
+ bindListener(keyMatcher(Instance.class), new ChainAsserter(pList,
chain.build()));
- chain.add(Instance.class).add(A.class);
+ chain.add(A.class);
bindListener(keyMatcher(A.class), new ChainAsserter(pList,
chain.build()));
chain.add(B.class).add(BImpl.class);
@@ -482,7 +514,8 @@
});
Instance instance = injector.getInstance(Instance.class);
// make sure we're checking all of the chain asserters..
- assertEquals(of(A.class, BImpl.class, C.class, DP.class, D.class,
E.class, F.class),
+ assertEquals(
+ of(Instance.class, A.class, BImpl.class, C.class, DP.class,
D.class, E.class, F.class),
pList);
// and make sure that nothing else was notified that we didn't expect.
assertEquals(totalList, pList);
@@ -585,5 +618,22 @@
@SuppressWarnings("unused")
@Inject F f;
}
- private static class F {}
+ private static class F {
+ }
+
+ public void testBindToInjectorWithListeningGivesSaneException() {
+ try {
+ Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bindListener(Matchers.any(), new Counter());
+ bind(Injector.class).toProvider(Providers.<Injector>of(null));
+ }
+ });
+ fail();
+ } catch (CreationException ce) {
+ assertContains(
+ ce.getMessage(), "Binding to core guice framework type is not
allowed: Injector.");
+ }
+ }
}
=======================================
--- /core/test/com/google/inject/TypeListenerTest.java Thu Jul 7 17:34:16
2011
+++ /core/test/com/google/inject/TypeListenerTest.java Wed May 15 18:39:15
2013
@@ -596,7 +596,8 @@
try {
Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(Matchers.only(new TypeLiteral<Stage>() {}), new
TypeListener() {
+ requestInjection(new Object());
+ bindListener(Matchers.any(), new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
encounter.addError("There was an error on %s", type);
encounter.addError(new IllegalArgumentException("whoops!"));
@@ -609,7 +610,7 @@
fail();
} catch (CreationException expected) {
assertContains(expected.getMessage(),
- "1) There was an error on com.google.inject.Stage",
+ "1) There was an error on java.lang.Object",
"2) An exception was caught and reported. Message: whoops!",
"3) And another problem",
"4) An exception was caught and reported. Message: null",
=======================================
---
/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
Thu Jul 7 17:34:16 2011
+++
/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
Wed May 15 18:39:15 2013
@@ -500,7 +500,7 @@
return new MapResult<K, V>(k, new BindResult<V>(PROVIDER_INSTANCE, v,
null));
}
- private static class MapResult<K, V> {
+ static class MapResult<K, V> {
private final K k;
private final BindResult<V> v;
@@ -534,7 +534,7 @@
/** The kind of binding. */
static enum BindType { INSTANCE, LINKED, PROVIDER_INSTANCE }
/** The result of the binding. */
- private static class BindResult<T> {
+ static class BindResult<T> {
private final BindType type;
private final Key<? extends T> key;
private final T instance;
--
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.