Author: limpbizkit
Date: Fri Feb 27 13:59:15 2009
New Revision: 871
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
Log:
Applying ilya.firman's patch for issue 218. I tweaked the patch to use
TypeLiteral's new type resolution methods like
TypeLiteral.getReturnType(Method) etc., which makes it so we always just
do-the-right-thing for matching type variables.
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
==============================================================================
---
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/AssistedConstructor.java
Fri Feb 27 13:59:15 2009
@@ -17,6 +17,8 @@
package com.google.inject.assistedinject;
import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Lists;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -41,18 +43,17 @@
private final List<Parameter> allParameters;
@SuppressWarnings("unchecked")
- public AssistedConstructor(Constructor<T> constructor) {
+ public AssistedConstructor(Constructor<T> constructor,
List<TypeLiteral<?>> parameterTypes) {
this.constructor = constructor;
- Type[] parameterTypes = constructor.getGenericParameterTypes();
Annotation[][] annotations = constructor.getParameterAnnotations();
- List<Type> typeList = new ArrayList<Type>();
+ List<Type> typeList = Lists.newArrayList();
allParameters = new ArrayList<Parameter>();
// categorize params as @Assisted or @Injected
- for (int i = 0; i < parameterTypes.length; i++) {
- Parameter parameter = new Parameter(parameterTypes[i],
annotations[i]);
+ for (int i = 0; i < parameterTypes.size(); i++) {
+ Parameter parameter = new Parameter(parameterTypes.get(i).getType(),
annotations[i]);
allParameters.add(parameter);
if (parameter.isProvidedByFactory()) {
typeList.add(parameter.getType());
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
Fri Feb 27 13:59:15 2009
@@ -21,6 +21,7 @@
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
import com.google.inject.internal.Errors;
import com.google.inject.internal.ImmutableMap;
import com.google.inject.internal.ImmutableSet;
@@ -34,6 +35,7 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -144,11 +146,16 @@
private Injector injector;
- private final Class<F> factoryType;
+ private final TypeLiteral<F> factoryType;
private final Map<Method, AssistedConstructor<?>>
factoryMethodToConstructor;
public static <F> Provider<F> newFactory(
Class<F> factoryType, Class<?> implementationType){
+ return newFactory(TypeLiteral.get(factoryType),
TypeLiteral.get(implementationType));
+ }
+
+ public static <F> Provider<F> newFactory(
+ TypeLiteral<F> factoryType, TypeLiteral<?> implementationType) {
Map<Method, AssistedConstructor<?>> factoryMethodToConstructor
= createMethodMapping(factoryType, implementationType);
@@ -159,7 +166,7 @@
}
}
- private FactoryProvider(Class<F> factoryType,
+ private FactoryProvider(TypeLiteral<F> factoryType,
Map<Method, AssistedConstructor<?>> factoryMethodToConstructor) {
this.factoryType = factoryType;
this.factoryMethodToConstructor = factoryMethodToConstructor;
@@ -208,14 +215,16 @@
return parameter.isBound(injector);
}
- @SuppressWarnings({"unchecked"})
private static Map<Method, AssistedConstructor<?>> createMethodMapping(
- Class<?> factoryType, Class<?> implementationType) {
+ TypeLiteral<?> factoryType, TypeLiteral<?> implementationType) {
List<AssistedConstructor<?>> constructors = Lists.newArrayList();
- for (Constructor<?> c : implementationType.getDeclaredConstructors()) {
- if (c.getAnnotation(AssistedInject.class) != null) {
- constructors.add(new AssistedConstructor(c));
+ for (Constructor<?> constructor :
implementationType.getRawType().getDeclaredConstructors()) {
+ if (constructor.getAnnotation(AssistedInject.class) != null) {
+ @SuppressWarnings("unchecked") // the constructor type and
implementation type agree
+ AssistedConstructor assistedConstructor = new AssistedConstructor(
+ constructor,
implementationType.getParameterTypes(constructor));
+ constructors.add(assistedConstructor);
}
}
@@ -223,10 +232,12 @@
return ImmutableMap.of();
}
- if (constructors.size() != factoryType.getMethods().length) {
+ Method[] factoryMethods = factoryType.getRawType().getMethods();
+
+ if (constructors.size() != factoryMethods.length) {
throw newConfigurationException("Constructor mismatch: %s has %s
@AssistedInject "
- + "constructors, factory %s has %s creation methods",
implementationType.getSimpleName(),
- constructors.size(), factoryType.getSimpleName(),
factoryType.getMethods().length);
+ + "constructors, factory %s has %s creation methods",
implementationType,
+ constructors.size(), factoryType, factoryMethods.length);
}
Map<ParameterListKey, AssistedConstructor> paramsToConstructor =
Maps.newHashMap();
@@ -239,13 +250,17 @@
}
Map<Method, AssistedConstructor<?>> result = Maps.newHashMap();
- for (Method method : factoryType.getMethods()) {
- if (!method.getReturnType().isAssignableFrom(implementationType)) {
- throw new RuntimeException(String.format("Return type of method
\"%s\""
- + " is not assignable from class \"%s\"", method,
- implementationType.getName()));
+ for (Method method : factoryMethods) {
+ if
(!method.getReturnType().isAssignableFrom(implementationType.getRawType()))
{
+ throw newConfigurationException("Return type of method %s is not
assignable from %s",
+ method, implementationType);
+ }
+
+ List<Type> parameterTypes = Lists.newArrayList();
+ for (TypeLiteral<?> parameterType :
factoryType.getParameterTypes(method)) {
+ parameterTypes.add(parameterType.getType());
}
- ParameterListKey methodParams = new
ParameterListKey(method.getGenericParameterTypes());
+ ParameterListKey methodParams = new ParameterListKey(parameterTypes);
if (!paramsToConstructor.containsKey(methodParams)) {
throw newConfigurationException("%s has no @AssistInject
constructor that takes the "
@@ -319,8 +334,10 @@
}
};
- return
factoryType.cast(Proxy.newProxyInstance(factoryType.getClassLoader(),
- new Class[] {factoryType}, invocationHandler));
+ @SuppressWarnings("unchecked") // we imprecisely treat the class
literal of T as a Class<T>
+ Class<F> factoryRawType = (Class) factoryType.getRawType();
+ return
factoryRawType.cast(Proxy.newProxyInstance(factoryRawType.getClassLoader(),
+ new Class[] { factoryRawType }, invocationHandler));
}
private static ConfigurationException newConfigurationException(String
format, Object... args) {
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
==============================================================================
---
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java
Fri Feb 27 13:59:15 2009
@@ -41,7 +41,6 @@
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 java.util.List;
@@ -94,25 +93,29 @@
* @param producedType a concrete type that is assignable to the return
types of all factory
* methods.
*/
- FactoryProvider2(Class<F> factoryType, Key<?> producedType) {
+ FactoryProvider2(TypeLiteral<F> factoryType, Key<?> producedType) {
this.producedType = producedType;
Errors errors = new Errors();
+
+ @SuppressWarnings("unchecked") // we imprecisely treat the class
literal of T as a Class<T>
+ Class<F> factoryRawType = (Class) factoryType.getRawType();
+
try {
ImmutableMap.Builder<Method, Key<?>> returnTypesBuilder =
ImmutableMap.builder();
ImmutableMap.Builder<Method, ImmutableList<Key<?>>> paramTypesBuilder
= ImmutableMap.builder();
// TODO: also grab methods from superinterfaces
- for (Method method : factoryType.getMethods()) {
- Key<?> returnType =
getKey(TypeLiteral.get(method.getGenericReturnType()),
- method, method.getAnnotations(), errors);
+ for (Method method : factoryRawType.getMethods()) {
+ Key<?> returnType = getKey(
+ factoryType.getReturnType(method), method,
method.getAnnotations(), errors);
returnTypesBuilder.put(method, returnType);
- Type[] params = method.getGenericParameterTypes();
+ List<TypeLiteral<?>> params =
factoryType.getParameterTypes(method);
Annotation[][] paramAnnotations = method.getParameterAnnotations();
int p = 0;
List<Key<?>> keys = Lists.newArrayList();
- for (Type param : params) {
- Key<?> paramKey = getKey(TypeLiteral.get(param), method,
paramAnnotations[p++], errors);
+ for (TypeLiteral<?> param : params) {
+ Key<?> paramKey = getKey(param, method, paramAnnotations[p++],
errors);
keys.add(assistKey(method, paramKey, errors));
}
paramTypesBuilder.put(method, ImmutableList.copyOf(keys));
@@ -123,8 +126,8 @@
throw new ConfigurationException(e.getErrors().getMessages());
}
- factory =
factoryType.cast(Proxy.newProxyInstance(factoryType.getClassLoader(),
- new Class[] { factoryType }, this));
+ factory =
factoryRawType.cast(Proxy.newProxyInstance(factoryRawType.getClassLoader(),
+ new Class[] { factoryRawType }, this));
}
public F get() {
Modified:
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
==============================================================================
---
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
(original)
+++
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/Parameter.java
Fri Feb 27 13:59:15 2009
@@ -93,11 +93,10 @@
}
private boolean isBound(Injector injector, Key<?> key) {
- /* This method is particularly lame - we really need an API that can
test
- for any binding, implicit or explicit */
+ // This method is particularly lame - we really need an API that can
test
+ // for any binding, implicit or explicit
try {
- return injector.getBinding(key) != null
- || injector.getProvider(key) != null;
+ return injector.getBinding(key) != null;
} catch (ConfigurationException e) {
return false;
}
@@ -123,12 +122,12 @@
}
private Type getProvidedType(Type type) {
- return ((ParameterizedType)type).getActualTypeArguments()[0];
+ return ((ParameterizedType) type).getActualTypeArguments()[0];
}
private boolean isProvider(Type type) {
return type instanceof ParameterizedType
- && ((ParameterizedType)type).getRawType() == Provider.class;
+ && ((ParameterizedType) type).getRawType() == Provider.class;
}
private Key<?> getBindingForType(Type type) {
Modified:
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
==============================================================================
---
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
(original)
+++
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProvider2Test.java
Fri Feb 27 13:59:15 2009
@@ -24,6 +24,7 @@
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matchers;
@@ -687,5 +688,195 @@
=
Subaru.class.getDeclaredField("colorProvider").getAnnotation(Assisted.class);
assertEqualsBothWays(FactoryProvider2.DEFAULT_ANNOTATION,
plainAssisted);
assertEquals(FactoryProvider2.DEFAULT_ANNOTATION.toString(),
plainAssisted.toString());
+ }
+
+
+ interface GenericColoredCarFactory<T extends Car> {
+ T create(Color color);
+ }
+
+ public void testGenericAssistedFactory() {
+ final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral
+ = new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
+ final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral
+ = new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Double.class).toInstance(5.0d);
+
bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+
bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+ bind(mustangTypeLiteral)
+ .toProvider(FactoryProvider.newFactory(mustangTypeLiteral,
TypeLiteral.get(Mustang.class)));
+ bind(camaroTypeLiteral)
+ .toProvider(FactoryProvider.newFactory(camaroTypeLiteral,
TypeLiteral.get(Camaro.class)));
+ }
+ });
+
+ GenericColoredCarFactory<Mustang> mustangFactory
+ = injector.getInstance(Key.get(mustangTypeLiteral));
+ GenericColoredCarFactory<Camaro> camaroFactory
+ = injector.getInstance(Key.get(camaroTypeLiteral));
+
+ Mustang blueMustang = mustangFactory.create(Color.BLUE);
+ assertEquals(Color.BLUE, blueMustang.color);
+ assertEquals(5.0d, blueMustang.engineSize);
+
+ Camaro redCamaro = camaroFactory.create(Color.RED);
+ assertEquals(Color.RED, redCamaro.color);
+ assertEquals(1984, redCamaro.modelYear);
+ assertEquals(250, redCamaro.horsePower);
+ }
+
+ public interface Insurance<T extends Car> {
+ }
+
+ public static class MustangInsurance implements Insurance<Mustang> {
+ private final double premium;
+ private final double limit;
+ private Mustang car;
+
+ @Inject
+ public MustangInsurance(@Named("lowLimit") double limit, @Assisted
Mustang car,
+ @Assisted double premium) {
+ this.premium = premium;
+ this.limit = limit;
+ this.car = car;
+ }
+
+ public void sell() {}
+ }
+
+ public static class CamaroInsurance implements Insurance<Camaro> {
+ private final double premium;
+ private final double limit;
+ private Camaro car;
+
+ @Inject
+ public CamaroInsurance(@Named("highLimit") double limit, @Assisted
Camaro car,
+ @Assisted double premium) {
+ this.premium = premium;
+ this.limit = limit;
+ this.car = car;
+ }
+
+ public void sell() {}
+ }
+
+ public interface MustangInsuranceFactory {
+ public Insurance<Mustang> create(Mustang car, double premium);
+ }
+
+ public interface CamaroInsuranceFactory {
+ public Insurance<Camaro> create(Camaro car, double premium);
+ }
+
+ public void testAssistedFactoryForConcreteType() {
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+
bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+
bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+ bind(MustangInsuranceFactory.class).toProvider(
+ FactoryProvider.newFactory(MustangInsuranceFactory.class,
MustangInsurance.class));
+ bind(CamaroInsuranceFactory.class).toProvider(
+ FactoryProvider.newFactory(CamaroInsuranceFactory.class,
CamaroInsurance.class));
+ }
+ });
+
+ MustangInsuranceFactory mustangInsuranceFactory =
+ injector.getInstance(MustangInsuranceFactory.class);
+ CamaroInsuranceFactory camaroInsuranceFactory =
+ injector.getInstance(CamaroInsuranceFactory.class);
+
+ Mustang mustang = new Mustang(5000d, Color.BLACK);
+ MustangInsurance mustangPolicy =
+ (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
+ assertEquals(800.0d, mustangPolicy.premium);
+ assertEquals(50000.0d, mustangPolicy.limit);
+
+ Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
+ CamaroInsurance camaroPolicy = (CamaroInsurance)
camaroInsuranceFactory.create(camaro, 800.0d);
+ assertEquals(800.0d, camaroPolicy.premium);
+ assertEquals(100000.0d, camaroPolicy.limit);
+ }
+
+ public interface InsuranceFactory<T extends Car> {
+ public Insurance<T> create(T car, double premium);
+ }
+
+ public void testAssistedFactoryForParameterizedType() {
+ final TypeLiteral<InsuranceFactory<Mustang>>
mustangInsuranceFactoryType =
+ new TypeLiteral<InsuranceFactory<Mustang>>() {};
+ final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType
=
+ new TypeLiteral<InsuranceFactory<Camaro>>() {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+
bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+
bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+
bind(mustangInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
+ mustangInsuranceFactoryType,
TypeLiteral.get(MustangInsurance.class)));
+
bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
+ camaroInsuranceFactoryType,
TypeLiteral.get(CamaroInsurance.class)));
+ }
+ });
+
+ InsuranceFactory<Mustang> mustangInsuranceFactory =
+ injector.getInstance(Key.get(mustangInsuranceFactoryType));
+ InsuranceFactory<Camaro> camaroInsuranceFactory =
+ injector.getInstance(Key.get(camaroInsuranceFactoryType));
+
+ Mustang mustang = new Mustang(5000d, Color.BLACK);
+ MustangInsurance mustangPolicy =
+ (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
+ assertEquals(800.0d, mustangPolicy.premium);
+ assertEquals(50000.0d, mustangPolicy.limit);
+
+ Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
+ CamaroInsurance camaroPolicy = (CamaroInsurance)
camaroInsuranceFactory.create(camaro, 800.0d);
+ assertEquals(800.0d, camaroPolicy.premium);
+ assertEquals(100000.0d, camaroPolicy.limit);
+ }
+
+ public static class AutoInsurance<T extends Car> implements Insurance<T>
{
+ private final double premium;
+ private final double limit;
+ private final T car;
+
+ @Inject
+ public AutoInsurance(double limit, @Assisted T car, @Assisted double
premium) {
+ this.limit = limit;
+ this.car = car;
+ this.premium = premium;
+ }
+
+ public void sell() {}
+ }
+
+ public void testAssistedFactoryForTypeVariableParameters() {
+ final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType
=
+ new TypeLiteral<InsuranceFactory<Camaro>>() {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Double.class).toInstance(50000.0d);
+
bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
+ camaroInsuranceFactoryType, new
TypeLiteral<AutoInsurance<Camaro>>() {}));
+ }
+ });
+
+ InsuranceFactory<Camaro> camaroInsuranceFactory =
+ injector.getInstance(Key.get(camaroInsuranceFactoryType));
+
+ Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
+ AutoInsurance camaroPolicy = (AutoInsurance)
camaroInsuranceFactory.create(camaro, 800.0d);
+ assertEquals(800.0d, camaroPolicy.premium);
+ assertEquals(50000.0d, camaroPolicy.limit);
+ assertEquals(camaro, camaroPolicy.car);
}
}
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
Fri Feb 27 13:59:15 2009
@@ -577,4 +577,193 @@
interface AssistedParamsFactory {
Car create(@Assisted Color color);
}
+
+ interface GenericColoredCarFactory<T extends Car> {
+ T create(Color color);
+ }
+
+ public void testGenericAssistedFactory() {
+ final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral
+ = new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
+ final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral
+ = new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Double.class).toInstance(5.0d);
+
bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
+
bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
+ bind(mustangTypeLiteral).toProvider(
+ FactoryProvider.newFactory(mustangTypeLiteral,
TypeLiteral.get(Mustang.class)));
+ bind(camaroTypeLiteral).toProvider(
+ FactoryProvider.newFactory(camaroTypeLiteral,
TypeLiteral.get(Camaro.class)));
+ }
+ });
+
+ GenericColoredCarFactory<Mustang> mustangFactory
+ = injector.getInstance(Key.get(mustangTypeLiteral));
+ GenericColoredCarFactory<Camaro> camaroFactory
+ = injector.getInstance(Key.get(camaroTypeLiteral));
+
+ Mustang blueMustang = mustangFactory.create(Color.BLUE);
+ assertEquals(Color.BLUE, blueMustang.color);
+ assertEquals(5.0d, blueMustang.engineSize);
+
+ Camaro redCamaro = camaroFactory.create(Color.RED);
+ assertEquals(Color.RED, redCamaro.color);
+ assertEquals(1984, redCamaro.modelYear);
+ assertEquals(250, redCamaro.horsePower);
+ }
+
+ public interface Insurance<T extends Car> {
+ }
+
+ public static class MustangInsurance implements Insurance<Mustang> {
+ private final double premium;
+ private final double limit;
+ private Mustang car;
+
+ @AssistedInject
+ public MustangInsurance(@Named("lowLimit") double limit, @Assisted
Mustang car,
+ @Assisted double premium) {
+ this.premium = premium;
+ this.limit = limit;
+ this.car = car;
+ }
+
+ public void sell() {}
+ }
+
+ public static class CamaroInsurance implements Insurance<Camaro> {
+ private final double premium;
+ private final double limit;
+ private Camaro car;
+
+ @AssistedInject
+ public CamaroInsurance(@Named("highLimit") double limit, @Assisted
Camaro car,
+ @Assisted double premium) {
+ this.premium = premium;
+ this.limit = limit;
+ this.car = car;
+ }
+
+ public void sell() {}
+ }
+
+ public interface MustangInsuranceFactory {
+ public Insurance<Mustang> create(Mustang car, double premium);
+ }
+
+ public interface CamaroInsuranceFactory {
+ public Insurance<Camaro> create(Camaro car, double premium);
+ }
+
+ public void testAssistedFactoryForConcreteType() {
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+
bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+
bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+ bind(MustangInsuranceFactory.class).toProvider(
+ FactoryProvider.newFactory(MustangInsuranceFactory.class,
MustangInsurance.class));
+ bind(CamaroInsuranceFactory.class).toProvider(
+ FactoryProvider.newFactory(CamaroInsuranceFactory.class,
CamaroInsurance.class));
+ }
+ });
+
+ MustangInsuranceFactory mustangInsuranceFactory =
+ injector.getInstance(MustangInsuranceFactory.class);
+ CamaroInsuranceFactory camaroInsuranceFactory =
+ injector.getInstance(CamaroInsuranceFactory.class);
+
+ Mustang mustang = new Mustang(5000d, Color.BLACK);
+ MustangInsurance mustangPolicy =
+ (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
+ assertEquals(800.0d, mustangPolicy.premium);
+ assertEquals(50000.0d, mustangPolicy.limit);
+
+ Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
+ CamaroInsurance camaroPolicy = (CamaroInsurance)
camaroInsuranceFactory.create(camaro, 800.0d);
+ assertEquals(800.0d, camaroPolicy.premium);
+ assertEquals(100000.0d, camaroPolicy.limit);
+ }
+
+ public interface InsuranceFactory<T extends Car> {
+ public Insurance<T> create(T car, double premium);
+ }
+
+ public void testAssistedFactoryForParameterizedType() {
+ final TypeLiteral<InsuranceFactory<Mustang>>
mustangInsuranceFactoryType =
+ new TypeLiteral<InsuranceFactory<Mustang>>() {};
+ final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType
=
+ new TypeLiteral<InsuranceFactory<Camaro>>() {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+
bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
+
bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
+
bind(mustangInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
+ mustangInsuranceFactoryType,
TypeLiteral.get(MustangInsurance.class)));
+
bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
+ camaroInsuranceFactoryType,
TypeLiteral.get(CamaroInsurance.class)));
+ }
+ });
+
+ InsuranceFactory<Mustang> mustangInsuranceFactory =
+ injector.getInstance(Key.get(mustangInsuranceFactoryType));
+ InsuranceFactory<Camaro> camaroInsuranceFactory =
+ injector.getInstance(Key.get(camaroInsuranceFactoryType));
+
+ Mustang mustang = new Mustang(5000d, Color.BLACK);
+ MustangInsurance mustangPolicy =
+ (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
+ assertEquals(800.0d, mustangPolicy.premium);
+ assertEquals(50000.0d, mustangPolicy.limit);
+
+ Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
+ CamaroInsurance camaroPolicy = (CamaroInsurance)
camaroInsuranceFactory.create(camaro, 800.0d);
+ assertEquals(800.0d, camaroPolicy.premium);
+ assertEquals(100000.0d, camaroPolicy.limit);
+ }
+
+ public static class AutoInsurance<T extends Car> implements Insurance<T>
{
+ private final double premium;
+ private final double limit;
+ private final T car;
+
+ @AssistedInject
+ public AutoInsurance(double limit, @Assisted T car, @Assisted double
premium) {
+ this.limit = limit;
+ this.car = car;
+ this.premium = premium;
+ }
+
+ public void sell() {}
+ }
+
+ public void testAssistedFactoryForTypeVariableParameters() {
+ final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType
=
+ new TypeLiteral<InsuranceFactory<Camaro>>() {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Double.class).toInstance(50000.0d);
+
bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
+ camaroInsuranceFactoryType, new
TypeLiteral<AutoInsurance<Camaro>>() {}));
+ }
+ });
+
+ InsuranceFactory<Camaro> camaroInsuranceFactory =
+ injector.getInstance(Key.get(camaroInsuranceFactoryType));
+
+ Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
+ AutoInsurance camaroPolicy = (AutoInsurance)
camaroInsuranceFactory.create(camaro, 800.0d);
+ assertEquals(800.0d, camaroPolicy.premium);
+ assertEquals(50000.0d, camaroPolicy.limit);
+ assertEquals(camaro, camaroPolicy.car);
+ }
}
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---