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
-~----------~----~----~----~------~----~------~--~---

Reply via email to