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