private static <T> CommandParameterSuggester<T> optionallyCreateSuggestor( Class<? extends CommandParameterSuggester<T>> suggestorClass, Context context) { if (suggestorClass == null) { return null; } return InjectionHelper.createWithConstructorInjection(suggestorClass, context); }
@SuppressWarnings({"rawtypes", "unchecked"}) private static void registerTypeHandlers(Context context, TypeSerializationLibrary library, ModuleEnvironment environment) { for (Class<? extends TypeHandler> handler : environment.getSubtypesOf(TypeHandler.class)) { RegisterTypeHandler register = handler.getAnnotation(RegisterTypeHandler.class); if (register != null) { Optional<Type> opt = GenericsUtil.getTypeParameterBindingForInheritedClass(handler, TypeHandler.class, 0); if (opt.isPresent()) { TypeHandler instance = InjectionHelper.createWithConstructorInjection(handler, context); InjectionHelper.inject(instance, context); library.add((Class) opt.get(), instance); } } } } }
private static Parameter getParameterTypeFor(Class<?> type, Annotation[] annotations, Context context) { for (Annotation annotation : annotations) { if (annotation instanceof CommandParam) { CommandParam parameterAnnotation = (CommandParam) annotation; String name = parameterAnnotation.value(); Class<? extends CommandParameterSuggester> suggesterClass = parameterAnnotation.suggester(); boolean required = parameterAnnotation.required(); CommandParameterSuggester suggester = InjectionHelper.createWithConstructorInjection(suggesterClass, context); if (type.isArray()) { Class<?> childType = type.getComponentType(); return CommandParameter.array(name, childType, required, suggester, context); } else { return CommandParameter.single(name, type, required, suggester, context); } } else if (annotation instanceof Sender) { return MarkerParameters.SENDER; } } return MarkerParameters.INVALID; } }
@Test public void testConstructorInjectionNotAllParametersPopulated() { Context context = new ContextImpl(); context.put(ServiceA.class, serviceA); //context.put(ServiceB.class, serviceB); ConstructorAB constructorAB = InjectionHelper.createWithConstructorInjection(ConstructorAB.class, context); //the two-arg constructor can't be populated because serviceB is not available //there is no fallback for a constructor with only serviceA, so the default constructor is called assertThat(constructorAB.getServiceA(), is(nullValue())); assertThat(constructorAB.getServiceB(), is(nullValue())); }
@Test(expected = NoSuchElementException.class) public void testConstructorInjectionNoDefaultConstructorForFallback() { Context context = new ContextImpl(); context.put(ServiceA.class, serviceA); //context.put(ServiceB.class, serviceB); //there is only one constructor for serviceB which is not present on the context. //a default constructor is not available, so the injection fails. InjectionHelper.createWithConstructorInjection(ConstructorB.class, context); }
@Test public void testConstructorInjectionNotAllParametersPopulatedFallback() { Context context = new ContextImpl(); context.put(ServiceA.class, serviceA); //context.put(ServiceB.class, serviceB); ConstructorA_AB constructorA_AB = InjectionHelper.createWithConstructorInjection(ConstructorA_AB.class, context); //the one-arg constructor is used as it can be populated with serviceA which is available assertThat(constructorA_AB.getServiceA(), is(serviceA)); assertThat(constructorA_AB.getServiceB(), is(nullValue())); }
@Test public void testDefaultConstructorInjection() { Context context = new ContextImpl(); context.put(ServiceA.class, serviceA); context.put(ServiceB.class, serviceB); ConstructorAB constructorAB = InjectionHelper.createWithConstructorInjection(ConstructorAB.class, context); //the two-arg constructor should be used as it has the most parameters and all can be populated assertThat(constructorAB.getServiceA(), is(serviceA)); assertThat(constructorAB.getServiceB(), is(serviceB)); }