/** Creates a new members injector and attaches both injection listeners and method aspects. */ private <T> MembersInjectorImpl<T> createWithListeners(TypeLiteral<T> type, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); Set<InjectionPoint> injectionPoints; try { injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type); } catch (ConfigurationException e) { errors.merge(e.getErrorMessages()); injectionPoints = e.getPartialValue(); } ImmutableList<SingleMemberInjector> injectors = getInjectors(injectionPoints, errors); errors.throwIfNewErrors(numErrorsBefore); EncounterImpl<T> encounter = new EncounterImpl<>(errors, injector.lookups); Set<TypeListener> alreadySeenListeners = Sets.newHashSet(); for (TypeListenerBinding binding : typeListenerBindings) { TypeListener typeListener = binding.getListener(); if (!alreadySeenListeners.contains(typeListener) && binding.getTypeMatcher().matches(type)) { alreadySeenListeners.add(typeListener); try { typeListener.hear(type, encounter); } catch (RuntimeException e) { errors.errorNotifyingTypeListener(binding, type, e); } } } encounter.invalidate(); errors.throwIfNewErrors(numErrorsBefore); return new MembersInjectorImpl<T>(injector, type, encounter, injectors); }
membersInjector.getAddedAspects().isEmpty() ? injectorAspects : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects())); ConstructionProxyFactory<T> factory = new ProxyFactory<>(injectionPoint, methodAspects); membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors,
@Override public void injectMembers(T instance) { TypeLiteral<T> localTypeLiteral = typeLiteral; try { injectAndNotify(instance, null, null, localTypeLiteral, false); } catch (InternalProvisionException ipe) { throw ipe.addSource(localTypeLiteral).toProvisionException(); } }
/** Provisions a new T. */ private T provision(InternalContext context, ConstructionContext<T> constructionContext) throws InternalProvisionException { try { T t; try { Object[] parameters = SingleParameterInjector.getAll(context, parameterInjectors); t = constructionProxy.newInstance(parameters); constructionContext.setProxyDelegates(t); } finally { constructionContext.finishConstruction(); } // Store reference. If an injector re-enters this factory, they'll get the same reference. constructionContext.setCurrentReference(t); MembersInjectorImpl<T> localMembersInjector = membersInjector; localMembersInjector.injectMembers(t, context, false); localMembersInjector.notifyListeners(t); return t; } catch (InvocationTargetException userException) { Throwable cause = userException.getCause() != null ? userException.getCause() : userException; throw InternalProvisionException.errorInjectingConstructor(cause) .addSource(constructionProxy.getInjectionPoint()); } finally { constructionContext.removeCurrentReference(); } } }
@Override public T call() throws InternalProvisionException { injectMembers(instance, context, toolableOnly); return instance; } });
void injectAndNotify(final T instance, final Errors errors, final boolean toolableOnly) throws ErrorsException { if (instance == null) { return; } injector.callInContext(new ContextualCallable<Void>() { public Void call(InternalContext context) throws ErrorsException { injectMembers(instance, errors, context, toolableOnly); return null; } }); // TODO: We *could* notify listeners too here, // but it's not clear if we want to. There's no way to know // if a MembersInjector from the usersMemberInjector list wants // toolable injections, so do we really want to notify // about injection? (We could take a strategy of only notifying // if atleast one InjectionPoint was toolable, in which case // the above callInContext could return 'true' if it injected // anything.) if(!toolableOnly) { notifyListeners(instance, errors); } }
private <T> ConstructorInjector<T> createConstructor(InjectionPoint injectionPoint, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); SingleParameterInjector<?>[] constructorParameterInjectors = injector.getParametersInjectors(injectionPoint.getDependencies(), errors); @SuppressWarnings("unchecked") // the injector type agrees with the injection point type MembersInjectorImpl<T> membersInjector = (MembersInjectorImpl<T>) injector.membersInjectorStore .get(injectionPoint.getDeclaringType(), errors); ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<T>(injectionPoint); errors.throwIfNewErrors(numErrorsBefore); return new ConstructorInjector<T>(membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors, membersInjector); } }
injectMembers(instance, context, toolableOnly); notifyListeners(instance);
@Override public T call() throws InternalProvisionException { injectMembers(instance, context, toolableOnly); return instance; } });
void injectAndNotify(final T instance, final Errors errors, final boolean toolableOnly) throws ErrorsException { if (instance == null) { return; } injector.callInContext(new ContextualCallable<Void>() { public Void call(InternalContext context) throws ErrorsException { injectMembers(instance, errors, context, toolableOnly); return null; } }); // TODO: We *could* notify listeners too here, // but it's not clear if we want to. There's no way to know // if a MembersInjector from the usersMemberInjector list wants // toolable injections, so do we really want to notify // about injection? (We could take a strategy of only notifying // if atleast one InjectionPoint was toolable, in which case // the above callInContext could return 'true' if it injected // anything.) if(!toolableOnly) { notifyListeners(instance, errors); } }
private <T> ConstructorInjector<T> createConstructor(InjectionPoint injectionPoint, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); SingleParameterInjector<?>[] constructorParameterInjectors = injector.getParametersInjectors(injectionPoint.getDependencies(), errors); @SuppressWarnings("unchecked") // the injector type agrees with the injection point type MembersInjectorImpl<T> membersInjector = (MembersInjectorImpl<T>) injector.membersInjectorStore .get(injectionPoint.getDeclaringType(), errors); /*if[AOP]*/ ImmutableList<MethodAspect> injectorAspects = injector.state.getMethodAspects(); ImmutableList<MethodAspect> methodAspects = membersInjector.getAddedAspects().isEmpty() ? injectorAspects : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects())); ConstructionProxyFactory<T> factory = new ProxyFactory<T>(injectionPoint, methodAspects); /*end[AOP]*/ /*if[NO_AOP] ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<T>(injectionPoint); end[NO_AOP]*/ errors.throwIfNewErrors(numErrorsBefore); return new ConstructorInjector<T>(membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors, membersInjector); } }
/** Provisions a new T. */ private T provision(InternalContext context, ConstructionContext<T> constructionContext) throws InternalProvisionException { try { T t; try { Object[] parameters = SingleParameterInjector.getAll(context, parameterInjectors); t = constructionProxy.newInstance(parameters); constructionContext.setProxyDelegates(t); } finally { constructionContext.finishConstruction(); } // Store reference. If an injector re-enters this factory, they'll get the same reference. constructionContext.setCurrentReference(t); MembersInjectorImpl<T> localMembersInjector = membersInjector; localMembersInjector.injectMembers(t, context, false); localMembersInjector.notifyListeners(t); return t; } catch (InvocationTargetException userException) { Throwable cause = userException.getCause() != null ? userException.getCause() : userException; throw InternalProvisionException.errorInjectingConstructor(cause) .addSource(constructionProxy.getInjectionPoint()); } finally { constructionContext.removeCurrentReference(); } } }
membersInjector.injectAndNotify( instance, key, provisionCallback, source, injector.options.stage == Stage.TOOL); } catch (InternalProvisionException ipe) {
membersInjector.getAddedAspects().isEmpty() ? injectorAspects : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects())); ConstructionProxyFactory<T> factory = new ProxyFactory<>(injectionPoint, methodAspects); membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors,
public Void call(InternalContext context) throws ErrorsException { injectMembers(instance, errors, context, toolableOnly); return null; } });
/** Creates a new members injector and attaches both injection listeners and method aspects. */ private <T> MembersInjectorImpl<T> createWithListeners(TypeLiteral<T> type, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); Set<InjectionPoint> injectionPoints; try { injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type); } catch (ConfigurationException e) { errors.merge(e.getErrorMessages()); injectionPoints = e.getPartialValue(); } ImmutableList<SingleMemberInjector> injectors = getInjectors(injectionPoints, errors); errors.throwIfNewErrors(numErrorsBefore); EncounterImpl<T> encounter = new EncounterImpl<>(errors, injector.lookups); Set<TypeListener> alreadySeenListeners = Sets.newHashSet(); for (TypeListenerBinding binding : typeListenerBindings) { TypeListener typeListener = binding.getListener(); if (!alreadySeenListeners.contains(typeListener) && binding.getTypeMatcher().matches(type)) { alreadySeenListeners.add(typeListener); try { typeListener.hear(type, encounter); } catch (RuntimeException e) { errors.errorNotifyingTypeListener(binding, type, e); } } } encounter.invalidate(); errors.throwIfNewErrors(numErrorsBefore); return new MembersInjectorImpl<T>(injector, type, encounter, injectors); }
void injectAndNotify(final T instance, final Errors errors, final boolean toolableOnly) throws ErrorsException { if (instance == null) { return; } injector.callInContext(new ContextualCallable<Void>() { public Void call(InternalContext context) throws ErrorsException { injectMembers(instance, errors, context, toolableOnly); return null; } }); // TODO: We *could* notify listeners too here, // but it's not clear if we want to. There's no way to know // if a MembersInjector from the usersMemberInjector list wants // toolable injections, so do we really want to notify // about injection? (We could take a strategy of only notifying // if atleast one InjectionPoint was toolable, in which case // the above callInContext could return 'true' if it injected // anything.) if(!toolableOnly) { notifyListeners(instance, errors); } }
private <T> ConstructorInjector<T> createConstructor(InjectionPoint injectionPoint, Errors errors) throws ErrorsException { int numErrorsBefore = errors.size(); SingleParameterInjector<?>[] constructorParameterInjectors = injector.getParametersInjectors(injectionPoint.getDependencies(), errors); @SuppressWarnings("unchecked") // the injector type agrees with the injection point type MembersInjectorImpl<T> membersInjector = (MembersInjectorImpl<T>) injector.membersInjectorStore .get(injectionPoint.getDeclaringType(), errors); /*if[AOP]*/ ImmutableList<MethodAspect> injectorAspects = injector.state.getMethodAspects(); ImmutableList<MethodAspect> methodAspects = membersInjector.getAddedAspects().isEmpty() ? injectorAspects : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects())); ConstructionProxyFactory<T> factory = new ProxyFactory<T>(injectionPoint, methodAspects); /*end[AOP]*/ /*if[NO_AOP] ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<T>(injectionPoint); end[NO_AOP]*/ errors.throwIfNewErrors(numErrorsBefore); return new ConstructorInjector<T>(membersInjector.getInjectionPoints(), factory.create(), constructorParameterInjectors, membersInjector); } }
injectMembers(instance, context, toolableOnly); notifyListeners(instance);
/** * Reentrant. If {@code instance} was registered for injection at injector-creation time, this * method will ensure that all its members have been injected before returning. */ public T get(Errors errors) throws ErrorsException { if (ready.getCount() == 0) { return instance; } // just wait for everything to be injected by another thread if (Thread.currentThread() != creatingThread) { try { ready.await(); return instance; } catch (InterruptedException e) { // Give up, since we don't know if our injection is ready throw new RuntimeException(e); } } // toInject needs injection, do it right away. we only do this once, even if it fails if (pendingInjection.remove(instance) != null) { // if in Stage.TOOL, we only want to inject & notify toolable injection points. // (otherwise we'll inject all of them) membersInjector.injectAndNotify(instance, errors.withSource(source), injector.options.stage == Stage.TOOL); } return instance; }