Author: limpbizkit
Date: Mon Jun 22 20:16:48 2009
New Revision: 1033
Modified:
trunk/servlet/src/com/google/inject/servlet/FilterDefinition.java
trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
trunk/servlet/src/com/google/inject/servlet/ServletScopes.java
trunk/src/com/google/inject/Scopes.java
trunk/src/com/google/inject/internal/LinkedBindingImpl.java
trunk/test/com/google/inject/ScopesTest.java
Log:
New API: Scopes.isSingleton(Binding)
The only thing interesting about this API is that I downcast the binding to
its internal type in order to follow linked bindings.
Modified: trunk/servlet/src/com/google/inject/servlet/FilterDefinition.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/FilterDefinition.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/FilterDefinition.java Mon
Jun 22 20:16:48 2009
@@ -17,8 +17,8 @@
import com.google.inject.Injector;
import com.google.inject.Key;
+import com.google.inject.Scopes;
import com.google.inject.internal.Iterators;
-import static com.google.inject.servlet.ServletScopes.isSingletonBinding;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
@@ -63,7 +63,7 @@
Set<Filter> initializedSoFar) throws ServletException {
// This absolutely must be a singleton, and so is only initialized
once.
- if (!isSingletonBinding(injector.getBinding(filterKey))) {
+ if (!Scopes.isSingleton(injector.getBinding(filterKey))) {
throw new ServletException("Filters must be bound as singletons. "
+ filterKey + " was not bound in singleton scope.");
}
Modified: trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java Mon
Jun 22 20:16:48 2009
@@ -17,8 +17,8 @@
import com.google.inject.Injector;
import com.google.inject.Key;
+import com.google.inject.Scopes;
import com.google.inject.internal.Iterators;
-import static com.google.inject.servlet.ServletScopes.isSingletonBinding;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
@@ -66,7 +66,7 @@
Set<HttpServlet> initializedSoFar) throws ServletException {
// This absolutely must be a singleton, and so is only initialized
once.
- if (!isSingletonBinding(injector.getBinding(servletKey))) {
+ if (!Scopes.isSingleton(injector.getBinding(servletKey))) {
throw new ServletException("Servlets must be bound as singletons. "
+ servletKey + " was not bound in singleton scope.");
}
Modified: trunk/servlet/src/com/google/inject/servlet/ServletScopes.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/ServletScopes.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/ServletScopes.java Mon Jun
22 20:16:48 2009
@@ -16,15 +16,9 @@
package com.google.inject.servlet;
-import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
-import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.spi.DefaultBindingScopingVisitor;
-import java.lang.annotation.Annotation;
-import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -97,36 +91,4 @@
return "ServletScopes.SESSION";
}
};
-
- static boolean isSingletonBinding(Binding<?> binding) {
- final AtomicBoolean isSingleton = new AtomicBoolean(true);
- binding.acceptScopingVisitor(new DefaultBindingScopingVisitor<Void>() {
- @Override
- public Void visitNoScoping() {
- isSingleton.set(false);
-
- return null;
- }
-
- @Override
- public Void visitScopeAnnotation(Class<? extends Annotation>
scopeAnnotation) {
- if (null != scopeAnnotation
&& !Singleton.class.equals(scopeAnnotation)) {
- isSingleton.set(false);
- }
-
- return null;
- }
-
- @Override
- public Void visitScope(Scope scope) {
- if (null != scope && !Scopes.SINGLETON.equals(scope)) {
- isSingleton.set(false);
- }
-
- return null;
- }
- });
-
- return isSingleton.get();
- }
}
Modified: trunk/src/com/google/inject/Scopes.java
==============================================================================
--- trunk/src/com/google/inject/Scopes.java (original)
+++ trunk/src/com/google/inject/Scopes.java Mon Jun 22 20:16:48 2009
@@ -17,6 +17,9 @@
package com.google.inject;
import com.google.inject.internal.InjectorBuilder;
+import com.google.inject.internal.LinkedBindingImpl;
+import com.google.inject.spi.BindingScopingVisitor;
+import java.lang.annotation.Annotation;
/**
* Built-in scope implementations.
@@ -86,4 +89,49 @@
return "Scopes.NO_SCOPE";
}
};
+
+ /**
+ * Returns true if {...@code binding} is singleton-scoped. If the binding
is a {...@link
+ * com.google.inject.spi.LinkedKeyBinding linked key binding} and
belongs to an injector (ie. it
+ * was retrieved via {...@link Injector#getBinding Injector.getBinding()}),
then this method will
+ * also true if the target binding is singleton-scoped.
+ *
+ * @since 2.1
+ */
+ public static boolean isSingleton(Binding<?> binding) {
+ do {
+ boolean singleton = binding.acceptScopingVisitor(new
BindingScopingVisitor<Boolean>() {
+ public Boolean visitNoScoping() {
+ return false;
+ }
+
+ public Boolean visitScopeAnnotation(Class<? extends Annotation>
scopeAnnotation) {
+ return Singleton.class == scopeAnnotation;
+ }
+
+ public Boolean visitScope(Scope scope) {
+ return scope == Scopes.SINGLETON;
+ }
+
+ public Boolean visitEagerSingleton() {
+ return true;
+ }
+ });
+
+ if (singleton) {
+ return true;
+ }
+
+ if (binding instanceof LinkedBindingImpl) {
+ LinkedBindingImpl<?> linkedBinding = (LinkedBindingImpl) binding;
+ Injector injector = (Injector) linkedBinding.getInjector();
+ if (injector != null) {
+ binding = injector.getBinding(linkedBinding.getLinkedKey());
+ continue;
+ }
+ }
+
+ return false;
+ } while (true);
+ }
}
Modified: trunk/src/com/google/inject/internal/LinkedBindingImpl.java
==============================================================================
--- trunk/src/com/google/inject/internal/LinkedBindingImpl.java (original)
+++ trunk/src/com/google/inject/internal/LinkedBindingImpl.java Mon Jun 22
20:16:48 2009
@@ -21,7 +21,7 @@
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.LinkedKeyBinding;
-final class LinkedBindingImpl<T> extends BindingImpl<T> implements
LinkedKeyBinding<T> {
+public final class LinkedBindingImpl<T> extends BindingImpl<T> implements
LinkedKeyBinding<T> {
final Key<? extends T> targetKey;
Modified: trunk/test/com/google/inject/ScopesTest.java
==============================================================================
--- trunk/test/com/google/inject/ScopesTest.java (original)
+++ trunk/test/com/google/inject/ScopesTest.java Mon Jun 22 20:16:48 2009
@@ -17,7 +17,13 @@
package com.google.inject;
import static com.google.inject.Asserts.assertContains;
+import com.google.inject.internal.ImmutableMap;
import com.google.inject.internal.Maps;
+import com.google.inject.name.Named;
+import static com.google.inject.name.Names.named;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.Elements;
+import com.google.inject.util.Providers;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -441,5 +447,103 @@
}
};
}
+ }
+
+ public void testIsSingletonPositive() {
+ final Key<String> a = Key.get(String.class, named("A"));
+ final Key<String> b = Key.get(String.class, named("B"));
+ final Key<String> c = Key.get(String.class, named("C"));
+ final Key<String> d = Key.get(String.class, named("D"));
+ final Key<String> e = Key.get(String.class, named("E"));
+ final Key<String> f = Key.get(String.class, named("F"));
+ final Key<String> g = Key.get(String.class, named("G"));
+ final Key<Object> h = Key.get(Object.class, named("H"));
+
+ Module singletonBindings = new AbstractModule() {
+ protected void configure() {
+ bind(a).to(b);
+ bind(b).to(c);
+ bind(c).toProvider(Providers.of("c")).in(Scopes.SINGLETON);
+ bind(d).toInstance("d");
+ bind(e).toProvider(Providers.of("e")).asEagerSingleton();
+ bind(f).toProvider(Providers.of("f")).in(Singleton.class);
+ bind(h).to(AnnotatedSingleton.class);
+ }
+
+ @Provides @Named("G") @Singleton String provideG() {
+ return "g";
+ }
+ };
+
+ @SuppressWarnings("unchecked") // we know the module contains only
bindings
+ List<Element> moduleBindings = Elements.getElements(singletonBindings);
+ ImmutableMap<Key<?>, Binding<?>> map = indexBindings(moduleBindings);
+ assertFalse(Scopes.isSingleton(map.get(a))); // linked bindings are
not followed by modules
+ assertFalse(Scopes.isSingleton(map.get(b)));
+ assertTrue(Scopes.isSingleton(map.get(c)));
+ assertTrue(Scopes.isSingleton(map.get(d)));
+ assertTrue(Scopes.isSingleton(map.get(e)));
+ assertTrue(Scopes.isSingleton(map.get(f)));
+ assertTrue(Scopes.isSingleton(map.get(g)));
+ assertFalse(Scopes.isSingleton(map.get(h))); // annotated classes are
not followed by modules
+
+ Injector injector = Guice.createInjector(singletonBindings);
+ assertTrue(Scopes.isSingleton(injector.getBinding(a)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(b)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(c)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(d)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(e)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(f)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(g)));
+ assertTrue(Scopes.isSingleton(injector.getBinding(h)));
+ }
+
+ public void testIsSingletonNegative() {
+ final Key<String> a = Key.get(String.class, named("A"));
+ final Key<String> b = Key.get(String.class, named("B"));
+ final Key<String> c = Key.get(String.class, named("C"));
+ final Key<String> d = Key.get(String.class, named("D"));
+ final Key<String> e = Key.get(String.class, named("E"));
+
+ Module singletonBindings = new AbstractModule() {
+ protected void configure() {
+ bind(a).to(b);
+ bind(b).to(c);
+ bind(c).toProvider(Providers.of("c")).in(Scopes.NO_SCOPE);
+ bind(d).toProvider(Providers.of("d")).in(CustomScoped.class);
+ bindScope(CustomScoped.class, Scopes.NO_SCOPE);
+ }
+
+ @Provides @Named("E") @CustomScoped String provideE() {
+ return "e";
+ }
+ };
+
+ @SuppressWarnings("unchecked") // we know the module contains only
bindings
+ List<Element> moduleBindings = Elements.getElements(singletonBindings);
+ ImmutableMap<Key<?>, Binding<?>> map = indexBindings(moduleBindings);
+ assertFalse(Scopes.isSingleton(map.get(a)));
+ assertFalse(Scopes.isSingleton(map.get(b)));
+ assertFalse(Scopes.isSingleton(map.get(c)));
+ assertFalse(Scopes.isSingleton(map.get(d)));
+ assertFalse(Scopes.isSingleton(map.get(e)));
+
+ Injector injector = Guice.createInjector(singletonBindings);
+ assertFalse(Scopes.isSingleton(injector.getBinding(a)));
+ assertFalse(Scopes.isSingleton(injector.getBinding(b)));
+ assertFalse(Scopes.isSingleton(injector.getBinding(c)));
+ assertFalse(Scopes.isSingleton(injector.getBinding(d)));
+ assertFalse(Scopes.isSingleton(injector.getBinding(e)));
+ }
+
+ 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);
+ }
+ }
+ return builder.build();
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---