private ImmutableMap<Key<?>, Binding<?>> indexBindings(Iterable<Element> elements) { ImmutableMap.Builder<Key<?>, Binding<?>> builder = ImmutableMap.builder(); for (Element element : elements) { if (element instanceof Binding) { Binding<?> binding = (Binding<?>) element; builder.put(binding.getKey(), binding); } else if (element instanceof PrivateElements) { PrivateElements privateElements = (PrivateElements) element; Map<Key<?>, Binding<?>> privateBindings = indexBindings(privateElements.getElements()); for (Key<?> exposed : privateElements.getExposedKeys()) { builder.put(exposed, privateBindings.get(exposed)); } } } return builder.build(); }
ImmutableMap<Key<?>, Binding<?>> indexBindings(Iterable<Element> elements) { ImmutableMap.Builder<Key<?>, Binding<?>> builder = ImmutableMap.builder(); for (Element element : elements) { if (element instanceof Binding) { Binding<?> binding = (Binding<?>) element; builder.put(binding.getKey(), binding); } else if (element instanceof PrivateElements) { PrivateElements privateElements = (PrivateElements) element; Map<Key<?>, Binding<?>> privateBindings = indexBindings(privateElements.getElements()); for (Key<?> exposed : privateElements.getExposedKeys()) { builder.put(exposed, privateBindings.get(exposed)); } } } return builder.build(); }
public void testSpiAccess() { Injector injector = Guice.createInjector(new PrivateModule() { @Override public void configure() { bind(String.class).annotatedWith(named("a")).toInstance("private"); bind(String.class).annotatedWith(named("b")).toInstance("exposed"); expose(String.class).annotatedWith(named("b")); } }); ExposedBinding<?> binding = (ExposedBinding<?>) injector.getBinding(Key.get(String.class, Names.named("b"))); assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class))), binding.getDependencies()); PrivateElements privateElements = binding.getPrivateElements(); assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class, named("b"))), privateElements.getExposedKeys()); assertContains(privateElements.getExposedSource(Key.get(String.class, named("b"))).toString(), PrivateModuleTest.class.getName(), getDeclaringSourcePart(getClass())); Injector privateInjector = privateElements.getInjector(); assertEquals("private", privateInjector.getInstance(Key.get(String.class, Names.named("a")))); }
ImmutableMap<Key<?>, Binding<?>> indexBindings(Iterable<Element> elements) { ImmutableMap.Builder<Key<?>, Binding<?>> builder = ImmutableMap.builder(); for (Element element : elements) { if (element instanceof Binding) { Binding<?> binding = (Binding<?>) element; builder.put(binding.getKey(), binding); } else if (element instanceof PrivateElements) { PrivateElements privateElements = (PrivateElements)element; Map<Key<?>, Binding<?>> privateBindings = indexBindings(privateElements.getElements()); for(Key<?> exposed : privateElements.getExposedKeys()) { builder.put(exposed, privateBindings.get(exposed)); } } } return builder.build(); }
public void testSpiAccess() { Injector injector = Guice.createInjector(new PrivateModule() { public void configure() { bind(String.class).annotatedWith(named("a")).toInstance("private"); bind(String.class).annotatedWith(named("b")).toInstance("exposed"); expose(String.class).annotatedWith(named("b")); } }); ExposedBinding<?> binding = (ExposedBinding<?>) injector.getBinding(Key.get(String.class, Names.named("b"))); assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class))), binding.getDependencies()); PrivateElements privateElements = binding.getPrivateElements(); assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class, named("b"))), privateElements.getExposedKeys()); assertContains(privateElements.getExposedSource(Key.get(String.class, named("b"))).toString(), PrivateModuleTest.class.getName(), ".configure(PrivateModuleTest.java:"); Injector privateInjector = privateElements.getInjector(); assertEquals("private", privateInjector.getInstance(Key.get(String.class, Names.named("a")))); }
@Override public Boolean visit(PrivateElements privateElements) { for (Key<?> key : privateElements.getExposedKeys()) { bindExposed(privateElements, key); } return false; // leave the private elements for the PrivateElementsProcessor to handle }
private <T> void bindExposed(PrivateElements privateElements, Key<T> key) { ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<>(key, privateElements); bindingData.addCreationListener(exposedKeyFactory); putBinding( new ExposedBindingImpl<T>( injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements)); }
public ExposedBindingImpl( InjectorImpl injector, Object source, Key<T> key, InternalFactory<T> factory, PrivateElements privateElements) { super(injector, key, source, factory, Scoping.UNSCOPED); this.privateElements = privateElements; }
@Override public String toString() { return MoreObjects.toStringHelper(PrivateElements.class) .add("exposedKeys", getExposedKeys()) .add("source", getSource()) .toString(); }
@Override public Boolean visit(PrivateElements privateElements) { InjectorShell.Builder builder = new InjectorShell.Builder().parent(injector).privateElements(privateElements); injectorShellBuilders.add(builder); return true; }
public void testSpiAccess() { Injector injector = Guice.createInjector( new PrivateModule() { @Override public void configure() { bind(String.class).annotatedWith(named("a")).toInstance("private"); bind(String.class).annotatedWith(named("b")).toInstance("exposed"); expose(String.class).annotatedWith(named("b")); } }); ExposedBinding<?> binding = (ExposedBinding<?>) injector.getBinding(Key.get(String.class, Names.named("b"))); assertEquals( ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class))), binding.getDependencies()); PrivateElements privateElements = binding.getPrivateElements(); assertEquals( ImmutableSet.<Key<?>>of(Key.get(String.class, named("b"))), privateElements.getExposedKeys()); assertContains( privateElements.getExposedSource(Key.get(String.class, named("b"))).toString(), PrivateModuleTest.class.getName(), getDeclaringSourcePart(getClass())); Injector privateInjector = privateElements.getInjector(); assertEquals("private", privateInjector.getInstance(Key.get(String.class, Names.named("a")))); }
@Override public Boolean visit(PrivateElements privateElements) { InjectorShell.Builder builder = new InjectorShell.Builder() .parent(injector) .privateElements(privateElements); injectorShellBuilders.add(builder); return true; }
@Override public Object visit(PrivateElements privateElements) { processElements(privateElements.getElements()); return super.visit(privateElements); }
@Override public Void visit(PrivateElements privateElements) { privateElements.getExposedKeys().forEach(binder::expose); return super.visit(privateElements); }
public Void visit(PrivateElements privateElements) { GinjectorBindings childCollection = children.next(); // Add information about the elements in the child ginjector to the child bindings // TODO(bchambers): Use the tree loggers more intelligently -- when visiting // a child bindings collection, we should create a new branch. This is slightly // complicated because we process in two stages -- once here where we // add explicit bindings (and record implicit dependencies), and again later // to resolve the implicit dependencies. GuiceElementVisitor childVisitor = guiceElementVisitorFactory.create(childCollection); childVisitor.visitElements(privateElements.getElements()); messages.addAll(childVisitor.getMessages()); // Add information about the exposed elements in child to the current binding collection for (Key<?> key : privateElements.getExposedKeys()) { ExposedChildBinding childBinding = bindingFactory.getExposedChildBinding(key, childCollection, Context.forElement(privateElements)); // The child must have an explicit binding or pin for anything it exposes. // // Note that this is correct only because the // GuiceElementVisitor runs before any synthetic bindings are // inserted into the GinjectorBindings (more specifically, // before implicit bindings are generated). Otherwise, // isBound() might return true for keys that weren't explicitly bound. // // If the above invariant is violated, the effect will be to // bypass this error in some cases. The offending key should // still generate an error, but it will not be as clearly // described. if (!(childCollection.isBound(key) || childCollection.isPinned(key))) { errorManager.logError( "Key %s was exposed from but not bound in %s. Did you forget to call bind()?", key, childCollection); } PrettyPrinter.log(logger, TreeLogger.TRACE, "Child binding for %s in %s: %s", key, bindings, childBinding); bindings.addBinding(key, childBinding); } return null; }
@Override public PrivateElements getPrivateElements() { return privateElements; }
ExposedKeyFactory(Key<T> key, PrivateElements privateElements) { this.key = key; this.privateElements = privateElements; }
private <T> void bindExposed(PrivateElements privateElements, Key<T> key) { ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<T>(key, privateElements); bindingData.addCreationListener(exposedKeyFactory); putBinding(new ExposedBindingImpl<T>( injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements)); }
public ExposedBindingImpl(InjectorImpl injector, Object source, Key<T> key, InternalFactory<T> factory, PrivateElements privateElements) { super(injector, key, source, factory, Scoping.UNSCOPED); this.privateElements = privateElements; }
public PrivateElements getPrivateElements() { return privateElements; }
@Override public String toString() { return Objects.toStringHelper(PrivateElements.class) .add("exposedKeys", getExposedKeys()) .add("source", getSource()) .toString(); }