Author: limpbizkit
Date: Wed Apr 8 16:48:49 2009
New Revision: 927
Added:
trunk/src/com/google/inject/TypeListenerBindingProcessor.java
- copied, changed from r915,
/trunk/src/com/google/inject/InjectableTypeListenerBindingProcessor.java
trunk/src/com/google/inject/spi/TypeListenerBinding.java
- copied, changed from r926,
/trunk/src/com/google/inject/spi/InjectableTypeListenerBinding.java
trunk/test/com/google/inject/TypeListenerTest.java
- copied, changed from r926,
/trunk/test/com/google/inject/InjectableTypeListenerTest.java
Removed:
trunk/src/com/google/inject/InjectableTypeListenerBindingProcessor.java
trunk/src/com/google/inject/spi/InjectableTypeListenerBinding.java
trunk/test/com/google/inject/InjectableTypeListenerTest.java
Modified:
trunk/guice.ipr
trunk/src/com/google/inject/AbstractProcessor.java
trunk/src/com/google/inject/EncounterImpl.java
trunk/src/com/google/inject/InheritingState.java
trunk/src/com/google/inject/InjectorShell.java
trunk/src/com/google/inject/MembersInjectorImpl.java
trunk/src/com/google/inject/MembersInjectorStore.java
trunk/src/com/google/inject/ProxyFactory.java
trunk/src/com/google/inject/State.java
trunk/src/com/google/inject/internal/Errors.java
trunk/src/com/google/inject/spi/DefaultElementVisitor.java
trunk/src/com/google/inject/spi/ElementVisitor.java
trunk/src/com/google/inject/spi/Elements.java
trunk/src/com/google/inject/spi/InterceptorBinding.java
trunk/src/com/google/inject/spi/ModuleWriter.java
trunk/src/com/google/inject/spi/TypeEncounter.java
trunk/src/com/google/inject/spi/TypeListener.java
trunk/test/com/google/inject/AllTests.java
trunk/test/com/google/inject/spi/ElementsTest.java
Log:
More listener changes:
- we now support user-supplied MembersInjectors. These execute before
InjectionListeners, enabling a two-phase injection
- renamed InjectableTypeListenerBinding to TypeListenerBinding
Modified: trunk/guice.ipr
==============================================================================
--- trunk/guice.ipr (original)
+++ trunk/guice.ipr Wed Apr 8 16:48:49 2009
@@ -574,10 +574,10 @@
<command
command-class="de.frag.umlplugin.uml.command.AddClassCommand"
psi-class="com.google.inject.spi.InjectableType" />
<command
command-class="de.frag.umlplugin.uml.command.AddClassCommand"
psi-class="com.google.inject.spi.Element" />
<command
command-class="de.frag.umlplugin.uml.command.AddClassCommand"
psi-class="com.google.inject.spi.BinderElement" />
- <command
command-class="de.frag.umlplugin.uml.command.AddClassCommand"
psi-class="com.google.inject.spi.InjectableTypeListenerBinding" />
+ <command
command-class="de.frag.umlplugin.uml.command.AddClassCommand"
psi-class="com.google.inject.spi.TypeListenerBinding" />
<command
command-class="de.frag.umlplugin.uml.command.ConnectClassesCommand" />
<command
command-class="de.frag.umlplugin.uml.command.AddClassCommand"
psi-class="com.google.inject.Binder" />
- <command
command-class="de.frag.umlplugin.uml.command.AddDependentClassesCommand"
psi-class="com.google.inject.spi.InjectableTypeListenerBinding" />
+ <command
command-class="de.frag.umlplugin.uml.command.AddDependentClassesCommand"
psi-class="com.google.inject.spi.TypeListenerBinding" />
<compartment-visibility />
</diagram>
</component>
Modified: trunk/src/com/google/inject/AbstractProcessor.java
==============================================================================
--- trunk/src/com/google/inject/AbstractProcessor.java (original)
+++ trunk/src/com/google/inject/AbstractProcessor.java Wed Apr 8 16:48:49
2009
@@ -20,14 +20,14 @@
import com.google.inject.spi.Element;
import com.google.inject.spi.ElementVisitor;
import com.google.inject.spi.InjectionRequest;
+import com.google.inject.spi.MembersInjectorLookup;
import com.google.inject.spi.Message;
import com.google.inject.spi.PrivateElements;
import com.google.inject.spi.ProviderLookup;
import com.google.inject.spi.ScopeBinding;
import com.google.inject.spi.StaticInjectionRequest;
import com.google.inject.spi.TypeConverterBinding;
-import com.google.inject.spi.MembersInjectorLookup;
-import com.google.inject.spi.InjectableTypeListenerBinding;
+import com.google.inject.spi.TypeListenerBinding;
import java.util.Iterator;
import java.util.List;
@@ -116,7 +116,7 @@
return false;
}
- public Boolean visit(InjectableTypeListenerBinding binding) {
+ public Boolean visit(TypeListenerBinding binding) {
return false;
}
}
Modified: trunk/src/com/google/inject/EncounterImpl.java
==============================================================================
--- trunk/src/com/google/inject/EncounterImpl.java (original)
+++ trunk/src/com/google/inject/EncounterImpl.java Wed Apr 8 16:48:49 2009
@@ -36,6 +36,7 @@
private final Errors errors;
private final Lookups lookups;
+ private List<MembersInjector<? super T>> membersInjectors; // lazy
private List<InjectionListener<? super T>> injectionListeners; // lazy
private List<MethodAspect> aspects; // lazy
private boolean valid = true;
@@ -55,13 +56,28 @@
: ImmutableList.copyOf(aspects);
}
+ public ImmutableList<MembersInjector<? super T>> getMembersInjectors() {
+ return membersInjectors == null
+ ? ImmutableList.<MembersInjector<? super T>>of()
+ : ImmutableList.copyOf(membersInjectors);
+ }
+
public ImmutableList<InjectionListener<? super T>>
getInjectionListeners() {
return injectionListeners == null
? ImmutableList.<InjectionListener<? super T>>of()
: ImmutableList.copyOf(injectionListeners);
}
- @SuppressWarnings("unchecked") // an InjectionListener<? super T> is an
InjectionListener<T>
+ public void register(MembersInjector<? super T> membersInjector) {
+ checkState(valid, "Encounters may not be used after hear() returns.");
+
+ if (membersInjectors == null) {
+ membersInjectors = Lists.newArrayList();
+ }
+
+ membersInjectors.add(membersInjector);
+ }
+
public void register(InjectionListener<? super T> injectionListener) {
checkState(valid, "Encounters may not be used after hear() returns.");
Modified: trunk/src/com/google/inject/InheritingState.java
==============================================================================
--- trunk/src/com/google/inject/InheritingState.java (original)
+++ trunk/src/com/google/inject/InheritingState.java Wed Apr 8 16:48:49
2009
@@ -22,7 +22,7 @@
import com.google.inject.internal.Maps;
import com.google.inject.internal.MatcherAndConverter;
import static com.google.inject.internal.Preconditions.checkNotNull;
-import com.google.inject.spi.InjectableTypeListenerBinding;
+import com.google.inject.spi.TypeListenerBinding;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
@@ -45,7 +45,7 @@
/*if[AOP]*/
private final List<MethodAspect> methodAspects = Lists.newArrayList();
/*end[AOP]*/
- private final List<InjectableTypeListenerBinding> listenerBindings =
Lists.newArrayList();
+ private final List<TypeListenerBinding> listenerBindings =
Lists.newArrayList();
private final WeakKeySet blacklistedKeys = new WeakKeySet();
private final Object lock;
@@ -118,14 +118,14 @@
}
/*end[AOP]*/
- public void addInjectableTypeListener(InjectableTypeListenerBinding
listenerBinding) {
+ public void addTypeListener(TypeListenerBinding listenerBinding) {
listenerBindings.add(listenerBinding);
}
- public List<InjectableTypeListenerBinding>
getInjectableTypeListenerBindings() {
- List<InjectableTypeListenerBinding> parentBindings =
parent.getInjectableTypeListenerBindings();
- List<InjectableTypeListenerBinding> result
- = new
ArrayList<InjectableTypeListenerBinding>(parentBindings.size() + 1);
+ public List<TypeListenerBinding> getTypeListenerBindings() {
+ List<TypeListenerBinding> parentBindings =
parent.getTypeListenerBindings();
+ List<TypeListenerBinding> result
+ = new ArrayList<TypeListenerBinding>(parentBindings.size() + 1);
result.addAll(parentBindings);
result.addAll(listenerBindings);
return result;
Modified: trunk/src/com/google/inject/InjectorShell.java
==============================================================================
--- trunk/src/com/google/inject/InjectorShell.java (original)
+++ trunk/src/com/google/inject/InjectorShell.java Wed Apr 8 16:48:49 2009
@@ -33,9 +33,9 @@
import com.google.inject.spi.Dependency;
import com.google.inject.spi.Element;
import com.google.inject.spi.Elements;
-import com.google.inject.spi.InjectableTypeListenerBinding;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.PrivateElements;
+import com.google.inject.spi.TypeListenerBinding;
import java.util.List;
import java.util.logging.Logger;
@@ -147,9 +147,8 @@
injector.constructionProxyFactory = new
DefaultConstructionProxyFactory();
end[NO_AOP]*/
- new InjectableTypeListenerBindingProcessor(errors).process(injector,
elements);
- List<InjectableTypeListenerBinding> listenerBindings
- = injector.state.getInjectableTypeListenerBindings();
+ new TypeListenerBindingProcessor(errors).process(injector, elements);
+ List<TypeListenerBinding> listenerBindings =
injector.state.getTypeListenerBindings();
injector.membersInjectorStore = new MembersInjectorStore(injector,
listenerBindings);
stopwatch.resetAndLog("TypeListeners creation");
Modified: trunk/src/com/google/inject/MembersInjectorImpl.java
==============================================================================
--- trunk/src/com/google/inject/MembersInjectorImpl.java (original)
+++ trunk/src/com/google/inject/MembersInjectorImpl.java Wed Apr 8
16:48:49 2009
@@ -33,16 +33,19 @@
private final TypeLiteral<T> typeLiteral;
private final InjectorImpl injector;
private final ImmutableList<SingleMemberInjector> memberInjectors;
+ private final ImmutableList<MembersInjector<? super T>>
userMembersInjectors;
private final ImmutableList<InjectionListener<? super T>>
injectionListeners;
private final ImmutableList<MethodAspect> addedAspects;
MembersInjectorImpl(InjectorImpl injector, TypeLiteral<T> typeLiteral,
ImmutableList<SingleMemberInjector> memberInjectors,
+ ImmutableList<MembersInjector<? super T>> userMembersInjectors,
ImmutableList<InjectionListener<? super T>> injectionListeners,
ImmutableList<MethodAspect> addedAspects) {
this.injector = injector;
this.typeLiteral = typeLiteral;
this.memberInjectors = memberInjectors;
+ this.userMembersInjectors = userMembersInjectors;
this.injectionListeners = injectionListeners;
this.addedAspects = addedAspects;
}
@@ -92,6 +95,14 @@
void injectMembers(T t, Errors errors, InternalContext context) {
for (SingleMemberInjector injector : memberInjectors) {
injector.inject(errors, context, t);
+ }
+
+ for (MembersInjector<? super T> userMembersInjector :
userMembersInjectors) {
+ try {
+ userMembersInjector.injectMembers(t);
+ } catch (RuntimeException e) {
+ errors.errorInUserInjector(userMembersInjector, typeLiteral, e);
+ }
}
}
Modified: trunk/src/com/google/inject/MembersInjectorStore.java
==============================================================================
--- trunk/src/com/google/inject/MembersInjectorStore.java (original)
+++ trunk/src/com/google/inject/MembersInjectorStore.java Wed Apr 8
16:48:49 2009
@@ -21,8 +21,8 @@
import com.google.inject.internal.FailableCache;
import com.google.inject.internal.ImmutableList;
import com.google.inject.internal.Lists;
-import com.google.inject.spi.InjectableTypeListenerBinding;
import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.TypeListenerBinding;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;
@@ -34,7 +34,7 @@
*/
class MembersInjectorStore {
private final InjectorImpl injector;
- private final ImmutableList<InjectableTypeListenerBinding>
injectableTypeListenerBindings;
+ private final ImmutableList<TypeListenerBinding> typeListenerBindings;
private final FailableCache<TypeLiteral<?>, MembersInjectorImpl<?>> cache
= new FailableCache<TypeLiteral<?>, MembersInjectorImpl<?>>() {
@@ -45,9 +45,9 @@
};
MembersInjectorStore(InjectorImpl injector,
- List<InjectableTypeListenerBinding> injectableTypeListenerBindings) {
+ List<TypeListenerBinding> typeListenerBindings) {
this.injector = injector;
- this.injectableTypeListenerBindings =
ImmutableList.copyOf(injectableTypeListenerBindings);
+ this.typeListenerBindings = ImmutableList.copyOf(typeListenerBindings);
}
/**
@@ -55,7 +55,7 @@
* aren't any type listeners.
*/
public boolean hasTypeListeners() {
- return !injectableTypeListenerBindings.isEmpty();
+ return !typeListenerBindings.isEmpty();
}
/**
@@ -84,7 +84,7 @@
errors.throwIfNewErrors(numErrorsBefore);
EncounterImpl<T> encounter = new EncounterImpl<T>(errors,
injector.lookups);
- for (InjectableTypeListenerBinding typeListener :
injectableTypeListenerBindings) {
+ for (TypeListenerBinding typeListener : typeListenerBindings) {
if (typeListener.getTypeMatcher().matches(type)) {
try {
typeListener.getListener().hear(type, encounter);
@@ -96,8 +96,8 @@
encounter.invalidate();
errors.throwIfNewErrors(numErrorsBefore);
- return new MembersInjectorImpl<T>(injector, type, injectors,
encounter.getInjectionListeners(),
- encounter.getAspects());
+ return new MembersInjectorImpl<T>(injector, type, injectors,
encounter.getMembersInjectors(),
+ encounter.getInjectionListeners(), encounter.getAspects());
}
/**
Modified: trunk/src/com/google/inject/ProxyFactory.java
==============================================================================
--- trunk/src/com/google/inject/ProxyFactory.java (original)
+++ trunk/src/com/google/inject/ProxyFactory.java Wed Apr 8 16:48:49 2009
@@ -141,8 +141,7 @@
}
/**
- * Returns the interceptors that apply to the constructed type. When
InjectableType.Listeners
- * add additional interceptors, this builder will be thrown out and
another created.n
+ * Returns the interceptors that apply to the constructed type.
*/
public ImmutableMap<Method, List<MethodInterceptor>> getInterceptors() {
return interceptors;
Modified: trunk/src/com/google/inject/State.java
==============================================================================
--- trunk/src/com/google/inject/State.java (original)
+++ trunk/src/com/google/inject/State.java Wed Apr 8 16:48:49 2009
@@ -21,7 +21,7 @@
import com.google.inject.internal.ImmutableList;
import com.google.inject.internal.ImmutableSet;
import com.google.inject.internal.MatcherAndConverter;
-import com.google.inject.spi.InjectableTypeListenerBinding;
+import com.google.inject.spi.TypeListenerBinding;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
@@ -82,12 +82,11 @@
}
/*end[AOP]*/
- public void addInjectableTypeListener(
- InjectableTypeListenerBinding injectableTypeListenerBinding) {
+ public void addTypeListener(TypeListenerBinding typeListenerBinding) {
throw new UnsupportedOperationException();
}
- public List<InjectableTypeListenerBinding>
getInjectableTypeListenerBindings() {
+ public List<TypeListenerBinding> getTypeListenerBindings() {
return ImmutableList.of();
}
@@ -133,9 +132,9 @@
List<MethodAspect> getMethodAspects();
/*end[AOP]*/
- void addInjectableTypeListener(InjectableTypeListenerBinding
injectableTypeListenerBinding);
+ void addTypeListener(TypeListenerBinding typeListenerBinding);
- List<InjectableTypeListenerBinding> getInjectableTypeListenerBindings();
+ List<TypeListenerBinding> getTypeListenerBindings();
/**
* Forbids the corresponding injector from creating a binding to {...@code
key}. Child injectors
Copied: trunk/src/com/google/inject/TypeListenerBindingProcessor.java (from
r915,
/trunk/src/com/google/inject/InjectableTypeListenerBindingProcessor.java)
==============================================================================
---
/trunk/src/com/google/inject/InjectableTypeListenerBindingProcessor.java
(original)
+++ trunk/src/com/google/inject/TypeListenerBindingProcessor.java Wed Apr
8 16:48:49 2009
@@ -17,21 +17,21 @@
package com.google.inject;
import com.google.inject.internal.Errors;
-import com.google.inject.spi.InjectableTypeListenerBinding;
+import com.google.inject.spi.TypeListenerBinding;
/**
* Handles {...@link Binder#bindListener} commands.
*
* @author [email protected] (Jesse Wilson)
*/
-class InjectableTypeListenerBindingProcessor extends AbstractProcessor {
+class TypeListenerBindingProcessor extends AbstractProcessor {
- InjectableTypeListenerBindingProcessor(Errors errors) {
+ TypeListenerBindingProcessor(Errors errors) {
super(errors);
}
- @Override public Boolean visit(InjectableTypeListenerBinding binding) {
- injector.state.addInjectableTypeListener(binding);
+ @Override public Boolean visit(TypeListenerBinding binding) {
+ injector.state.addTypeListener(binding);
return true;
}
}
Modified: trunk/src/com/google/inject/internal/Errors.java
==============================================================================
--- trunk/src/com/google/inject/internal/Errors.java (original)
+++ trunk/src/com/google/inject/internal/Errors.java Wed Apr 8 16:48:49
2009
@@ -19,15 +19,16 @@
import com.google.inject.ConfigurationException;
import com.google.inject.CreationException;
import com.google.inject.Key;
+import com.google.inject.MembersInjector;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.Scope;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.Dependency;
-import com.google.inject.spi.InjectableTypeListenerBinding;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.Message;
+import com.google.inject.spi.TypeListenerBinding;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
@@ -253,7 +254,7 @@
return errorInUserCode(cause, "Error injecting method, %s", cause);
}
- public Errors errorNotifyingTypeListener(InjectableTypeListenerBinding
listener,
+ public Errors errorNotifyingTypeListener(TypeListenerBinding listener,
TypeLiteral<?> type, Throwable cause) {
return errorInUserCode(cause,
"Error notifying TypeListener %s (bound at %s) of %s.%n"
@@ -269,10 +270,16 @@
return errorInUserCode(runtimeException, "Error in custom
provider, %s", runtimeException);
}
+ public Errors errorInUserInjector(
+ MembersInjector<?> listener, TypeLiteral<?> type, RuntimeException
cause) {
+ return errorInUserCode(cause, "Error injecting %s using %s.%n"
+ + " Reason: %s", type, listener, cause);
+ }
+
public Errors errorNotifyingInjectionListener(
- InjectionListener listener, TypeLiteral<?> typeLiteral,
RuntimeException cause) {
+ InjectionListener<?> listener, TypeLiteral<?> type, RuntimeException
cause) {
return errorInUserCode(cause, "Error notifying InjectionListener %s
of %s.%n"
- + " Reason: %s", listener, typeLiteral, cause);
+ + " Reason: %s", listener, type, cause);
}
public void exposedButNotBound(Key<?> key) {
Modified: trunk/src/com/google/inject/spi/DefaultElementVisitor.java
==============================================================================
--- trunk/src/com/google/inject/spi/DefaultElementVisitor.java (original)
+++ trunk/src/com/google/inject/spi/DefaultElementVisitor.java Wed Apr 8
16:48:49 2009
@@ -79,7 +79,7 @@
return visitOther(lookup);
}
- public V visit(InjectableTypeListenerBinding binding) {
+ public V visit(TypeListenerBinding binding) {
return visitOther(binding);
}
}
Modified: trunk/src/com/google/inject/spi/ElementVisitor.java
==============================================================================
--- trunk/src/com/google/inject/spi/ElementVisitor.java (original)
+++ trunk/src/com/google/inject/spi/ElementVisitor.java Wed Apr 8 16:48:49
2009
@@ -85,5 +85,5 @@
/**
* Visit an injectable type listener binding.
*/
- V visit(InjectableTypeListenerBinding binding);
+ V visit(TypeListenerBinding binding);
}
Modified: trunk/src/com/google/inject/spi/Elements.java
==============================================================================
--- trunk/src/com/google/inject/spi/Elements.java (original)
+++ trunk/src/com/google/inject/spi/Elements.java Wed Apr 8 16:48:49 2009
@@ -189,7 +189,7 @@
}
public void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher,
TypeListener listener) {
- elements.add(new InjectableTypeListenerBinding(getSource(),
listener, typeMatcher));
+ elements.add(new TypeListenerBinding(getSource(), listener,
typeMatcher));
}
public void requestStaticInjection(Class<?>... types) {
Modified: trunk/src/com/google/inject/spi/InterceptorBinding.java
==============================================================================
--- trunk/src/com/google/inject/spi/InterceptorBinding.java (original)
+++ trunk/src/com/google/inject/spi/InterceptorBinding.java Wed Apr 8
16:48:49 2009
@@ -34,7 +34,7 @@
* new MyTransactionInterceptor());</pre>
*
* or from an injectable type listener using {...@link
TypeEncounter#bindInterceptor(Matcher,
- * org.aopalliance.intercept.MethodInterceptor[])
InjectableType.Encounter.bindInterceptor()}.
+ * org.aopalliance.intercept.MethodInterceptor[])
TypeEncounter.bindInterceptor()}.
*
* @author [email protected] (Jesse Wilson)
* @since 2.0
Modified: trunk/src/com/google/inject/spi/ModuleWriter.java
==============================================================================
--- trunk/src/com/google/inject/spi/ModuleWriter.java (original)
+++ trunk/src/com/google/inject/spi/ModuleWriter.java Wed Apr 8 16:48:49
2009
@@ -109,7 +109,7 @@
return null;
}
- public Void visit(InjectableTypeListenerBinding element) {
+ public Void visit(TypeListenerBinding element) {
writeBindListener(binder, element);
return null;
}
@@ -138,7 +138,7 @@
}
/*end[AOP]*/
- protected void writeBindListener(Binder binder,
InjectableTypeListenerBinding element) {
+ protected void writeBindListener(Binder binder, TypeListenerBinding
element) {
binder.withSource(element.getSource())
.bindListener(element.getTypeMatcher(), element.getListener());
}
Modified: trunk/src/com/google/inject/spi/TypeEncounter.java
==============================================================================
--- trunk/src/com/google/inject/spi/TypeEncounter.java (original)
+++ trunk/src/com/google/inject/spi/TypeEncounter.java Wed Apr 8 16:48:49
2009
@@ -43,9 +43,8 @@
/**
* Records an exception for type {...@code I}, the full details of which
will be logged, and the
- * message of which will be presented to the user at a later time. If
your
- * InjectableTypeListener calls something that you worry may fail, you
should catch the
- * exception and pass it to this method.
+ * message of which will be presented to the user at a later time. If
your type listener calls
+ * something that you worry may fail, you should catch the exception and
pass it to this method.
*/
void addError(Throwable t);
@@ -89,11 +88,14 @@
<T> MembersInjector<T> getMembersInjector(Class<T> type);
/**
- * Registers an injection listener for type {...@code I}. Guice will notify
the listener after
- * injecting an instance of {...@code I}. The order in which Guice will
invoke listeners is
- * unspecified.
- *
- * @param listener for injections into instances of type {...@code I}
+ * Registers a members injector for type {...@code I}. Guice will use the
members injector after its
+ * performed its own injections on an instance of {...@code I}.
+ */
+ void register(MembersInjector<? super I> membersInjector);
+
+ /**
+ * Registers an injection listener for type {...@code I}. Guice will notify
the listener after all
+ * injections have been performed on an instance of {...@code I}.
*/
void register(InjectionListener<? super I> listener);
Modified: trunk/src/com/google/inject/spi/TypeListener.java
==============================================================================
--- trunk/src/com/google/inject/spi/TypeListener.java (original)
+++ trunk/src/com/google/inject/spi/TypeListener.java Wed Apr 8 16:48:49
2009
@@ -37,7 +37,7 @@
*
* @param type encountered by Guice
* @param encounter context of this encounter, enables reporting errors,
registering injection
- * listeners and binding method interceptors for injectableType
+ * listeners and binding method interceptors for {...@code type}.
*
* @param <I> the injectable type
*/
Copied: trunk/src/com/google/inject/spi/TypeListenerBinding.java (from
r926, /trunk/src/com/google/inject/spi/InjectableTypeListenerBinding.java)
==============================================================================
--- /trunk/src/com/google/inject/spi/InjectableTypeListenerBinding.java
(original)
+++ trunk/src/com/google/inject/spi/TypeListenerBinding.java Wed Apr 8
16:48:49 2009
@@ -21,23 +21,21 @@
import com.google.inject.matcher.Matcher;
/**
- * Binds injectable types (picked using a Matcher) to an injectable type
listener.
- * Registrations are created explicitly in a module using {...@link
- *
com.google.inject.Binder#bindListener(com.google.inject.matcher.Matcher,
TypeListener)}
- * statements:
+ * Binds types (picked using a Matcher) to an type listener. Registrations
are created explicitly in
+ * a module using {...@link com.google.inject.Binder#bindListener(Matcher,
TypeListener)} statements:
*
* <pre>
* register(only(new TypeLiteral<PaymentService<CreditCard>>()
{}), listener);</pre>
*
* @author [email protected] (Jesse Wilson)
*/
-public final class InjectableTypeListenerBinding implements Element {
+public final class TypeListenerBinding implements Element {
- final Object source;
- final Matcher<? super TypeLiteral<?>> typeMatcher;
- final TypeListener listener;
+ private final Object source;
+ private final Matcher<? super TypeLiteral<?>> typeMatcher;
+ private final TypeListener listener;
- InjectableTypeListenerBinding(Object source, TypeListener listener,
+ TypeListenerBinding(Object source, TypeListener listener,
Matcher<? super TypeLiteral<?>> typeMatcher) {
this.source = source;
this.listener = listener;
Modified: trunk/test/com/google/inject/AllTests.java
==============================================================================
--- trunk/test/com/google/inject/AllTests.java (original)
+++ trunk/test/com/google/inject/AllTests.java Wed Apr 8 16:48:49 2009
@@ -56,7 +56,7 @@
suite.addTestSuite(EagerSingletonTest.class);
suite.addTestSuite(GenericInjectionTest.class);
suite.addTestSuite(ImplicitBindingTest.class);
- suite.addTestSuite(InjectableTypeListenerTest.class);
+ suite.addTestSuite(TypeListenerTest.class);
suite.addTestSuite(InjectorTest.class);
// IntegrationTest is AOP-only
suite.addTestSuite(KeyTest.class);
Copied: trunk/test/com/google/inject/TypeListenerTest.java (from r926,
/trunk/test/com/google/inject/InjectableTypeListenerTest.java)
==============================================================================
--- /trunk/test/com/google/inject/InjectableTypeListenerTest.java
(original)
+++ trunk/test/com/google/inject/TypeListenerTest.java Wed Apr 8 16:48:49
2009
@@ -23,6 +23,7 @@
import com.google.inject.matcher.Matchers;
import static com.google.inject.matcher.Matchers.any;
import static com.google.inject.matcher.Matchers.only;
+import static com.google.inject.name.Names.named;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
@@ -36,11 +37,12 @@
/**
* @author [email protected] (Jesse Wilson)
*/
-public class InjectableTypeListenerTest extends TestCase {
+public class TypeListenerTest extends TestCase {
- private final Matcher<Object> onlyAbc = Matchers.only(new
TypeLiteral<A>() {})
+ private final Matcher<Object> onlyAbcd = Matchers.only(new
TypeLiteral<A>() {})
.or(only(new TypeLiteral<B>() {}))
- .or(only(new TypeLiteral<C>() {}));
+ .or(only(new TypeLiteral<C>() {}))
+ .or(only(new TypeLiteral<D>() {}));
private static MethodInterceptor prefixInterceptor(final String prefix) {
return new MethodInterceptor() {
@@ -50,7 +52,7 @@
};
}
- final TypeListener failingInjectableTypeListener = new TypeListener() {
+ final TypeListener failingTypeListener = new TypeListener() {
int failures = 0;
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
@@ -74,6 +76,18 @@
}
};
+ final MembersInjector<Object> failingMembersInjector = new
MembersInjector<Object>() {
+ int failures = 0;
+
+ public void injectMembers(Object instance) {
+ throw new ClassCastException("whoops, failure #" + (++failures));
+ }
+
+ @Override public String toString() {
+ return "awkward";
+ }
+ };
+
public void testTypeListenersAreFired() throws NoSuchMethodException {
final AtomicInteger firedCount = new AtomicInteger();
@@ -86,7 +100,7 @@
Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, typeListener);
+ bindListener(onlyAbcd, typeListener);
bind(A.class);
}
});
@@ -104,7 +118,7 @@
Injector injector = Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, new TypeListener() {
+ bindListener(onlyAbcd, new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
encounter.register(injectionListener);
}
@@ -139,7 +153,7 @@
bindInterceptor(any(), buzz, prefixInterceptor("ka"));
bindInterceptor(any(), any(), prefixInterceptor("fe"));
- bindListener(onlyAbc, new TypeListener() {
+ bindListener(onlyAbcd, new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
encounter.bindInterceptor(any(), prefixInterceptor("li"));
encounter.bindInterceptor(buzz, prefixInterceptor("no"));
@@ -154,11 +168,11 @@
assertEquals("felibeep", c.beep());
}
- public void testInjectableTypeListenerThrows() {
+ public void testTypeListenerThrows() {
try {
Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, failingInjectableTypeListener);
+ bindListener(onlyAbcd, failingTypeListener);
bind(B.class);
bind(C.class);
}
@@ -167,18 +181,18 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at " +
getClass().getName(),
- ".configure(InjectableTypeListenerTest.java:",
+ ".configure(TypeListenerTest.java:",
"of " + B.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #1",
"2) Error notifying TypeListener clumsy (bound at " +
getClass().getName(),
- ".configure(InjectableTypeListenerTest.java:",
+ ".configure(TypeListenerTest.java:",
"of " + C.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #2");
}
Injector injector = Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, failingInjectableTypeListener);
+ bindListener(onlyAbcd, failingTypeListener);
}
});
try {
@@ -187,7 +201,7 @@
} catch (ConfigurationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at " +
getClass().getName(),
- ".configure(InjectableTypeListenerTest.java:",
+ ".configure(TypeListenerTest.java:",
"of " + B.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #3");
}
@@ -199,19 +213,19 @@
} catch (ConfigurationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at " +
getClass().getName(),
- ".configure(InjectableTypeListenerTest.java:",
+ ".configure(TypeListenerTest.java:",
"of " + B.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #3");
}
- // non-constructed types do not participate
+ // non-injected types do not participate
assertSame(Stage.DEVELOPMENT, injector.getInstance(Stage.class));
}
public void testInjectionListenerThrows() {
Injector injector = Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, new TypeListener() {
+ bindListener(onlyAbcd, new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
encounter.register(failingInjectionListener);
}
@@ -250,23 +264,23 @@
" Reason: java.lang.ClassCastException: whoops, failure #3");
}
- // non-constructed types do not participate
+ // non-injected types do not participate
assertSame(Stage.DEVELOPMENT, injector.getInstance(Stage.class));
}
- public void testInjectMembersInjectableTypeListenerFails() {
+ public void testInjectMembersTypeListenerFails() {
try {
Guice.createInjector(new AbstractModule() {
protected void configure() {
getMembersInjector(A.class);
- bindListener(onlyAbc, failingInjectableTypeListener);
+ bindListener(onlyAbcd, failingTypeListener);
}
});
fail();
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at ",
-
InjectableTypeListenerTest.class.getName(),
".configure(InjectableTypeListenerTest.java:",
+
TypeListenerTest.class.getName(), ".configure(TypeListenerTest.java:",
"of " + A.class.getName(),
" Reason: java.lang.ClassCastException: whoops, failure #1");
}
@@ -285,7 +299,7 @@
Injector injector = Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, new TypeListener() {
+ bindListener(onlyAbcd, new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
typeEncounters.incrementAndGet();
encounter.register((InjectionListener) listener);
@@ -397,6 +411,102 @@
injector.getInstance(C.class);
}
+ public void testMembersInjector() {
+ final MembersInjector<D> membersInjector = new MembersInjector<D>() {
+ public void injectMembers(D instance) {
+ instance.userInjected++;
+ assertEquals(instance.guiceInjected, instance.userInjected);
+ }
+ };
+
+ final InjectionListener<D> injectionListener = new
InjectionListener<D>() {
+ public void afterInjection(D injectee) {
+ assertTrue(injectee.userInjected > 0);
+ injectee.listenersNotified++;
+ assertEquals(injectee.guiceInjected, injectee.listenersNotified);
+ }
+ };
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bindListener(onlyAbcd, new TypeListener() {
+ public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
+ encounter.register((MembersInjector) membersInjector);
+ encounter.register((InjectionListener) injectionListener);
+ }
+ });
+
+ D boundThreeTimes = new D();
+
bind(D.class).annotatedWith(named("i")).toInstance(boundThreeTimes);
+
bind(D.class).annotatedWith(named("ii")).toInstance(boundThreeTimes);
+
bind(D.class).annotatedWith(named("iii")).toInstance(boundThreeTimes);
+ }
+ });
+
+ D boundThreeTimes = injector.getInstance(Key.get(D.class,
named("iii")));
+ boundThreeTimes.assertAllCounts(1);
+
+ D getInstance = injector.getInstance(D.class);
+ getInstance.assertAllCounts(1);
+
+ D memberInjection = new D();
+ injector.injectMembers(memberInjection);
+ memberInjection.assertAllCounts(1);
+
+ injector.injectMembers(memberInjection);
+ injector.injectMembers(memberInjection);
+ memberInjection.assertAllCounts(3);
+
+ injector.getMembersInjector(D.class).injectMembers(memberInjection);
+ memberInjection.assertAllCounts(4);
+ }
+
+ public void testMembersInjectorThrows() {
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bindListener(onlyAbcd, new TypeListener() {
+ public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
+ encounter.register(failingMembersInjector);
+ }
+ });
+ bind(B.class);
+ }
+ });
+
+ try {
+ injector.getInstance(A.class);
+ fail();
+ } catch (ProvisionException e) {
+ assertContains(e.getMessage(),
+ "1) Error injecting " + A.class.getName() + " using awkward.",
+ "Reason: java.lang.ClassCastException: whoops, failure #1");
+ }
+
+ // second time through should be a new cause (#2)
+ try {
+ injector.getInstance(A.class);
+ fail();
+ } catch (ProvisionException e) {
+ assertContains(e.getMessage(),
+ "1) Error injecting " + A.class.getName() + " using awkward.",
+ "Reason: java.lang.ClassCastException: whoops, failure #2");
+ }
+
+ // we should get errors for all types, but only on getInstance()
+ Provider<B> bProvider = injector.getProvider(B.class);
+ try {
+ bProvider.get();
+ fail();
+ } catch (ProvisionException e) {
+ assertContains(e.getMessage(),
+ "1) Error injecting " + B.class.getName() + " using awkward.",
+ "Reason: java.lang.ClassCastException: whoops, failure #3");
+ }
+
+ // non-injected types do not participate
+ assertSame(Stage.DEVELOPMENT, injector.getInstance(Stage.class));
+ }
+
/**
* We had a bug where we weren't notifying of types encountered for
member injection when those
* types had no members to be injected. Constructed types are always
injected because they always
@@ -407,7 +517,7 @@
Guice.createInjector(new AbstractModule() {
protected void configure() {
- bindListener(onlyAbc, new TypeListener() {
+ bindListener(onlyAbcd, new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter) {
notificationCount.incrementAndGet();
}
@@ -489,6 +599,22 @@
public String beep() {
return "beep";
+ }
+ }
+
+ static class D {
+ int guiceInjected = 0;
+ int userInjected = 0;
+ int listenersNotified = 0;
+
+ @Inject void guiceInjected() {
+ guiceInjected++;
+ }
+
+ void assertAllCounts(int expected) {
+ assertEquals(expected, guiceInjected);
+ assertEquals(expected, userInjected);
+ assertEquals(expected, listenersNotified);
}
}
}
Modified: trunk/test/com/google/inject/spi/ElementsTest.java
==============================================================================
--- trunk/test/com/google/inject/spi/ElementsTest.java (original)
+++ trunk/test/com/google/inject/spi/ElementsTest.java Wed Apr 8 16:48:49
2009
@@ -606,7 +606,7 @@
},
new FailingElementVisitor() {
- @Override public Void visit(InjectableTypeListenerBinding
binding) {
+ @Override public Void visit(TypeListenerBinding binding) {
assertSame(typeMatcher, binding.getTypeMatcher());
assertSame(listener, binding.getListener());
return null;
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---