1b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin/** 2b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * Copyright (C) 2011 Google Inc. 3b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * 4b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * Licensed under the Apache License, Version 2.0 (the "License"); 5b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * you may not use this file except in compliance with the License. 6b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * You may obtain a copy of the License at 7b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * 8b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * http://www.apache.org/licenses/LICENSE-2.0 9b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * 10b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * Unless required by applicable law or agreed to in writing, software 11b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * distributed under the License is distributed on an "AS IS" BASIS, 12b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * See the License for the specific language governing permissions and 14b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * limitations under the License. 15b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin */ 16b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 17b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinpackage com.google.inject.servlet; 18b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 19b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport static com.google.inject.name.Names.named; 20b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport static java.lang.annotation.RetentionPolicy.RUNTIME; 21b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 22b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.common.collect.ImmutableMap; 23b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.AbstractModule; 24b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Binding; 25b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Guice; 26b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Injector; 27b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Key; 28b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Module; 29b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.PrivateModule; 30b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Provides; 31b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.ScopeAnnotation; 32b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Scopes; 33b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.Singleton; 34b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.name.Named; 35b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.spi.Element; 36b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.spi.Elements; 37b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.spi.PrivateElements; 38b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport com.google.inject.util.Providers; 39b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 40b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport junit.framework.TestCase; 41b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 42b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport java.lang.annotation.ElementType; 43b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport java.lang.annotation.Retention; 44b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport java.lang.annotation.Target; 45b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport java.util.List; 46b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinimport java.util.Map; 47b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 48b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin/** 49b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * Tests for {@link ServletScopes}. 50b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * 51b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin * @author forster@google.com (Mike Forster) 52b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin */ 53b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlinpublic class ServletScopesTest extends TestCase { 54b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin public void testIsRequestScopedPositive() { 55b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> a = Key.get(String.class, named("A")); 56b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> b = Key.get(String.class, named("B")); 57b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> c = Key.get(String.class, named("C")); 58b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> d = Key.get(String.class, named("D")); 59b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<Object> e = Key.get(Object.class, named("E")); 60b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> f = Key.get(String.class, named("F")); 61b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> g = Key.get(String.class, named("G")); 62b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 63b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin Module requestScopedBindings = new AbstractModule() { 64b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Override 65b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin protected void configure() { 66b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(a).to(b); 67b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(b).to(c); 68b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(c).toProvider(Providers.of("c")).in(ServletScopes.REQUEST); 69b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(d).toProvider(Providers.of("d")).in(RequestScoped.class); 70b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(e).to(AnnotatedRequestScopedClass.class); 71b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin install(new PrivateModule() { 72b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Override 73b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin protected void configure() { 74b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(f).toProvider(Providers.of("f")).in(RequestScoped.class); 75b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin expose(f); 76b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 77b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin }); 78b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 79b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 80b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Provides 81b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Named("G") 82b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @RequestScoped 83b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin String provideG() { 84b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin return "g"; 85b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 86b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin }; 87b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 88b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @SuppressWarnings("unchecked") // we know the module contains only bindings 89b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin List<Element> moduleBindings = Elements.getElements(requestScopedBindings); 90b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin ImmutableMap<Key<?>, Binding<?>> map = indexBindings(moduleBindings); 91b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin // linked bindings are not followed by modules 92b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(a))); 93b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(b))); 94b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(map.get(c))); 95b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(map.get(d))); 96b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin // annotated classes are not followed by modules 97b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(e))); 98b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(map.get(f))); 99b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(map.get(g))); 100b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 101b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin Injector injector = Guice.createInjector(requestScopedBindings, new ServletModule()); 102b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(a))); 103b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(b))); 104b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(c))); 105b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(d))); 106b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(e))); 107b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(f))); 108b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertTrue(ServletScopes.isRequestScoped(injector.getBinding(g))); 109b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 110b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 111b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin public void testIsRequestScopedNegative() { 112b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> a = Key.get(String.class, named("A")); 113b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> b = Key.get(String.class, named("B")); 114b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> c = Key.get(String.class, named("C")); 115b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> d = Key.get(String.class, named("D")); 116b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> e = Key.get(String.class, named("E")); 117b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> f = Key.get(String.class, named("F")); 118b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> g = Key.get(String.class, named("G")); 119b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> h = Key.get(String.class, named("H")); 120b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> i = Key.get(String.class, named("I")); 121b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin final Key<String> j = Key.get(String.class, named("J")); 122b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 123b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin Module requestScopedBindings = new AbstractModule() { 124b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Override 125b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin protected void configure() { 126b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(a).to(b); 127b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(b).to(c); 128b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE); 129b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(d).toInstance("d"); 130b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(e).toProvider(Providers.of("e")).asEagerSingleton(); 131b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(f).toProvider(Providers.of("f")).in(Scopes.SINGLETON); 132b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(g).toProvider(Providers.of("g")).in(Singleton.class); 133b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(h).toProvider(Providers.of("h")).in(CustomScoped.class); 134b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bindScope(CustomScoped.class, Scopes.NO_SCOPE); 135b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin install(new PrivateModule() { 136b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Override 137b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin protected void configure() { 138b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin bind(i).toProvider(Providers.of("i")).in(CustomScoped.class); 139b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin expose(i); 140b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 141b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin }); 142b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 143b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 144b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Provides 145b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Named("J") 146b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @CustomScoped 147b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin String provideJ() { 148b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin return "j"; 149b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 150b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin }; 151b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 152b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @SuppressWarnings("unchecked") // we know the module contains only bindings 153b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin List<Element> moduleBindings = Elements.getElements(requestScopedBindings); 154b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin ImmutableMap<Key<?>, Binding<?>> map = indexBindings(moduleBindings); 155b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(a))); 156b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(b))); 157b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(c))); 158b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(d))); 159b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(e))); 160b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(f))); 161b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(g))); 162b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(h))); 163b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(i))); 164b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(map.get(j))); 165b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 166b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin Injector injector = Guice.createInjector(requestScopedBindings); 167b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(a))); 168b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(b))); 169b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(c))); 170b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(d))); 171b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(e))); 172b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(f))); 173b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(g))); 174b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(h))); 175b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(i))); 176b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin assertFalse(ServletScopes.isRequestScoped(injector.getBinding(j))); 177b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 178b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 179b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @RequestScoped 180b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin static class AnnotatedRequestScopedClass {} 181b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 182b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Target({ ElementType.TYPE, ElementType.METHOD }) 183b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @Retention(RUNTIME) 184b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin @ScopeAnnotation 185b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin private @interface CustomScoped {} 186b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin 187b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin private ImmutableMap<Key<?>, Binding<?>> indexBindings(Iterable<Element> elements) { 188b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin ImmutableMap.Builder<Key<?>, Binding<?>> builder = ImmutableMap.builder(); 189b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin for (Element element : elements) { 190b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin if (element instanceof Binding) { 191b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin Binding<?> binding = (Binding<?>) element; 192b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin builder.put(binding.getKey(), binding); 193b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } else if (element instanceof PrivateElements) { 194b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin PrivateElements privateElements = (PrivateElements) element; 195b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin Map<Key<?>, Binding<?>> privateBindings = indexBindings(privateElements.getElements()); 196b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin for (Key<?> exposed : privateElements.getExposedKeys()) { 197b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin builder.put(exposed, privateBindings.get(exposed)); 198b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 199b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 200b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 201b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin return builder.build(); 202b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin } 203b2f558228f0b812a38a0c2407baf5826b452cb2cSam Berlin} 204