@Override public Void visit(ExposedBinding<? extends T> binding) { final PrivateBinder privateBinder = this.binder.newPrivateBinder(); final Scoper scoper = new Scoper(privateBinder, scoping); for(Element element : binding.getPrivateElements().getElements()) { if(element instanceof Binding) { ((Binding) element).acceptTargetVisitor(scoper); } else { element.applyTo(privateBinder); } } for(Key key : binding.getPrivateElements().getExposedKeys()) { privateBinder.expose(key); } return null; }
@Override protected void configure() { binder().requireExplicitBindings(); List<Element> elements = Elements.getElements(modules); ElementAnalyzer analyzer = new ElementAnalyzer(binder()); for( Element element : elements ) { element.acceptVisitor(analyzer); } analyzer.throwErrorIfNeeded(); Set<Key<?>> external = analyzer.getExternalDependencies(); for( Key<?> key : external ) { bindExternal(key); } }
public Module build() { // record commands from the modules final List<Element> elements = Elements.getElements(modules); // rewrite the commands to insert interception return new Module() { public void configure(Binder binder) { ModuleRewriter rewriter = new ModuleRewriter(binder); rewriter.writeAll(elements); // fail if any interceptions were missing if (!tolerateUnmatchedInterceptions && !rewriter.keysIntercepted.equals(keysToIntercept)) { Set<Key<?>> keysNotIntercepted = Sets.newHashSet(); keysNotIntercepted.addAll(keysToIntercept); keysNotIntercepted.removeAll(rewriter.keysIntercepted); binder.addError("An explicit binding is required for " + "all intercepted keys, but was not found for '%s'", keysNotIntercepted); } } }; }
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(); }
/** Implementation of {@link OptionalBinderBinding#containsElement}. */ boolean containsElement(Element element) { // All of our bindings are ProviderInstanceBindings whose providers extend // RealOptionalBinderProviderWithDependencies and have 'this' as its binding selection. if (element instanceof ProviderInstanceBinding) { javax.inject.Provider<?> providerInstance = ((ProviderInstanceBinding<?>) element).getUserSuppliedProvider(); if (providerInstance instanceof RealOptionalBinderProviderWithDependencies) { return ((RealOptionalBinderProviderWithDependencies<?, ?>) providerInstance) .bindingSelection.equals(this); } } if (element instanceof Binding) { Key<?> elementKey = ((Binding) element).getKey(); // if it isn't one of the things we bound directly it might be an actual or default key return elementKey.equals(getKeyForActualBinding()) || elementKey.equals(getKeyForDefaultBinding()); } return false; // cannot match; }
private boolean containsElement(Element element) { if (entrySetBinder.containsElement(element)) { return true; } Key<?> key; if (element instanceof Binding) { key = ((Binding<?>) element).getKey(); } else { return false; // cannot match; } return key.equals(getMapKey()) || key.equals(getProviderMapKey()) || key.equals(getJavaxProviderMapKey()) || key.equals(getMultimapKey()) || key.equals(getProviderSetMultimapKey()) || key.equals(getJavaxProviderSetMultimapKey()) || key.equals(getProviderCollectionMultimapKey()) || key.equals(getJavaxProviderCollectionMultimapKey()) || key.equals(entrySetBinder.getSetKey()) || key.equals(getEntrySetJavaxProviderKey()) || matchesValueKey(key); }
public void process(InjectorImpl injector, List<Element> elements) { Errors errorsAnyElement = this.errors; this.injector = injector; try { for (Iterator<Element> i = elements.iterator(); i.hasNext(); ) { Element element = i.next(); this.errors = errorsAnyElement.withSource(element.getSource()); Boolean allDone = element.acceptVisitor(this); if (allDone) { i.remove(); } } } finally { this.errors = errorsAnyElement; this.injector = null; } }
private static Module extractScanners(Iterable<Element> elements) { final List<ModuleAnnotatedMethodScannerBinding> scanners = Lists.newArrayList(); ElementVisitor<Void> visitor = new DefaultElementVisitor<Void>() { @Override public Void visit(ModuleAnnotatedMethodScannerBinding binding) { scanners.add(binding); return null; } }; for (Element element : elements) { element.acceptVisitor(visitor); } return new AbstractModule() { @Override protected void configure() { for (ModuleAnnotatedMethodScannerBinding scanner : scanners) { scanner.applyTo(binder()); } } }; }
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(); }
default void installIn(Scoping scoping, Module... modules) { final Scoper scoper = new Scoper(this, scoping); for(Element element : Elements.getElements(modules)) { if(element instanceof Binding) { ((Binding) element).acceptTargetVisitor(scoper); } else { element.applyTo(this); } } }
public DependencyCollector processElements(Iterable<Element> elements) { final ElementVisitor visitor = new ElementVisitor(); for(Element element : elements) { element.acceptVisitor(visitor); } processImplicitBindings(); return this; }
public static <T> Optional<Binding<T>> findBinding(Iterable<? extends Element> elements, Key<T> key) { for(Element element : elements) { if(element instanceof Binding && key.equals(((Binding<?>) element).getKey())) { return Optional.of((Binding<T>) element); } } return Optional.empty(); }
private Module createModule() { List<Element> allElements = new LinkedList<>(); for (List<Element> moduleElements : modules.values()) { allElements.addAll(moduleElements); } ElementCollector collector = new ElementCollector(); for (ListIterator<Element> it = allElements.listIterator(allElements.size()); it.hasPrevious(); ) { it.previous().acceptVisitor(collector); } return Elements.getModule(collector.elements); }
public void visitElementsAndReportErrors(List<Element> elements) { visitElements(elements); // Capture any binding errors, any of which we treat as fatal. if (!messages.isEmpty()) { for (Message message : messages) { // tostring has both source and message so use that errorManager.logError(message.toString(), message.getCause()); } } }
private void visitElements(List<Element> elements) { // We take advantage of the fact that iterating over the PrivateElements should // happen in the same order that the modules were installed. We match each PrivateElements // up with the {@link GinjectorBindings} that were created in the adapter. children = bindings.getChildren().iterator(); for (Element element : elements) { element.acceptVisitor(this); } }
public void assertAllDependenciesDeclared() { List<Key> requiredKeys = new ArrayList<>(); List<Element> elements = Elements.getElements(module); for (Element element : elements) { element.acceptVisitor(new DefaultElementVisitor<Void>() { @Override public <T> Void visit(ProviderLookup<T> providerLookup) { // Required keys are the only ones with null injection points. if (providerLookup.getDependency().getInjectionPoint() == null) { requiredKeys.add(providerLookup.getKey()); } return null; } }); } Injector injector = Guice.createInjector(module, new AbstractModule() { @Override @SuppressWarnings("unchecked") protected void configure() { binder().disableCircularProxies(); binder().requireAtInjectOnConstructors(); binder().requireExactBindingAnnotations(); for (Key<?> key : requiredKeys) { bind((Key) key).toProvider(Providers.of(null)); } } }); injector.getAllBindings(); }
@Test public void testExtensionSpi() { List<Element> elements = Elements.getElements(new AbstractModule() { @Override protected void configure() { ContextSensitiveBinder contextualBinder = ContextSensitiveBinder.create(binder()); contextualBinder .bind(String.class) .annotatedWith(Names.named("key")) .toContextSensitiveProvider(SelfProvider.class); contextualBinder .bind(String.class) .annotatedWith(Names.named("instance")) .toContextSensitiveProvider(new SelfProvider()); } }); int passed = 0; for (Element element : elements) { if (element instanceof Binding) { if (visit(((Binding<?>)element))) { ++passed; } } } assertThat(passed, equalTo(2)); Injector injector = Guice.createInjector(Elements.getModule(elements)); assertThat(visit(injector.getBinding(new Key<String>(Names.named("key")) { })), is(true)); assertThat(visit(injector.getBinding(new Key<String>(Names.named("instance")) { })), is(true)); assertThat(visit(injector.getBinding(SelfProvider.class)), is(false)); }
@Test public void testExtensionSpi() { Module module = new AbstractModule() { @Override protected void configure() { // TODO: Expose the SPI for unqualified bindings LazyBinder.create(binder()) .bind(Abstract.class) .annotatedWith(Simple.class) .toProvider(CountingProvider.class); } }; List<Element> elements = Elements.getElements(module); int passed = 0; for (Element element : elements) { if (element instanceof Binding) { if (visit((Binding<?>)element)) { ++passed; } } } assertThat(passed, equalTo(1)); Injector injector = Guice.createInjector(Elements.getModule(elements)); assertThat(visit(injector.getBinding(new Key<Lazy<Abstract>>(Simple.class) { })), is(true)); assertThat(visit(injector.getBinding(new Key<Abstract>(Simple.class) { })), is(false)); }
public final void testSpiOnElements() { ServletSpiVisitor visitor = new ServletSpiVisitor(false); int count = 0; for (Element element : Elements.getElements(new Module())) { if (element instanceof Binding) { assertEquals(count++, ((Binding) element).acceptTargetVisitor(visitor)); } } validateVisitor(visitor); }
public final void testSpiOnElements() throws Exception { AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor(); Integer count = 0; for (Element element : Elements.getElements(new Module())) { if (element instanceof Binding) { assertEquals(count++, ((Binding<?>) element).acceptTargetVisitor(visitor)); } } validateVisitor(visitor); }
@Override public List<Element> getElements() { if (elements == null) { elements = ImmutableList.copyOf(elementsMutable); elementsMutable = null; } return elements; }
@Override public void applyTo(Binder binder) { PrivateBinder privateBinder = binder.withSource(source).newPrivateBinder(); for (Element element : getElements()) { element.applyTo(privateBinder); } getExposedKeys(); // ensure exposedKeysToSources is populated for (Map.Entry<Key<?>, Object> entry : exposedKeysToSources.entrySet()) { privateBinder.withSource(entry.getValue()).expose(entry.getKey()); } }
public AbstractBindingBuilder(Binder binder, List<Element> elements, Object source, Key<T> key) { this.binder = binder; this.elements = elements; this.position = elements.size(); this.binding = new UntargettedBindingImpl<>(source, key, Scoping.UNSCOPED); elements.add(position, this.binding); }
public void testConcurrentMutation_bindingsSameAtInjectorCreation() { // We initially bind two distinct lists final List<String> list1 = Lists.newArrayList("A"); final List<String> list2 = Lists.newArrayList("B"); Module module = new AbstractModule() { @Override protected void configure() { Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings); multibinder.addBinding().toInstance(list1); multibinder.addBinding().toInstance(list2); } }; List<Element> elements = Elements.getElements(module); // Now we change the lists so they compare equal, and create the injector. list1.add(1, "B"); list2.add(0, "A"); Injector injector = Guice.createInjector(Elements.getModule(elements)); // Now we change the lists again so they are once more different, and create the set. list1.remove("A"); list2.remove("B"); Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings)); // The set will contain just one of the two lists. // (In fact, it will be the first one we bound, but we don't promise that, so we won't test it.) assertTrue( ImmutableSet.of(ImmutableList.of("A")).equals(set) || ImmutableSet.of(ImmutableList.of("B")).equals(set)); }
/** Returns the subset of elements that have keys, indexed by them. */ private static Map<Key<?>, Binding<?>> index(Iterable<Element> elements) { ImmutableMap.Builder<Key<?>, Binding<?>> builder = ImmutableMap.builder(); for (Element element : elements) { if (element instanceof Binding) { builder.put(((Binding) element).getKey(), (Binding) element); } } return builder.build(); }
public void testElementsDeduplicate() { List<Element> elements = Elements.getElements( new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo), new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)); assertEquals(14, elements.size()); assertEquals(7, new LinkedHashSet<Element>(elements).size()); }
public void testDifferentBindingTypesFail() { List<Element> elements = Elements.getElements(new FailedModule(foo, pFoo, pclFoo, clFoo, cFoo)); // Make sure every combination of the elements with another element fails. // This ensures that duplication checks the kind of binding also. for (Element e1 : elements) { for (Element e2 : elements) { // if they're the same, this shouldn't fail. try { Guice.createInjector(Elements.getModule(Arrays.asList(e1, e2))); if (e1 != e2) { fail("must fail!"); } } catch (CreationException expected) { if (e1 != e2) { assertContains( expected.getMessage(), "A binding to " + Foo.class.getName() + " was already configured at " + FailedModule.class.getName(), "at " + FailedModule.class.getName()); } else { throw expected; } } } } }
public final void testSpiOnElements() { ServletSpiVisitor visitor = new ServletSpiVisitor(false); int count = 0; for(Element element : Elements.getElements(new Module())) { if(element instanceof Binding) { assertEquals(count++, ((Binding)element).acceptTargetVisitor(visitor)); } } validateVisitor(visitor); }
public final void testSpiOnElements() throws Exception { AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor(); Integer count = 0; for(Element element : Elements.getElements(new Module())) { if(element instanceof Binding) { assertEquals(count++, ((Binding<?>)element).acceptTargetVisitor(visitor)); } } validateVisitor(visitor); }
public void testConcurrentMutation_bindingsDiffentAtInjectorCreation() { // We initially bind two equal lists final List<String> list1 = Lists.newArrayList(); final List<String> list2 = Lists.newArrayList(); Module module = new AbstractModule() { @Override protected void configure() { Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings); multibinder.addBinding().toInstance(list1); multibinder.addBinding().toInstance(list2); } }; List<Element> elements = Elements.getElements(module); // Now we change the lists so they no longer match, and create the injector. list1.add("A"); list2.add("B"); Injector injector = Guice.createInjector(Elements.getModule(elements)); // Now we change the lists so they compare equal again, and create the set. list1.add(1, "B"); list2.add(0, "A"); try { injector.getInstance(Key.get(setOfListOfStrings)); fail(); } catch (ProvisionException e) { assertEquals(1, e.getErrorMessages().size()); assertContains( Iterables.getOnlyElement(e.getErrorMessages()).getMessage().toString(), "Set injection failed due to duplicated element \"[A, B]\""); } // Finally, we change the lists again so they are once more different, and ensure the set // contains both. list1.remove("A"); list2.remove("B"); Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings)); assertEquals(ImmutableSet.of(ImmutableList.of("A"), ImmutableList.of("B")), set); }
public void testConcurrentMutation_bindingsSameAtInjectorCreation() { // We initially bind two distinct lists final List<String> list1 = Lists.newArrayList("A"); final List<String> list2 = Lists.newArrayList("B"); Module module = new AbstractModule() { @Override protected void configure() { Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings); multibinder.addBinding().toInstance(list1); multibinder.addBinding().toInstance(list2); } }; List<Element> elements = Elements.getElements(module); // Now we change the lists so they compare equal, and create the injector. list1.add(1, "B"); list2.add(0, "A"); Injector injector = Guice.createInjector(Elements.getModule(elements)); // Now we change the lists again so they are once more different, and create the set. list1.remove("A"); list2.remove("B"); Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings)); // The set will contain just one of the two lists. // (In fact, it will be the first one we bound, but we don't promise that, so we won't test it.) assertTrue(ImmutableSet.of(ImmutableList.of("A")).equals(set) || ImmutableSet.of(ImmutableList.of("B")).equals(set)); }
public List<Element> getElements() { if (elements == null) { elements = ImmutableList.copyOf(elementsMutable); elementsMutable = null; } return elements; }