Author: limpbizkit
Date: Mon Dec 8 22:26:00 2008
New Revision: 723
Added:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
- copied, changed from r714,
/trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Factories.java
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
- copied, changed from r714,
/trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoriesTest.java
Removed:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Factories.java
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoriesTest.java
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
trunk/src/com/google/inject/spi/InjectionPoint.java
Log:
Big API change to AssistedInject Deluxe.
I unified the API - both old and new use the same API, and the code detects
which to use (by looking for the presence or absence of an @AssistedInject
annotation)
This means that:
- Upgrading from new to old is extremely easy
- Unified Javadocs for old and new. The new Javadocs just have a section
pointing out the differences when @AssistedInject is used instead of
@Assisted
- It's a little clumsier to make sure you're getting the right one. This
is mitigated by some new checks on the factory interface to ensure the old
constructor isn't used with the newer factories.
Also applying local variable naming fixes to InjectionPoint, as pointed out
by Brian Harris.
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
==============================================================================
---
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Assisted.java
Mon Dec 8 22:26:00 2008
@@ -32,5 +32,10 @@
*/
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface Assisted {
+
+ /**
+ * The unique name for this parameter. This is matched to the [EMAIL
PROTECTED]
@Assisted} constructor
+ * parameter with the same value.
+ */
String value() default "";
}
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
==============================================================================
---
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedInject.java
Mon Dec 8 22:26:00 2008
@@ -22,16 +22,22 @@
import java.lang.annotation.Target;
/**
- * Constructors annotated with <code>@AssistedInject</code> indicate that
will
- * can be instantiated by the [EMAIL PROTECTED] FactoryProvider}. Each
constructor
must
- * exactly one corresponding factory method within the Factory Interface.
+ * <p>Constructors annotated with [EMAIL PROTECTED] @AssistedInject} indicate
that
will can be instantiated by
+ * the [EMAIL PROTECTED] FactoryProvider}. Each constructor must exactly one
corresponding factory method
+ * within the factory interface.
*
- * <p>Constructor parameters must be either supplied by the Factory
Interface and
- * marked with <code>@Assisted</code>, or they must be injectable.
+ * <p>Constructor parameters must be either supplied by the factory
interface and marked with
+ * <code>@Assisted</code>, or they must be injectable.
*
+ * @deprecated [EMAIL PROTECTED] FactoryProvider} now works better with the
standard
[EMAIL PROTECTED] @Inject}
+ * annotation. When using that annotation, parameters are matched by
name and type rather than
+ * by position. In addition, values that use the standard [EMAIL
PROTECTED]
@Inject} constructor
+ * annotation are eligible for method interception.
+ *
* @author [EMAIL PROTECTED] (Jerome Mourits)
* @author [EMAIL PROTECTED] (Jesse Wilson)
*/
@Target({CONSTRUCTOR})
@Retention(RUNTIME)
[EMAIL PROTECTED]
public @interface AssistedInject {}
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
==============================================================================
---
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
Mon Dec 8 22:26:00 2008
@@ -16,15 +16,18 @@
package com.google.inject.assistedinject;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.ConfigurationException;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.internal.Errors;
import com.google.inject.spi.Message;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -33,77 +36,130 @@
import java.util.Map;
/**
- * Provides a mechanism to combine user-specified paramters with
- * [EMAIL PROTECTED] Injector}-specified paramters when creating new objects.
+ * Provides a factory that combines caller-provided parameters with
injector-provided values when
+ * constructing objects.
*
- * <p>To use a [EMAIL PROTECTED] FactoryProvider}:
+ * <h3>Defining a factory</h3>
+ * Create an interface whose methods return the constructed type, or its
supertypes. The method's
+ * parameters are the arguments required to build the constructed type.
+ * <pre>public interface PaymentFactory {
+ * Payment create(Date startDate, Money amount);
+ * }</pre>
+ * You can name your factory methods whatever you like, such as
<i>create</i>, <i>createPayment</i>
+ * or <i>newPayment</i>.
*
- * <p>Annotate your implementation class' constructor with the
- * [EMAIL PROTECTED] @[EMAIL PROTECTED] AssistedInject} and the user-specified
parameters
with
- * [EMAIL PROTECTED] @[EMAIL PROTECTED] Assisted}:
- * <pre><code>public class RealPayment implements Payment {
- * [EMAIL PROTECTED] @}AssistedInject
- * public RealPayment(CreditService creditService, AuthService
authService,
- * [EMAIL PROTECTED] @}Assisted Date startDate, [EMAIL PROTECTED]
@}Assisted Money
amount) {
+ * <h3>Creating a type that accepts factory parameters</h3>
+ * [EMAIL PROTECTED] constructedType} is a concrete class with an [EMAIL
PROTECTED] @[EMAIL PROTECTED]
Inject}-annotated
+ * constructor. In addition to injector-provided parameters, the
constructor should have
+ * parameters that match each of the factory method's parameters. Each
factory-provided parameter
+ * requires an [EMAIL PROTECTED] @[EMAIL PROTECTED] Assisted} annotation. This
serves to
document that the parameter
+ * is not bound by your application's modules.
+ * <pre>public class RealPayment implements Payment {
+ * [EMAIL PROTECTED] @}Inject
+ * public RealPayment(
+ * CreditService creditService,
+ * AuthService authService,
+ * <strong>[EMAIL PROTECTED] @}Assisted Date startDate</strong>,
+ * <strong>[EMAIL PROTECTED] @}Assisted Money amount</strong>) {
* ...
- * }
- * }</code></pre>
+ * }
+ * }</pre>
*
- * <p>Write an interface with a <i>create</i> method that accepts the
user-specified
- * parameters in the same order as they appear in the implementation
class' constructor:
- * <pre><code>public interface PaymentFactory {
- * Payment create(Date startDate, Money amount);
- * }</code></pre>
- *
- * <p>You can name your create methods whatever you like, such as
<i>create</i>,
- * or <i>createPayment</i> or <i>newPayment</i>. The concrete class must
- * be assignable to the return type of your create method. You can also
provide
- * multiple factory methods, but there must be exactly one
- * [EMAIL PROTECTED] @[EMAIL PROTECTED] AssistedInject} constructor on the
implementation
class for each.
- *
- * <p>In your Guice [EMAIL PROTECTED] com.google.inject.Module module}, bind
your
factory
- * interface to an instance of [EMAIL PROTECTED] FactoryProvider} that was
created
with
- * the same factory interface and implementation type:
- * <pre><code> bind(PaymentFactory.class).toProvider(
- * FactoryProvider.newFactory(PaymentFactory.class,
RealPayment.class));</code></pre>
- *
- * <p>Now you can [EMAIL PROTECTED] @[EMAIL PROTECTED] Inject} your factory
interface into
your
- * Guice-injected classes. When you invoke the create method on that
factory,
- * the [EMAIL PROTECTED] FactoryProvider} will instantiate the implementation
class
using
- * parameters from the injector and the factory method.
- *
- * <pre><code>public class PaymentAction {
- * [EMAIL PROTECTED] @}Inject private PaymentFactory paymentFactory;
- *
- * public void doPayment(Money amount) {
- * Payment payment = paymentFactory.create(new Date(), amount);
- * payment.apply();
- * }
- * }</code></pre>
+ * <h3>Configuring factories</h3>
+ * In your [EMAIL PROTECTED] com.google.inject.Module module}, bind the
factory
interface to the returned
+ * factory:
+ * <pre>bind(PaymentFactory.class).toInstance(
+ * FactoryProvider.newFactory(PaymentFactory.class,
RealPayment.class));</pre>
+ * As a side-effect of this binding, Guice will inject the factory to
initialize it for use. The
+ * factory cannot be used until the injector has been initialized.
+ *
+ * <h3>Using the factory</h3>
+ * Inject your factory into your application classes. When you use the
factory, your arguments
+ * will be combined with values from the injector to produce a concrete
instance.
+ * <pre>public class PaymentAction {
+ * [EMAIL PROTECTED] @}Inject private PaymentFactory paymentFactory;
+ *
+ * public void doPayment(Money amount) {
+ * Payment payment = paymentFactory.create(new Date(), amount);
+ * payment.apply();
+ * }
+ * }</pre>
+ *
+ * <h3>Making parameter types distinct</h3>
+ * The types of the factory method's parameters must be distinct. To use
multiple parameters of
+ * the same type, use a named [EMAIL PROTECTED] @[EMAIL PROTECTED] Assisted}
annotation to
disambiguate the
+ * parameters. The names must be applied to the factory method's
parameters:
+ *
+ * <pre>public interface PaymentFactory {
+ * Payment create(
+ * <strong>[EMAIL PROTECTED] @}Assisted("startDate")</strong> Date
startDate,
+ * <strong>[EMAIL PROTECTED] @}Assisted("dueDate")</strong> Date dueDate,
+ * Money amount);
+ * } </pre>
+ * ...and to the concrete type's constructor parameters:
+ * <pre>public class RealPayment implements Payment {
+ * [EMAIL PROTECTED] @}Inject
+ * public RealPayment(
+ * CreditService creditService,
+ * AuthService authService,
+ * <strong>[EMAIL PROTECTED] @}Assisted("startDate")</strong> Date
startDate,
+ * <strong>[EMAIL PROTECTED] @}Assisted("dueDate")</strong> Date dueDate,
+ * <strong>[EMAIL PROTECTED] @}Assisted</strong> Money amount) {
+ * ...
+ * }
+ * }</pre>
+ *
+ * <h3>Values are created by Guice</h3>
+ * Returned factories use child injectors to create values. The values are
eligible for method
+ * interception. In addition, [EMAIL PROTECTED] @[EMAIL PROTECTED] Inject}
members will
be injected before they are
+ * returned.
+ *
+ * <h3>Backwards compatibility using [EMAIL PROTECTED] @}AssistedInject</h3>
+ * Instead of the [EMAIL PROTECTED] @}Inject annotation, you may annotate the
constructed classes with
+ * [EMAIL PROTECTED] @[EMAIL PROTECTED] AssistedInject}. This triggers a
limited
backwards-compatability mode.
+ *
+ * <p>Instead of matching factory method arguments to constructor
parameters using their names, the
+ * <strong>parameters are matched by their order</strong>. The first
factory method argument is
+ * used for the first [EMAIL PROTECTED] @}Assisted constructor parameter,
etc..
Annotation names have no
+ * effect.
+ *
+ * <p>Returned values are <strong>not created by Guice</strong>. These
types are not eligible for
+ * method interception. They do receive post-construction member injection.
*
* @param <F> The factory interface
- * @param <R> The concrete class to be created.
*
* @author [EMAIL PROTECTED] (Jerome Mourits)
* @author [EMAIL PROTECTED] (Jesse Wilson)
+ * @author [EMAIL PROTECTED] (Daniel Martin)
*/
-public class FactoryProvider<F, R> implements Provider<F> {
+public class FactoryProvider<F> implements Provider<F> {
+
+ /*
+ * This class implements the old @AssistedInject implementation that
manually matches constructors
+ * to factory methods. The new child injector implementation lives in
FactoryProvider2.
+ */
private Injector injector;
private final Class<F> factoryType;
- private final Class<R> implementationType;
private final Map<Method, AssistedConstructor<?>>
factoryMethodToConstructor;
- public static <X,Y> FactoryProvider<X,Y> newFactory(
- Class<X> factoryType, Class<Y> implementationType){
- return new FactoryProvider<X, Y>(factoryType,implementationType);
+ public static <F> Provider<F> newFactory(
+ Class<F> factoryType, Class<?> implementationType){
+ Map<Method, AssistedConstructor<?>> factoryMethodToConstructor
+ = createMethodMapping(factoryType, implementationType);
+
+ if (!factoryMethodToConstructor.isEmpty()) {
+ return new FactoryProvider<F>(factoryType,
factoryMethodToConstructor);
+ } else {
+ return new FactoryProvider2<F>(factoryType,
Key.get(implementationType));
+ }
}
- private FactoryProvider(Class<F> factoryType, Class<R>
implementationType) {
+ private FactoryProvider(Class<F> factoryType,
+ Map<Method, AssistedConstructor<?>> factoryMethodToConstructor) {
this.factoryType = factoryType;
- this.implementationType = implementationType;
- this.factoryMethodToConstructor = createMethodMapping();
+ this.factoryMethodToConstructor = factoryMethodToConstructor;
checkDeclaredExceptionsMatch();
}
@@ -150,7 +206,8 @@
}
@SuppressWarnings({"unchecked"})
- private Map<Method, AssistedConstructor<?>> createMethodMapping() {
+ private static Map<Method, AssistedConstructor<?>> createMethodMapping(
+ Class<?> factoryType, Class<?> implementationType) {
List<AssistedConstructor<?>> constructors = Lists.newArrayList();
for (Constructor<?> c : implementationType.getDeclaredConstructors()) {
@@ -159,6 +216,10 @@
}
}
+ if (constructors.isEmpty()) {
+ return ImmutableMap.of();
+ }
+
if (constructors.size() != factoryType.getMethods().length) {
throw newConfigurationException("Constructor mismatch: %s has %s
@AssistedInject "
+ "constructors, factory %s has %s creation methods",
implementationType.getSimpleName(),
@@ -188,6 +249,19 @@
+ "@Assisted parameters %s in that order. @AssistInject
constructors are %s",
implementationType, methodParams,
paramsToConstructor.values());
}
+
+ method.getParameterAnnotations();
+ for (Annotation[] parameterAnnotations :
method.getParameterAnnotations()) {
+ for (Annotation parameterAnnotation : parameterAnnotations) {
+ if (parameterAnnotation.annotationType() == Assisted.class) {
+ throw newConfigurationException("Factory method %s has an
@Assisted parameter, which "
+ + "is incompatible with the deprecated @AssistedInject
annotation. Please replace "
+ + "@AssistedInject with @Inject on the %s constructor.",
+ method, implementationType);
+ }
+ }
+ }
+
AssistedConstructor matchingConstructor =
paramsToConstructor.remove(methodParams);
result.put(method, matchingConstructor);
@@ -204,8 +278,7 @@
}
AssistedConstructor<?> constructor =
factoryMethodToConstructor.get(method);
- Object[] constructorArgs = gatherArgsForConstructor(
- constructor, creationArgs);
+ Object[] constructorArgs = gatherArgsForConstructor(constructor,
creationArgs);
Object objectToReturn = constructor.newInstance(constructorArgs);
injector.injectMembers(objectToReturn);
return objectToReturn;
@@ -235,7 +308,7 @@
new Class[] {factoryType}, invocationHandler));
}
- private ConfigurationException newConfigurationException(String format,
Object... args) {
+ private static ConfigurationException newConfigurationException(String
format, Object... args) {
return new ConfigurationException(ImmutableSet.of(new
Message(Errors.format(format, args))));
}
}
Copied:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
(from r714,
/trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Factories.java)
==============================================================================
---
/trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Factories.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
Mon Dec 8 22:26:00 2008
@@ -38,25 +38,24 @@
import com.google.inject.spi.Message;
import com.google.inject.util.Providers;
import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.Arrays;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.InvocationHandler;
+
/**
- * Static utility methods for creating and working with factory interfaces.
+ * The newer implementation of factory provider. This implementation uses
a child injector to
+ * create values.
*
- * @author [EMAIL PROTECTED] (Jerome Mourits)
* @author [EMAIL PROTECTED] (Jesse Wilson)
* @author [EMAIL PROTECTED] (Daniel Martin)
*/
-public final class Factories {
- private Factories() {}
-
- private static final Class[] ONLY_RIH = { RealInvocationHandler.class };
+final class FactoryProvider2<F> implements InvocationHandler, Provider<F> {
- static final Assisted DEFAULT_ASSISTED = new Assisted() {
+ /** if a factory method parameter isn't annotated, it gets this
annotation. */
+ static final Assisted DEFAULT_ANNOTATION = new Assisted() {
public String value() {
return "";
}
@@ -79,268 +78,158 @@
}
};
- /**
- * Returns a factory that combines caller-provided parameters with
injector-provided values when
- * constructing objects.
- *
- * <h3>Defining a Factory</h3>
- * [EMAIL PROTECTED] factoryInterface} is an interface whose methods return
the
constructed type, or its
- * supertypes. The method's parameters are the arguments required to
build the constructed type.
- *
- * <pre>
- * public interface PaymentFactory {
- * Payment create(Date startDate, Money amount);
- * } </pre>
- *
- * You can name your factory methods whatever you like, such as
<i>create</i>,
- * <i>createPayment</i> or <i>newPayment</i>. You may include multiple
factory methods in the
- * same interface but they must all construct the same type.
- *
- * <h3>Creating a type that accepts factory parameters</h3>
- * [EMAIL PROTECTED] constructedType} is a concrete class with an [EMAIL
PROTECTED]
@[EMAIL PROTECTED] Inject}-annotated
- * constructor. In addition to injector-provided parameters, the
constructor should have
- * parameters that match each of the factory method's parameters. Each
factory-provided parameter
- * requires an [EMAIL PROTECTED] @[EMAIL PROTECTED] Assisted} annotation.
This serves to
document that the parameter
- * is not bound in the injector.
- *
- * <pre>
- * public class RealPayment implements Payment {
- * [EMAIL PROTECTED] @}Inject
- * public RealPayment(
- * CreditService creditService,
- * AuthService authService,
- * <strong>[EMAIL PROTECTED] @}Assisted Date startDate</strong>,
- * <strong>[EMAIL PROTECTED] @}Assisted Money amount</strong>) {
- * ...
- * }
- * }</pre>
- *
- * <h3>Configuring factories</h3>
- * In your [EMAIL PROTECTED] com.google.inject.Module module}, bind the
factory
interface to the returned
- * factory:
- *
- * <pre>
- * bind(PaymentFactory.class).toInstance(
- * Factories.create(PaymentFactory.class, RealPayment.class));</pre>
- * As a side-effect of this binding, Guice will inject the factory to
initialize it for use. The
- * factory cannot be used until it has been initialized.
- *
- * <h3>Using the Factory</h3>
- * Inject your factory into your application classes. When you use the
factory, your arguments
- * will be combined with values from the injector to produce a concrete
instance.
- *
- * <pre>
- * public class PaymentAction {
- * [EMAIL PROTECTED] @}Inject private PaymentFactory paymentFactory;
- *
- * public void doPayment(Money amount) {
- * Payment payment = paymentFactory.create(new Date(), amount);
- * payment.apply();
- * }
- * }</pre>
- *
- * <h3>Making Parameter Types Distinct</h3>
- * The types of the factory method's parameters must be distinct. To use
multiple parameters of
- * the same type, use a named [EMAIL PROTECTED] @[EMAIL PROTECTED] Assisted}
annotation to
disambiguate the
- * parameters. The names must be applied to the factory method's
parameters:
- *
- * <pre>
- * public interface PaymentFactory {
- * Payment create(
- * <strong>[EMAIL PROTECTED] @}Assisted("startDate")</strong> Date
startDate,
- * <strong>[EMAIL PROTECTED] @}Assisted("dueDate")</strong> Date
dueDate,
- * Money amount);
- * } </pre>
- * ...and to the concrete type's constructor parameters:
- * <pre>
- * public class RealPayment implements Payment {
- * [EMAIL PROTECTED] @}Inject
- * public RealPayment(
- * CreditService creditService,
- * AuthService authService,
- * <strong>[EMAIL PROTECTED] @}Assisted("startDate")</strong> Date
startDate,
- * <strong>[EMAIL PROTECTED] @}Assisted("dueDate")</strong> Date
dueDate,
- * <strong>[EMAIL PROTECTED] @}Assisted</strong> Money amount) {
- * ...
- * }
- * }</pre>
- *
- * <h3>MethodInterceptor support</h3>
- * Returned factories delegate to the injector to construct returned
values. The values are
- * eligible for method interception.
- *
- * @param factoryInterface a Java interface that defines one or more
create methods.
- * @param constructedType a concrete type that is assignable to the
return types of all factory
- * methods.
- */
- public static <F> F create(Class<F> factoryInterface, Class<?>
constructedType) {
- RealInvocationHandler<F> invocationHandler
- = new RealInvocationHandler<F>(factoryInterface,
Key.get(constructedType));
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(Base.class);
- enhancer.setInterfaces(new Class[] { factoryInterface });
- enhancer.setCallback(invocationHandler);
- return factoryInterface.cast(enhancer.create(ONLY_RIH, new Object[] {
invocationHandler }));
- }
+ /** the produced type, or null if all methods return concrete types */
+ private final Key<?> producedType;
+ private final ImmutableMap<Method, Key<?>> returnTypesByMethod;
+ private final ImmutableMultimap<Method, Key<?>> paramTypes;
+
+ /** the hosting injector, or null if we haven't been initialized yet */
+ private Injector injector;
+
+ /** the factory interface, implemented and provided */
+ private final F factory;
/**
- * Generated factories extend this class, which gives us a hook to get
injected by Guice. Normal
- * Java proxies can't be injected, so we use cglib.
+ * @param factoryType a Java interface that defines one or more create
methods.
+ * @param producedType a concrete type that is assignable to the return
types of all factory
+ * methods.
*/
- private static class Base {
- private final RealInvocationHandler<?> invocationHandler;
+ FactoryProvider2(Class<F> factoryType, Key<?> producedType) {
+ this.producedType = producedType;
- protected Base(RealInvocationHandler<?> invocationHandler) {
- this.invocationHandler = invocationHandler;
+ Errors errors = new Errors();
+ try {
+ ImmutableMap.Builder<Method, Key<?>> returnTypesBuilder =
ImmutableMap.builder();
+ ImmutableMultimap.Builder<Method, Key<?>> paramTypesBuilder =
ImmutableMultimap.builder();
+ // TODO: also grab methods from superinterfaces
+ for (Method method : factoryType.getMethods()) {
+ Key<?> returnType =
getKey(TypeLiteral.get(method.getGenericReturnType()),
+ method, method.getAnnotations(), errors);
+ returnTypesBuilder.put(method, returnType);
+ Type[] params = method.getGenericParameterTypes();
+ Annotation[][] paramAnnotations = method.getParameterAnnotations();
+ int p = 0;
+ for (Type param : params) {
+ Key<?> paramKey = getKey(TypeLiteral.get(param), method,
paramAnnotations[p++], errors);
+ paramTypesBuilder.put(method, assistKey(method, paramKey,
errors));
+ }
+ }
+ returnTypesByMethod = returnTypesBuilder.build();
+ paramTypes = paramTypesBuilder.build();
+ } catch (ErrorsException e) {
+ throw new ConfigurationException(e.getErrors().getMessages());
}
- @SuppressWarnings("unused")
- @Inject private void initialize(Injector injector) {
- invocationHandler.initialize(injector);
- }
+ factory =
factoryType.cast(Proxy.newProxyInstance(factoryType.getClassLoader(),
+ new Class[] { factoryType }, this));
}
- // TODO: also grab methods from superinterfaces
+ public F get() {
+ return factory;
+ }
- private static class RealInvocationHandler<F> implements
InvocationHandler {
- /** the produced type, or null if all methods return concrete types */
- private final Key<?> producedType;
- private final ImmutableMap<Method, Key<?>> returnTypesByMethod;
- private final ImmutableMultimap<Method, Key<?>> paramTypes;
-
- /** the hosting injector, or null if we haven't been initialized yet */
- private Injector injector;
-
- private RealInvocationHandler(Class<F> factoryType, Key<?>
producedType) {
- this.producedType = producedType;
-
- Errors errors = new Errors();
- try {
- ImmutableMap.Builder<Method, Key<?>> returnTypesBuilder =
ImmutableMap.builder();
- ImmutableMultimap.Builder<Method, Key<?>> paramTypesBuilder =
ImmutableMultimap.builder();
- for (Method method : factoryType.getMethods()) {
- Key<?> returnType =
getKey(TypeLiteral.get(method.getGenericReturnType()),
- method, method.getAnnotations(), errors);
- returnTypesBuilder.put(method, returnType);
- Type[] params = method.getGenericParameterTypes();
- Annotation[][] paramAnnotations =
method.getParameterAnnotations();
- int p = 0;
- for (Type param : params) {
- Key<?> paramKey = getKey(TypeLiteral.get(param), method,
paramAnnotations[p++], errors);
- paramTypesBuilder.put(method, assistKey(method, paramKey,
errors));
- }
- }
- returnTypesByMethod = returnTypesBuilder.build();
- paramTypes = paramTypesBuilder.build();
- } catch (ErrorsException e) {
- throw new ConfigurationException(e.getErrors().getMessages());
- }
+ /**
+ * Returns a key similar to [EMAIL PROTECTED] key}, but with an [EMAIL
PROTECTED]
@}Assisted binding annotation.
+ * This fails if another binding annotation is clobbered in the process.
If the key already has
+ * the [EMAIL PROTECTED] @}Assisted annotation, it is returned as-is to
preserve
any String value.
+ */
+ private <T> Key<T> assistKey(Method method, Key<T> key, Errors errors)
throws ErrorsException {
+ if (key.getAnnotationType() == null) {
+ return Key.get(key.getTypeLiteral(), DEFAULT_ANNOTATION);
+ } else if (key.getAnnotationType() == Assisted.class) {
+ return key;
+ } else {
+ errors.withSource(method).addMessage(
+ "Only @Assisted is allowed for factory parameters, but found
@%s",
+ key.getAnnotationType());
+ throw errors.toException();
}
+ }
- /**
- * Returns a key similar to [EMAIL PROTECTED] key}, but with an [EMAIL
PROTECTED]
@}Assisted binding annotation.
- * This fails if another binding annotation is clobbered in the
process. If the key already has
- * the [EMAIL PROTECTED] @}Assisted annotation, it is returned as-is to
preserve any String value.
- */
- private <T> Key<T> assistKey(Method method, Key<T> key, Errors errors)
throws ErrorsException {
- if (key.getAnnotationType() == null) {
- return Key.get(key.getTypeLiteral(), DEFAULT_ASSISTED);
- } else if (key.getAnnotationType() == Assisted.class) {
- return key;
- } else {
- errors.withSource(method).addMessage(
- "Only @Assisted is allowed for factory parameters, but found
@%s",
- key.getAnnotationType());
- throw errors.toException();
- }
+ /**
+ * At injector-creation time, we initialize the invocation handler. At
this time we make sure
+ * all factory methods will be able to build the target types.
+ */
+ @Inject
+ void initialize(Injector injector) {
+ if (this.injector != null) {
+ throw new ConfigurationException(ImmutableList.of(new
Message(FactoryProvider2.class,
+ "Factories.create() factories may only be used in one
Injector!")));
}
- /**
- * At injector-creation time, we initialize the invocation handler. At
this time we make sure
- * all factory methods will be able to build the target types.
- */
- void initialize(Injector injector) {
- if (this.injector != null) {
- throw new ConfigurationException(ImmutableList.of(new
Message(Factories.class,
- "Factories.create() factories may only be used in one
Injector!")));
- }
+ this.injector = injector;
+
+ for (Method method : returnTypesByMethod.keySet()) {
+ Object[] args = new Object[method.getParameterTypes().length];
+ Arrays.fill(args, "dummy object for validating Factories");
+ getBindingFromNewInjector(method, args); // throws if the binding
isn't properly configured
+ }
+ }
- this.injector = injector;
+ /**
+ * Creates a child injector that binds the args, and returns the binding
for the method's result.
+ */
+ public Binding<?> getBindingFromNewInjector(final Method method, final
Object[] args) {
+ checkState(injector != null,
+ "Factories.create() factories cannot be used until they're
initialized by Guice.");
+
+ final Key<?> returnType = returnTypesByMethod.get(method);
+
+ Module assistedModule = new AbstractModule() {
+ @SuppressWarnings("unchecked") // raw keys are necessary for the
args array and return value
+ protected void configure() {
+ Binder binder = binder().withSource(method);
+
+ int p = 0;
+ for (Key<?> paramKey : paramTypes.get(method)) {
+ // Wrap in a Provider to cover null, and to prevent Guice from
injecting the parameter
+ binder.bind((Key) paramKey).toProvider(Providers.of(args[p++]));
+ }
- for (Method method : returnTypesByMethod.keySet()) {
- Object[] args = new Object[method.getParameterTypes().length];
- Arrays.fill(args, "dummy object for validating Factories");
- getBindingFromNewInjector(method, args); // throws if the binding
isn't properly configured
+ if (producedType != null && !returnType.equals(producedType)) {
+ binder.bind(returnType).to((Key) producedType);
+ } else {
+ binder.bind(returnType);
+ }
}
- }
+ };
- /**
- * Creates a child injector that binds the args, and returns the
binding for the method's
- * result.
- */
- public Binding<?> getBindingFromNewInjector(final Method method, final
Object[] args) {
- checkState(injector != null,
- "Factories.create() factories cannot be used until they're
initialized by Guice.");
-
- final Key<?> returnType = returnTypesByMethod.get(method);
-
- Module assistedModule = new AbstractModule() {
- @SuppressWarnings("unchecked") // raw keys are necessary for the
args array and return value
- protected void configure() {
- Binder binder = binder().withSource(method);
-
- int p = 0;
- for (Key<?> paramKey : paramTypes.get(method)) {
- // Wrap in a Provider to cover null, and to prevent Guice from
injecting the parameter
- binder.bind((Key)
paramKey).toProvider(Providers.of(args[p++]));
- }
-
- if (producedType != null && !returnType.equals(producedType)) {
- binder.bind(returnType).to((Key) producedType);
- } else {
- binder.bind(returnType);
- }
- }
- };
+ Injector forCreate = injector.createChildInjector(assistedModule);
+ return forCreate.getBinding(returnType);
+ }
- Injector forCreate = injector.createChildInjector(assistedModule);
- return forCreate.getBinding(returnType);
+ /**
+ * When a factory method is invoked, we create a child injector that
binds all parameters, then
+ * use that to get an instance of the return type.
+ */
+ public Object invoke(Object proxy, final Method method, final Object[]
args) throws Throwable {
+ if (method.getDeclaringClass() == Object.class) {
+ return method.invoke(this, args);
}
- /**
- * When a factory method is invoked, we create a child injector that
binds all parameters, then
- * use that to get an instance of the return type.
- */
- public Object invoke(Object proxy, final Method method, final Object[]
args) throws Throwable {
- if (method.getDeclaringClass() == Object.class) {
- return method.invoke(this, args);
- }
-
- Provider<?> provider = getBindingFromNewInjector(method,
args).getProvider();
- try {
- return provider.get();
- } catch (ProvisionException e) {
- // if this is an exception declared by the factory method, throw
it as-is
- if (e.getErrorMessages().size() == 1) {
- Message onlyError = getOnlyElement(e.getErrorMessages());
- Throwable cause = onlyError.getCause();
- if (cause != null && canRethrow(method, cause)) {
- throw cause;
- }
+ Provider<?> provider = getBindingFromNewInjector(method,
args).getProvider();
+ try {
+ return provider.get();
+ } catch (ProvisionException e) {
+ // if this is an exception declared by the factory method, throw it
as-is
+ if (e.getErrorMessages().size() == 1) {
+ Message onlyError = getOnlyElement(e.getErrorMessages());
+ Throwable cause = onlyError.getCause();
+ if (cause != null && canRethrow(method, cause)) {
+ throw cause;
}
- throw e;
}
+ throw e;
}
+ }
- @Override public String toString() {
- return "Factory";
- }
+ @Override public String toString() {
+ return factory.getClass().getInterfaces()[0].getName()
+ + " for " + producedType.getTypeLiteral();
+ }
- @Override public boolean equals(Object o) {
- // this equals() is wacky; we pretend it's defined on the Proxy
object rather than here
- return o instanceof Base
- && ((Base) o).invocationHandler == this;
- }
+ @Override public boolean equals(Object o) {
+ return o == this || o == factory;
}
/** Returns true if [EMAIL PROTECTED] thrown} can be thrown by [EMAIL
PROTECTED] invoked}
without wrapping. */
Copied:
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
(from r714,
/trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoriesTest.java)
==============================================================================
---
/trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoriesTest.java
(original)
+++
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
Mon Dec 8 22:26:00 2008
@@ -37,15 +37,15 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
-public class FactoriesTest extends TestCase {
+public class FactoryProvider2Test extends TestCase {
public void testAssistedFactory() {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(Double.class).toInstance(5.0d);
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Mustang.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Mustang.class));
}
});
ColoredCarFactory carFactory =
injector.getInstance(ColoredCarFactory.class);
@@ -65,8 +65,8 @@
protected void configure() {
bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Camaro.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Camaro.class));
}
});
@@ -99,9 +99,7 @@
this.color = color;
}
- public String drive() {
- return "vroom!";
- }
+ public void drive() {}
}
public static class Camaro implements Car {
@@ -124,13 +122,13 @@
Car create(Color color, boolean convertable);
}
- public void testFactoryWithMultipleMethods() {
+ public void testFactoryUsesInjectedConstructor() {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(float.class).toInstance(140f);
- bind(SummerCarFactory.class).toInstance(
- Factories.create(SummerCarFactory.class, Corvette.class));
+ bind(SummerCarFactory.class).toProvider(
+ FactoryProvider.newFactory(SummerCarFactory.class,
Corvette.class));
}
});
@@ -162,8 +160,8 @@
public void testConstructorDoesntNeedAllFactoryMethodArguments() {
Injector injector = Guice.createInjector(new AbstractModule() {
protected void configure() {
- bind(SummerCarFactory.class).toInstance(
- Factories.create(SummerCarFactory.class, Beetle.class));
+ bind(SummerCarFactory.class).toProvider(
+ FactoryProvider.newFactory(SummerCarFactory.class,
Beetle.class));
}
});
SummerCarFactory factory =
injector.getInstance(SummerCarFactory.class);
@@ -187,8 +185,8 @@
bind(String.class).toInstance("turbo");
bind(int.class).toInstance(911);
bind(double.class).toInstance(50000d);
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Porshe.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Porshe.class));
}
});
ColoredCarFactory carFactory =
injector.getInstance(ColoredCarFactory.class);
@@ -222,8 +220,8 @@
@Override
protected void configure() {
bind(String.class).toInstance("trans am");
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Firebird.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Firebird.class));
}
});
ColoredCarFactory carFactory =
injector.getInstance(ColoredCarFactory.class);
@@ -250,8 +248,8 @@
protected void configure() {
bind(new TypeLiteral<Set<String>>()
{}).toInstance(Collections.singleton("Flux Capacitor"));
bind(new TypeLiteral<Set<Integer>>()
{}).toInstance(Collections.singleton(88));
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, DeLorean.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
DeLorean.class));
}
});
ColoredCarFactory carFactory =
injector.getInstance(ColoredCarFactory.class);
@@ -281,8 +279,8 @@
@Override
protected void configure() {
bind(new TypeLiteral<Set<String>>() {
}).toInstance(Collections.singleton("Datsun"));
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Z.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
}
});
ColoredCarFactory carFactory =
injector.getInstance(ColoredCarFactory.class);
@@ -317,8 +315,8 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Prius.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Prius.class));
}
});
Car car =
injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
@@ -335,8 +333,8 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, ExplodingCar.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
ExplodingCar.class));
}
});
try {
@@ -373,8 +371,8 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(CorrectDefectiveCarFactory.class).toInstance(
- Factories.create(CorrectDefectiveCarFactory.class,
DefectiveCar.class));
+ bind(CorrectDefectiveCarFactory.class).toProvider(
+ FactoryProvider.newFactory(CorrectDefectiveCarFactory.class,
DefectiveCar.class));
}
});
try {
@@ -386,13 +384,6 @@
}
}
- public static class MultipleConstructorDefectiveCar implements Car {
- @Inject
- public MultipleConstructorDefectiveCar(@Assisted Color c) throws
FireException {
- throw new FireException();
- }
- }
-
public static class WildcardCollection {
public interface Factory {
@@ -407,8 +398,8 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(WildcardCollection.Factory.class).toInstance(
- Factories.create(WildcardCollection.Factory.class,
WildcardCollection.class));
+ bind(WildcardCollection.Factory.class).toProvider(
+ FactoryProvider.newFactory(WildcardCollection.Factory.class,
WildcardCollection.class));
}
});
WildcardCollection.Factory factory =
injector.getInstance(WildcardCollection.Factory.class);
@@ -434,8 +425,8 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Fiat.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Fiat.class));
}
});
@@ -449,15 +440,15 @@
try {
Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Mustang.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Mustang.class));
}
});
fail();
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"Could not find a suitable constructor in java.lang.Double.",
- "at " + ColoredCarFactory.class.getName()
+ ".create(FactoriesTest.java");
+ "at " + ColoredCarFactory.class.getName()
+ ".create(FactoryProvider2Test.java");
}
}
@@ -465,15 +456,16 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
bind(Double.class).toInstance(5.0d);
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Mustang.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Mustang.class));
}
});
ColoredCarFactory carFactory =
injector.getInstance(ColoredCarFactory.class);
assertEqualsBothWays(carFactory, carFactory);
- assertEquals("Factory", carFactory.toString());
+ assertEquals(ColoredCarFactory.class.getName() + " for " +
Mustang.class.getName(),
+ carFactory.toString());
}
static class Subaru implements Car {
@@ -483,8 +475,8 @@
public void testInjectingProviderOfParameter() {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Subaru.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Subaru.class));
}
});
@@ -498,8 +490,8 @@
public void testInjectingNullParameter() {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Subaru.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Subaru.class));
}
});
@@ -511,7 +503,8 @@
}
public void testFactoryUseBeforeInitialization() {
- ColoredCarFactory carFactory =
Factories.create(ColoredCarFactory.class, Subaru.class);
+ ColoredCarFactory carFactory =
FactoryProvider.newFactory(ColoredCarFactory.class, Subaru.class)
+ .get();
try {
carFactory.create(Color.RED);
fail();
@@ -530,8 +523,8 @@
protected void configure() {
bind(double.class).toInstance(5.0d);
// note there is no 'thatMakes()' call here:
- bind(MustangFactory.class).toInstance(
- Factories.create(MustangFactory.class, Mustang.class));
+ bind(MustangFactory.class).toProvider(
+ FactoryProvider.newFactory(MustangFactory.class,
Mustang.class));
}
});
MustangFactory factory = injector.getInstance(MustangFactory.class);
@@ -557,8 +550,8 @@
bind(double.class).toInstance(5.0d);
bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
- FleetFactory fleetFactory = Factories.create(FleetFactory.class,
Fleet.class);
- bind(FleetFactory.class).toInstance(fleetFactory);
+
bind(FleetFactory.class).toProvider(FactoryProvider.newFactory(FleetFactory.class,
+ Fleet.class));
}
});
@@ -585,8 +578,8 @@
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
- bind(TwoToneCarFactory.class).toInstance(
- Factories.create(TwoToneCarFactory.class, Maxima.class));
+ bind(TwoToneCarFactory.class).toProvider(
+ FactoryProvider.newFactory(TwoToneCarFactory.class,
Maxima.class));
}
});
@@ -596,6 +589,25 @@
assertSame(Color.GRAY, maxima.fabric);
}
+ interface DoubleToneCarFactory {
+ Car create(@Assisted("paint") Color paint, @Assisted("paint") Color
morePaint);
+ }
+
+ public void testDuplicateKeys() {
+ try {
+ Guice.createInjector(new AbstractModule() {
+ @Override protected void configure() {
+ bind(DoubleToneCarFactory.class).toProvider(
+ FactoryProvider.newFactory(DoubleToneCarFactory.class,
Maxima.class));
+ }
+ });
+ fail();
+ } catch (CreationException expected) {
+ assertContains(expected.getMessage(), "A binding to java.awt.Color
annotated with @"
+ + Assisted.class.getName() + "(value=paint) was already
configured at");
+ }
+ }
+
public void testMethodInterceptorsOnAssistedTypes() {
final AtomicInteger invocationCount = new AtomicInteger();
final MethodInterceptor interceptor = new MethodInterceptor() {
@@ -610,8 +622,8 @@
protected void configure() {
bindInterceptor(Matchers.any(), Matchers.any(), interceptor);
bind(Double.class).toInstance(5.0d);
- bind(ColoredCarFactory.class).toInstance(
- Factories.create(ColoredCarFactory.class, Mustang.class));
+ bind(ColoredCarFactory.class).toProvider(
+ FactoryProvider.newFactory(ColoredCarFactory.class,
Mustang.class));
}
});
@@ -623,7 +635,7 @@
}
public void testDefaultAssistedAnnotation() throws NoSuchFieldException {
- assertEqualsBothWays(Factories.DEFAULT_ASSISTED,
+ assertEqualsBothWays(FactoryProvider2.DEFAULT_ANNOTATION,
Subaru.class.getDeclaredField("colorProvider").getAnnotation(Assisted.class));
}
}
Modified:
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
==============================================================================
---
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
(original)
+++
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
Mon Dec 8 22:26:00 2008
@@ -536,5 +536,24 @@
carFactory.toString();
}
- // TODO(jessewilson): test for duplicate constructors
+ public void
testAssistedInjectConstructorAndAssistedFactoryParameterMustNotMix() {
+ try {
+ Guice.createInjector(new AbstractModule() {
+ @Override protected void configure() {
+ bind(Double.class).toInstance(5.0d);
+ bind(AssistedParamsFactory.class)
+
.toProvider(FactoryProvider.newFactory(AssistedParamsFactory.class,
Mustang.class));
+ }
+ });
+ fail();
+ } catch (CreationException expected) {
+ assertContains(expected.getMessage(), "Factory method "
+ + AssistedParamsFactory.class.getName() + ".create() has an
@Assisted parameter, which "
+ + "is incompatible with the deprecated @AssistedInject
annotation.");
+ }
+ }
+
+ interface AssistedParamsFactory {
+ Car create(@Assisted Color color);
+ }
}
Modified: trunk/src/com/google/inject/spi/InjectionPoint.java
==============================================================================
--- trunk/src/com/google/inject/spi/InjectionPoint.java (original)
+++ trunk/src/com/google/inject/spi/InjectionPoint.java Mon Dec 8 22:26:00
2008
@@ -356,9 +356,9 @@
}
private static <M extends Member & AnnotatedElement> void
addInjectorsForMembers(
- TypeLiteral<?> typeResolver, Factory<M> factory, boolean statics,
+ TypeLiteral<?> typeLiteral, Factory<M> factory, boolean statics,
Collection<InjectionPoint> injectionPoints, Errors errors) {
- for (M member :
factory.getMembers(getRawType(typeResolver.getType()))) {
+ for (M member : factory.getMembers(getRawType(typeLiteral.getType())))
{
if (isStatic(member) != statics) {
continue;
}
@@ -369,7 +369,7 @@
}
try {
- injectionPoints.add(factory.create(typeResolver, member, errors));
+ injectionPoints.add(factory.create(typeLiteral, member, errors));
} catch (ConfigurationException ignorable) {
if (!inject.optional()) {
errors.merge(ignorable.getErrorMessages());
@@ -387,8 +387,8 @@
public Field[] getMembers(Class<?> type) {
return type.getDeclaredFields();
}
- public InjectionPoint create(TypeLiteral<?> typeResolver, Field
member, Errors errors) {
- return new InjectionPoint(typeResolver, member);
+ public InjectionPoint create(TypeLiteral<?> typeLiteral, Field
member, Errors errors) {
+ return new InjectionPoint(typeLiteral, member);
}
};
@@ -396,14 +396,14 @@
public Method[] getMembers(Class<?> type) {
return type.getDeclaredMethods();
}
- public InjectionPoint create(TypeLiteral<?> typeResolver, Method
member, Errors errors) {
+ public InjectionPoint create(TypeLiteral<?> typeLiteral, Method
member, Errors errors) {
checkForMisplacedBindingAnnotations(member, errors);
- return new InjectionPoint(typeResolver, member);
+ return new InjectionPoint(typeLiteral, member);
}
};
M[] getMembers(Class<?> type);
- InjectionPoint create(TypeLiteral<?> typeResolver, M member, Errors
errors);
+ InjectionPoint create(TypeLiteral<?> typeLiteral, M member, Errors
errors);
}
private static final long serialVersionUID = 0;
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---