@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); } } }; }
public void testServletModuleReuse() { Module module = new Module(); Elements.getElements(module); // use the module once (to, say, introspect bindings) Injector injector = Guice.createInjector(module); // use it again. Visitor visitor = new Visitor(); // Validate only a single servlet binding & a single filter binding exist. for (Binding<?> binding : injector.getAllBindings().values()) { binding.acceptTargetVisitor(visitor); } assertEquals( "wrong linked servlets: " + visitor.linkedServlets, 0, visitor.linkedServlets.size()); assertEquals("wrong linked filters: " + visitor.linkedFilters, 0, visitor.linkedFilters.size()); assertEquals( "wrong instance servlets: " + visitor.instanceServlets, 1, visitor.instanceServlets.size()); assertEquals( "wrong instance filters: " + visitor.instanceFilters, 1, visitor.instanceFilters.size()); }
@SuppressWarnings("rawtypes") public void testGetEntries() { List<com.google.inject.spi.Element> elements = Elements.getElements(new MapBinderWithTwoEntriesModule()); // Get the MapBinderBinding MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements); // Execute the call to getEntries List<Map.Entry<?, Binding<?>>> mapEntries = mapBinderBinding.getEntries(elements); // Assert on the results Map.Entry<?, Binding<?>> firstEntry = mapEntries.get(0); assertEquals("keyOne", firstEntry.getKey()); Binding<?> firstBinding = firstEntry.getValue(); assertEquals("valueOne", ((InstanceBinding) firstBinding).getInstance()); Map.Entry<?, Binding<?>> secondEntry = mapEntries.get(1); assertEquals("keyTwo", secondEntry.getKey()); Binding<?> secondBinding = secondEntry.getValue(); assertEquals("valueTwo", ((InstanceBinding) secondBinding).getInstance()); }
/** Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}. */ public void testBindingKeysFixedOnReturnFromGetElements() { final List<String> list = Lists.newArrayList(); Module m = new AbstractModule() { @Override protected void configure() { OptionalBinder<List<String>> b = OptionalBinder.newOptionalBinder(binder(), listOfStrings); b.setDefault().toInstance(list); list.add("A"); list.add("B"); } }; InstanceBinding<?> binding = Iterables.getOnlyElement(Iterables.filter(Elements.getElements(m), InstanceBinding.class)); Key<?> keyBefore = binding.getKey(); assertEquals(listOfStrings, keyBefore.getTypeLiteral()); list.add("C"); Key<?> keyAfter = binding.getKey(); assertSame(keyBefore, keyAfter); }
/** Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}. */ public void testBindingKeysFixedOnReturnFromGetElements() { final List<String> list = Lists.newArrayList(); Module ab = new AbstractModule() { @Override protected void configure() { Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings); multibinder.addBinding().toInstance(list); list.add("A"); list.add("B"); } }; InstanceBinding<?> binding = Iterables.getOnlyElement(Iterables.filter(Elements.getElements(ab), InstanceBinding.class)); Key<?> keyBefore = binding.getKey(); assertEquals(listOfStrings, keyBefore.getTypeLiteral()); list.add("C"); Key<?> keyAfter = binding.getKey(); assertSame(keyBefore, keyAfter); }
@Override protected void configure() { // InstanceBinding bind(Foo.class).annotatedWith(named("instance")).toInstance(foo); // ProviderInstanceBinding bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo); // ProviderKeyBinding bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo); // LinkedKeyBinding bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo); // UntargettedBinding / ConstructorBinding bind(FooImpl.class); // ConstructorBinding bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo); // ProviderMethod // (reconstructed from an Element to ensure it doesn't get filtered out // by deduplicating Modules) install(Elements.getModule(Elements.getElements(new SimpleProviderModule()))); }
public void testServletModuleReuse() { Module module = new Module(); Elements.getElements(module); // use the module once (to, say, introspect bindings) Injector injector = Guice.createInjector(module); // use it again. Visitor visitor = new Visitor(); // Validate only a single servlet binding & a single filter binding exist. for(Binding<?> binding : injector.getAllBindings().values()) { binding.acceptTargetVisitor(visitor); } assertEquals("wrong linked servlets: " + visitor.linkedServlets, 0, visitor.linkedServlets.size()); assertEquals("wrong linked filters: " + visitor.linkedFilters, 0, visitor.linkedFilters.size()); assertEquals("wrong instance servlets: " + visitor.instanceServlets, 1, visitor.instanceServlets.size()); assertEquals("wrong instance filters: " + visitor.instanceFilters, 1, visitor.instanceFilters.size()); }
/** * Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}. */ public void testBindingKeysFixedOnReturnFromGetElements() { final List<String> list = Lists.newArrayList(); Module m = new AbstractModule() { @Override protected void configure() { OptionalBinder<List<String>> b = OptionalBinder.newOptionalBinder(binder(), listOfStrings); b.setDefault().toInstance(list); list.add("A"); list.add("B"); } }; InstanceBinding<?> binding = Iterables.getOnlyElement( Iterables.filter(Elements.getElements(m), InstanceBinding.class)); Key<?> keyBefore = binding.getKey(); assertEquals(listOfStrings, keyBefore.getTypeLiteral()); assertFalse(RehashableKeys.Keys.needsRehashing(keyBefore)); list.add("C"); Key<?> keyAfter = binding.getKey(); assertSame(keyBefore, keyAfter); assertTrue(RehashableKeys.Keys.needsRehashing(keyAfter)); }
/** * Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}. */ public void testBindingKeysFixedOnReturnFromGetElements() { final List<String> list = Lists.newArrayList(); Module ab = new AbstractModule() { @Override protected void configure() { Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings); multibinder.addBinding().toInstance(list); list.add("A"); list.add("B"); } }; InstanceBinding<?> binding = Iterables.getOnlyElement( Iterables.filter(Elements.getElements(ab), InstanceBinding.class)); Key<?> keyBefore = binding.getKey(); assertEquals(listOfStrings, keyBefore.getTypeLiteral()); assertFalse(RehashableKeys.Keys.needsRehashing(keyBefore)); list.add("C"); Key<?> keyAfter = binding.getKey(); assertSame(keyBefore, keyAfter); assertTrue(RehashableKeys.Keys.needsRehashing(keyAfter)); }
protected void configure() { // InstanceBinding bind(Foo.class).annotatedWith(named("instance")).toInstance(foo); // ProviderInstanceBinding bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo); // ProviderKeyBinding bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo); // LinkedKeyBinding bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo); // UntargettedBinding / ConstructorBinding bind(FooImpl.class); // ConstructorBinding bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo); // ProviderMethod // (reconstructed from an Element to ensure it doesn't get filtered out // by deduplicating Modules) install(Elements.getModule(Elements.getElements(new SimpleProviderModule()))); }
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); } } }
@Before public void setUp() throws Exception { module = new EndpointsModule() { @Override protected void configureServlets() { super.configureServlets(); configureEndpoints(URL_PATTERN, INIT_PARAMETERS, true); } }; Elements.getElements(module); }
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 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)); }
@Override protected boolean matchesSafely(Module item, Description mismatchDescription) { // Pass through the SPI to make sure the Module is atomic regardless of its equals() implementation // This ensures atomicity even through Modules.override(), for example Module copy1 = Elements.getModule(Elements.getElements(item)); Module copy2 = Elements.getModule(Elements.getElements(item)); try { Guice.createInjector(copy1, copy2); return true; } catch (CreationException e) { mismatchDescription.appendValue(e); return 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); }
@SuppressWarnings("rawtypes") public void testGetEntriesWithDuplicateKeys() { // Set up the module Module module = new AbstractModule() { @Override protected void configure() { MapBinder<String, String> mapBinder = MapBinder.newMapBinder(binder(), String.class, String.class); mapBinder.addBinding("A").toInstance("a1"); mapBinder.addBinding("A").toInstance("a2"); mapBinder.permitDuplicates(); } }; // Get the MapBinderBinding List<com.google.inject.spi.Element> elements = Elements.getElements(module); MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements); // Execute the call to getEntries List<Map.Entry<?, Binding<?>>> mapEntries = mapBinderBinding.getEntries(elements); // Assert on the results Map.Entry<?, Binding<?>> firstEntry = mapEntries.get(0); assertEquals("A", firstEntry.getKey()); Binding<?> firstBinding = firstEntry.getValue(); assertEquals("a1", ((InstanceBinding) firstBinding).getInstance()); Map.Entry<?, Binding<?>> secondEntry = mapEntries.get(1); assertEquals("A", secondEntry.getKey()); Binding<?> secondBinding = secondEntry.getValue(); assertEquals("a2", ((InstanceBinding) secondBinding).getInstance()); }
@SuppressWarnings("rawtypes") public void testGetEntriesWithDuplicateValues() { // Set up the module Module module = new AbstractModule() { @Override protected void configure() { MapBinder<String, String> mapBinder = MapBinder.newMapBinder(binder(), String.class, String.class); mapBinder.addBinding("A").toInstance("a"); mapBinder.addBinding("A").toInstance("a"); } }; // Get the MapBinderBinding List<com.google.inject.spi.Element> elements = Elements.getElements(module); MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements); // Execute the call to getEntries List<Map.Entry<?, Binding<?>>> mapEntries = mapBinderBinding.getEntries(elements); // Assert on the results Map.Entry<?, Binding<?>> firstEntry = mapEntries.get(0); assertEquals("A", firstEntry.getKey()); Binding<?> firstBinding = firstEntry.getValue(); assertEquals("a", ((InstanceBinding) firstBinding).getInstance()); Map.Entry<?, Binding<?>> secondEntry = mapEntries.get(1); assertEquals("A", secondEntry.getKey()); Binding<?> secondBinding = secondEntry.getValue(); assertEquals("a", ((InstanceBinding) secondBinding).getInstance()); }
@SuppressWarnings("rawtypes") public void testGetEntriesMissingProviderMapEntry() { List<com.google.inject.spi.Element> elements = Lists.newArrayList(Elements.getElements(new MapBinderWithTwoEntriesModule())); // Get the MapBinderBinding MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements); // Remove the ProviderMapEntry for "a" from the elements com.google.inject.spi.Element providerMapEntryForA = getProviderMapEntry("keyOne", elements); boolean removeSuccessful = elements.remove(providerMapEntryForA); assertTrue(removeSuccessful); // Execute the call to getEntries, we expect it to fail try { mapBinderBinding.getEntries(elements); fail(); } catch (IllegalArgumentException expected) { assertContains( expected.getMessage(), "Expected a 1:1 mapping from map keys to values.", "Found these Bindings that were missing an associated entry:", "java.lang.String", "bound at:", "MapBinderWithTwoEntriesModule"); } }
@SuppressWarnings("rawtypes") public void testGetEntriesMissingBindingForValue() { List<com.google.inject.spi.Element> elements = Lists.newArrayList(Elements.getElements(new MapBinderWithTwoEntriesModule())); // Get the MapBinderBinding MapBinderBinding<?> mapBinderBinding = getMapBinderBinding(elements); // Remove the ProviderMapEntry for "a" from the elements com.google.inject.spi.Element bindingForA = getInstanceBindingForValue("valueOne", elements); boolean removeSuccessful = elements.remove(bindingForA); assertTrue(removeSuccessful); // Execute the call to getEntries, we expect it to fail try { mapBinderBinding.getEntries(elements); fail(); } catch (IllegalArgumentException expected) { assertContains( expected.getMessage(), "Expected a 1:1 mapping from map keys to values.", "Found these map keys without a corresponding value:", "keyOne", "bound at:", "MapBinderWithTwoEntriesModule"); } }
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 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 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; } } } } }