checkForMisplacedBindingAnnotations(injectableConstructor, errors); return new InjectionPoint(type, injectableConstructor); checkForMisplacedBindingAnnotations(noArgConstructor, errors); return new InjectionPoint(type, noArgConstructor); } catch (NoSuchMethodException e) { errors.missingConstructor(rawType);
private static <M extends Member & AnnotatedElement> void addInjectionPoints(TypeLiteral<?> type, Factory<M> factory, boolean statics, Collection<InjectionPoint> injectionPoints, Errors errors) { if (type.getType() == Object.class) { return; } // Add injectors for superclass first. TypeLiteral<?> superType = type.getSupertype(type.getRawType().getSuperclass()); addInjectionPoints(superType, factory, statics, injectionPoints, errors); // Add injectors for all members next addInjectorsForMembers(type, factory, statics, injectionPoints, errors); }
/** * Returns a new injection point for the injectable constructor of {@code type}. * * @param type a concrete type with exactly one constructor annotated {@literal @}{@link Inject}, * or a no-arguments constructor that is not private. * @throws ConfigurationException if there is no injectable constructor, more than one injectable * constructor, or if parameters of the injectable constructor are malformed, such as a * parameter with multiple binding annotations. */ public static InjectionPoint forConstructorOf(Class<?> type) { return forConstructorOf(TypeLiteral.get(type)); }
SingleMethodInjector(InjectorImpl injector, InjectionPoint injectionPoint, Errors errors) throws ErrorsException { this.injectionPoint = injectionPoint; final Method method = (Method) injectionPoint.getMember(); methodInvoker = createMethodInvoker(method); parameterInjectors = injector.getParametersInjectors(injectionPoint.getDependencies(), errors); }
/** * Returns the injectors for the specified injection points. */ List<SingleMemberInjector> getInjectors( Set<InjectionPoint> injectionPoints, Errors errors) { List<SingleMemberInjector> injectors = new ArrayList<>(); for (InjectionPoint injectionPoint : injectionPoints) { try { Errors errorsForMember = injectionPoint.isOptional() ? new Errors(injectionPoint) : errors.withSource(injectionPoint); SingleMemberInjector injector = injectionPoint.getMember() instanceof Field ? new SingleFieldInjector(this.injector, injectionPoint, errorsForMember) : new SingleMethodInjector(this.injector, injectionPoint, errorsForMember); injectors.add(injector); } catch (ErrorsException ignoredForNow) { // ignored for now } } return Collections.unmodifiableList(injectors); } }
private <T> ConstructorInjector<T> createConstructor(TypeLiteral<T> type, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); InjectionPoint injectionPoint; try { injectionPoint = InjectionPoint.forConstructorOf(type); } catch (ConfigurationException e) { errors.merge(e.getErrorMessages()); throw errors.toException(); } SingleParameterInjector<?>[] constructorParameterInjectors = injector.getParametersInjectors(injectionPoint.getDependencies(), errors); MembersInjectorImpl<T> membersInjector = injector.membersInjectorStore.get(type, errors); ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<>(injectionPoint); errors.throwIfNewErrors(numErrorsBefore); return new ConstructorInjector<>(membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors, membersInjector); } }
/** * Returns the instance methods and fields of {@code instance} that will be injected to fulfill * this request. * * @return a possibly empty set of injection points. The set has a specified iteration order. All * fields are returned and then all methods. Within the fields, supertype fields are returned * before subtype fields. Similarly, supertype methods are returned before subtype methods. * @throws ConfigurationException if there is a malformed injection point on the class of {@code * instance}, such as a field with multiple binding annotations. The exception's {@link * ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} * of the valid injection points. */ public Set<InjectionPoint> getInjectionPoints() throws ConfigurationException { return InjectionPoint.forInstanceMethodsAndFields(instance.getClass()); }
InjectionPoint(TypeLiteral<?> type, Constructor<?> constructor) { this.member = constructor; this.optional = false; this.dependencies = forMember(constructor, type, constructor.getParameterAnnotations()); }
@Override public InjectionPoint create(TypeLiteral<?> typeLiteral, Method member, Errors errors) { checkForMisplacedBindingAnnotations(member, errors); return new InjectionPoint(typeLiteral, member); } };
/** * Returns the static methods and fields of {@code type} that will be injected to fulfill this * request. * * @return a possibly empty set of injection points. The set has a specified iteration order. All * fields are returned and then all methods. Within the fields, supertype fields are returned * before subtype fields. Similarly, supertype methods are returned before subtype methods. * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as * a field with multiple binding annotations. The exception's {@link * ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} * of the valid injection points. */ public Set<InjectionPoint> getInjectionPoints() throws ConfigurationException { return InjectionPoint.forStaticMethodsAndFields(type); }
/** * Returns all static method and field injection points on {@code type}. * * @return a possibly empty set of injection points. The set has a specified iteration order. All * fields are returned and then all methods. Within the fields, supertype fields are returned * before subtype fields. Similarly, supertype methods are returned before subtype methods. * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as * a field with multiple binding annotations. The exception's {@link * ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} * of the valid injection points. */ public static Set<InjectionPoint> forStaticMethodsAndFields(TypeLiteral type) { Set<InjectionPoint> result = new HashSet<>(); Errors errors = new Errors(); addInjectionPoints(type, Factory.FIELDS, true, result, errors); addInjectionPoints(type, Factory.METHODS, true, result, errors); result = unmodifiableSet(result); if (errors.hasErrors()) { throw new ConfigurationException(errors.getMessages()).withPartialValue(result); } return result; }
/** * Returns the dependencies from the given injection points. */ public static Set<Dependency<?>> forInjectionPoints(Set<InjectionPoint> injectionPoints) { Set<Dependency<?>> dependencies = new HashSet<>(); for (InjectionPoint injectionPoint : injectionPoints) { dependencies.addAll(injectionPoint.getDependencies()); } return unmodifiableSet(dependencies); }
@Override public ConstructionProxy<T> create() { @SuppressWarnings("unchecked") // the injection point is for a constructor of T final Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember(); return new ConstructionProxy<T>() { @Override public T newInstance(Object... arguments) throws InvocationTargetException { try { return constructor.newInstance(arguments); } catch (InstantiationException e) { throw new AssertionError(e); // shouldn't happen, we know this is a concrete type } catch (IllegalAccessException e) { // a security manager is blocking us, we're hosed throw new AssertionError("Wrong access modifiers on " + constructor, e); } } @Override public InjectionPoint getInjectionPoint() { return injectionPoint; } @Override public Constructor<T> getConstructor() { return constructor; } }; } }
SingleFieldInjector(InjectorImpl injector, InjectionPoint injectionPoint, Errors errors) throws ErrorsException { this.injectionPoint = injectionPoint; this.field = (Field) injectionPoint.getMember(); this.dependency = injectionPoint.getDependencies().get(0); factory = injector.getInternalFactory(dependency.getKey(), errors); }
private <T> ConstructorInjector<T> createConstructor(TypeLiteral<T> type, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); InjectionPoint injectionPoint; try { injectionPoint = InjectionPoint.forConstructorOf(type); } catch (ConfigurationException e) { errors.merge(e.getErrorMessages()); throw errors.toException(); } SingleParameterInjector<?>[] constructorParameterInjectors = injector.getParametersInjectors(injectionPoint.getDependencies(), errors); MembersInjectorImpl<T> membersInjector = injector.membersInjectorStore.get(type, errors); ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<>(injectionPoint); errors.throwIfNewErrors(numErrorsBefore); return new ConstructorInjector<>(membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors, membersInjector); } }
/** * Returns all instance method and field injection points on {@code type}. * * @return a possibly empty set of injection points. The set has a specified iteration order. All * fields are returned and then all methods. Within the fields, supertype fields are returned * before subtype fields. Similarly, supertype methods are returned before subtype methods. * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as * a field with multiple binding annotations. The exception's {@link * ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} * of the valid injection points. */ public static Set<InjectionPoint> forInstanceMethodsAndFields(Class<?> type) { return forInstanceMethodsAndFields(TypeLiteral.get(type)); }
InjectionPoint(TypeLiteral<?> type, Method method) { this.member = method; Inject inject = method.getAnnotation(Inject.class); this.optional = inject.optional(); this.dependencies = forMember(method, type, method.getParameterAnnotations()); }
@Override public InjectionPoint create(TypeLiteral<?> typeLiteral, Field member, Errors errors) { return new InjectionPoint(typeLiteral, member); } };
/** * Returns all static method and field injection points on {@code type}. * * @return a possibly empty set of injection points. The set has a specified iteration order. All * fields are returned and then all methods. Within the fields, supertype fields are returned * before subtype fields. Similarly, supertype methods are returned before subtype methods. * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as * a field with multiple binding annotations. The exception's {@link * ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} * of the valid injection points. */ public static Set<InjectionPoint> forStaticMethodsAndFields(Class<?> type) { return forStaticMethodsAndFields(TypeLiteral.get(type)); }
/** * Returns all instance method and field injection points on {@code type}. * * @return a possibly empty set of injection points. The set has a specified iteration order. All * fields are returned and then all methods. Within the fields, supertype fields are returned * before subtype fields. Similarly, supertype methods are returned before subtype methods. * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as * a field with multiple binding annotations. The exception's {@link * ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} * of the valid injection points. */ public static Set<InjectionPoint> forInstanceMethodsAndFields(TypeLiteral<?> type) { Set<InjectionPoint> result = new HashSet<>(); Errors errors = new Errors(); // TODO (crazybob): Filter out overridden members. addInjectionPoints(type, Factory.FIELDS, false, result, errors); addInjectionPoints(type, Factory.METHODS, false, result, errors); result = unmodifiableSet(result); if (errors.hasErrors()) { throw new ConfigurationException(errors.getMessages()).withPartialValue(result); } return result; }