com.google.inject.internal.InjectionRequestProcessor Maven / Gradle / Ivy
package com.google.inject.internal;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.inject.ConfigurationException;
import com.google.inject.Stage;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.InjectionRequest;
import com.google.inject.spi.StaticInjectionRequest;
import java.util.List;
import java.util.Set;
/**
* Handles {@code Binder.requestInjection} and {@code Binder.requestStaticInjection} commands.
*
*/
final class InjectionRequestProcessor extends AbstractProcessor {
private final List staticInjections = Lists.newArrayList();
private final Initializer initializer;
InjectionRequestProcessor(Errors errors, Initializer initializer) {
super(errors);
this.initializer = initializer;
}
@Override
public Boolean visit(StaticInjectionRequest request) {
staticInjections.add(new StaticInjection(injector, request));
return true;
}
@Override
public Boolean visit(InjectionRequest> request) {
Set injectionPoints;
try {
injectionPoints = request.getInjectionPoints();
} catch (ConfigurationException e) {
errors.merge(e.getErrorMessages());
injectionPoints = e.getPartialValue();
}
initializer.requestInjection(
injector, request.getInstance(), null, request.getSource(), injectionPoints);
return true;
}
void validate() {
for (StaticInjection staticInjection : staticInjections) {
staticInjection.validate();
}
}
void injectMembers() {
/*
* TODO: If you request both a parent class and one of its
* subclasses, the parent class's static members will be
* injected twice.
*/
for (StaticInjection staticInjection : staticInjections) {
staticInjection.injectMembers();
}
}
/**
* A requested static injection.
*/
private class StaticInjection {
final InjectorImpl injector;
final Object source;
final StaticInjectionRequest request;
ImmutableList memberInjectors;
public StaticInjection(InjectorImpl injector, StaticInjectionRequest request) {
this.injector = injector;
this.source = request.getSource();
this.request = request;
}
void validate() {
Errors errorsForMember = errors.withSource(source);
Set injectionPoints;
try {
injectionPoints = request.getInjectionPoints();
} catch (ConfigurationException e) {
errorsForMember.merge(e.getErrorMessages());
injectionPoints = e.getPartialValue();
}
if (injectionPoints != null) {
memberInjectors = injector.membersInjectorStore.getInjectors(
injectionPoints, errorsForMember);
} else {
memberInjectors = ImmutableList.of();
}
errors.merge(errorsForMember);
}
void injectMembers() {
try (InternalContext context = injector.enterContext()) {
boolean isStageTool = injector.options.stage == Stage.TOOL;
for (SingleMemberInjector memberInjector : memberInjectors) {
// Run injections if we're not in tool stage (ie, PRODUCTION or DEV),
// or if we are in tool stage and the injection point is toolable.
if (!isStageTool || memberInjector.getInjectionPoint().isToolable()) {
try {
memberInjector.inject(context, null);
} catch (InternalProvisionException e) {
errors.merge(e);
}
}
}
}
}
}
}