Author: dhanji
Date: Tue Jan  6 04:48:44 2009
New Revision: 801

Added:
    trunk/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java
Modified:
    trunk/servlet/src/com/google/inject/servlet/FilterDefinition.java
    trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
    trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java
    trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
    trunk/servlet/src/com/google/inject/servlet/ServletScopes.java
    trunk/servlet/test/com/google/inject/servlet/AllTests.java
    trunk/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
     
trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
    trunk/servlet/test/com/google/inject/servlet/FilterPipelineTest.java
     
trunk/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
     
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
    trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
     
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
     
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
    trunk/servlet/test/com/google/inject/servlet/ServletTest.java
     
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
     
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java

Log:
Added invalid scope (non-singleton) error checking and tests. Should pretty  
much be the last Guice Servlet 2.0 feature needed before release.

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   Tue  
Jan  6 04:48:44 2009
@@ -18,6 +18,7 @@
  import com.google.common.collect.Iterators;
  import com.google.inject.Injector;
  import com.google.inject.Key;
+import static com.google.inject.servlet.ServletScopes.isSingletonBinding;
  import java.io.IOException;
  import java.util.Collections;
  import java.util.Enumeration;
@@ -58,7 +59,12 @@
    }

    public void init(final ServletContext servletContext, Injector injector)  
throws ServletException {
-    //TODO validate that the filter is bound as a singleton, to match with  
servlet spec idiom
+    // This absolutely must be a singleton, and so is only initialized  
once.
+    if (!isSingletonBinding(injector.getBinding(filterKey))) {
+      throw new ServletException("Filters must be bound as singletons. "
+        + filterKey + " was not bound in singleton scope.");
+    }
+
      Filter filter = injector.getInstance(filterKey);
      this.filter.set(filter);


Modified:  
trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java       
 
(original)
+++ trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java       
 
Tue Jan  6 04:48:44 2009
@@ -73,6 +73,7 @@

      public void through(Class<? extends Filter> filterKey,
          Map<String, String> contextParams) {
+
        // Careful you don't accidentally make this method recursive, thank  
you IntelliJ IDEA!
        through(Key.get(filterKey), contextParams);
      }

Modified: trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java        
(original)
+++ trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java        Tue Jan 
 6  
04:48:44 2009
@@ -77,7 +77,7 @@

      // Multiple injectors with Servlet pipelines?!
      // We don't throw an exception in DEVELOPMENT stage, to allow for  
legacy
-    // tests that don't have a tearDown that calls  
GuiceFilter#clearPipeline().
+    // tests that don't have a tearDown that calls GuiceFilter#reset().
      if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
        if (Stage.PRODUCTION.equals(stage)) {
          throw new RuntimeException(MULTIPLE_INJECTORS_ERROR);
@@ -91,8 +91,8 @@
    }

    //VisibleForTesting
-  static void clearPipeline() {
-    pipeline = null;
+  static void reset() {
+    pipeline = new DefaultFilterPipeline();
    }

    public void doFilter(ServletRequest servletRequest,
@@ -175,7 +175,7 @@
        pipeline.destroyPipeline();

      } finally {
-      clearPipeline();
+      reset();
        servletContext.clear();
      }
    }

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  Tue  
Jan  6 04:48:44 2009
@@ -18,6 +18,7 @@
  import com.google.common.collect.Iterators;
  import com.google.inject.Injector;
  import com.google.inject.Key;
+import static com.google.inject.servlet.ServletScopes.isSingletonBinding;
  import java.io.IOException;
  import java.util.Collections;
  import java.util.Enumeration;
@@ -61,7 +62,12 @@
    }

    public void init(final ServletContext servletContext, Injector injector)  
throws ServletException {
-    //TODO(dhanji): this absolutely must be a singleton, and so is only  
initialized once
+    // This absolutely must be a singleton, and so is only initialized  
once.
+    if (!isSingletonBinding(injector.getBinding(servletKey))) {
+      throw new ServletException("Servlets must be bound as singletons. "
+        + servletKey + " was not bound in singleton scope.");
+    }
+
      HttpServlet httpServlet = injector.getInstance(servletKey);
      this.httpServlet.set(httpServlet);


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      Tue Jan 
  
6 04:48:44 2009
@@ -16,9 +16,15 @@

  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;

@@ -91,4 +97,36 @@
        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/servlet/test/com/google/inject/servlet/AllTests.java
==============================================================================
--- trunk/servlet/test/com/google/inject/servlet/AllTests.java  (original)
+++ trunk/servlet/test/com/google/inject/servlet/AllTests.java  Tue Jan  6  
04:48:44 2009
@@ -39,6 +39,7 @@
      suite.addTestSuite(ServletDefinitionPathsTest.class);
      suite.addTestSuite(ServletPipelineRequestDispatcherTest.class);
      suite.addTestSuite(ServletDispatchIntegrationTest.class);
+    suite.addTestSuite(InvalidScopeBindingTest.class);

      // Varargs URL mapping tests.
      suite.addTestSuite(VarargsFilterDispatchIntegrationTest.class);

Modified:  
trunk/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
==============================================================================
--- trunk/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java      
 
(original)
+++ trunk/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java      
 
Tue Jan  6 04:48:44 2009
@@ -1,16 +1,25 @@
  package com.google.inject.servlet;

+import com.google.inject.Binding;
  import com.google.inject.Injector;
  import com.google.inject.Key;
-import static org.easymock.EasyMock.*;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
  import java.io.IOException;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Map;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
  import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;

  /**
   * Tests the lifecycle of the encapsulated {...@link FilterDefinition} class.
@@ -24,7 +33,13 @@
      Injector injector = createMock(Injector.class);

      final MockFilter mockFilter = new MockFilter();
-     
expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
+
+    expect(injector.getBinding(Key.get(Filter.class)))
+        .andReturn(createMock(Binding.class));
+
+    expect(injector.getInstance(Key.get(Filter.class)))
+        .andReturn(mockFilter)
+        .anyTimes();

      replay(injector);

@@ -70,7 +85,13 @@
      HttpServletRequest request = createMock(HttpServletRequest.class);

      final MockFilter mockFilter = new MockFilter();
-     
expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
+
+    expect(injector.getBinding(Key.get(Filter.class)))
+        .andReturn(createMock(Binding.class));
+
+    expect(injector.getInstance(Key.get(Filter.class)))
+        .andReturn(mockFilter)
+        .anyTimes();

      expect(request.getServletPath()).andReturn("/index.html");

@@ -118,7 +139,13 @@
          //suppress rest of chain...
        }
      };
-     
expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes();
+
+    expect(injector.getBinding(Key.get(Filter.class)))
+        .andReturn(createMock(Binding.class));
+
+    expect(injector.getInstance(Key.get(Filter.class)))
+        .andReturn(mockFilter)
+        .anyTimes();

      expect(request.getServletPath()).andReturn("/index.html");


Modified:  
trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java 
 
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java 
 
Tue Jan  6 04:48:44 2009
@@ -39,7 +39,7 @@
      doFilters = 0;
      destroys = 0;

-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }



Modified:  
trunk/servlet/test/com/google/inject/servlet/FilterPipelineTest.java
==============================================================================
--- trunk/servlet/test/com/google/inject/servlet/FilterPipelineTest.java        
 
(original)
+++ trunk/servlet/test/com/google/inject/servlet/FilterPipelineTest.java        
 
Tue Jan  6 04:48:44 2009
@@ -33,7 +33,7 @@

    @Override
    public final void setUp() {
-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();

      Guice.createInjector(new ServletModule() {

@@ -53,7 +53,7 @@

    @Override
    public final void tearDown() {
-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }

    public final void testDispatchThruGuiceFilter() throws ServletException,  
IOException {

Added:  
trunk/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java
==============================================================================
--- (empty file)
+++  
trunk/servlet/test/com/google/inject/servlet/InvalidScopeBindingTest.java       
 
Tue Jan  6 04:48:44 2009
@@ -0,0 +1,98 @@
+package com.google.inject.servlet;
+
+import com.google.inject.Guice;
+import com.google.inject.Singleton;
+import com.google.inject.Scopes;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+
+/**
+ * Ensures that an error is thrown if a Servlet or Filter is bound
+ * under any scope other than singleton, explicitly.
+ *
+ * @author [email protected]
+ */
+public class InvalidScopeBindingTest extends TestCase {
+
+  @Override
+  protected void tearDown() throws Exception {
+    GuiceFilter.reset();
+  }
+
+  public final void testServletInNonSingletonScopeThrowsServletException(){
+    GuiceFilter guiceFilter = new GuiceFilter();
+
+    Guice.createInjector(new ServletModule() {
+      @Override
+      protected void configureServlets() {
+        serve("/*").with(MyNonSingletonServlet.class);
+      }
+    });
+
+    ServletException se = null;
+    try {
+      guiceFilter.init(createMock(FilterConfig.class));
+    } catch (ServletException e) {
+      se = e;
+    } finally {
+      assertNotNull("Servlet exception was not thrown with wrong scope  
binding", se);
+    }
+  }
+
+  public final void testFilterInNonSingletonScopeThrowsServletException(){
+    GuiceFilter guiceFilter = new GuiceFilter();
+
+    Guice.createInjector(new ServletModule() {
+      @Override
+      protected void configureServlets() {
+        filter("/*").through(MyNonSingletonFilter.class);
+      }
+    });
+
+    ServletException se = null;
+    try {
+      guiceFilter.init(createMock(FilterConfig.class));
+    } catch (ServletException e) {
+      se = e;
+    } finally {
+      assertNotNull("Servlet exception was not thrown with wrong scope  
binding", se);
+    }
+  }
+
+  public final void testHappyCaseFilter(){
+    GuiceFilter guiceFilter = new GuiceFilter();
+
+    Guice.createInjector(new ServletModule() {
+      @Override
+      protected void configureServlets() {
+        // Annotated scoping variant.
+        filter("/*").through(MySingletonFilter.class);
+
+        // Explicit scoping variant.
+        bind(DummyFilterImpl.class).in(Scopes.SINGLETON);
+        filter("/*").through(DummyFilterImpl.class);
+      }
+    });
+
+    ServletException se = null;
+    try {
+      guiceFilter.init(createMock(FilterConfig.class));
+    } catch (ServletException e) {
+      se = e;
+    } finally {
+      assertNull("Servlet exception was thrown with correct scope  
binding", se);
+    }
+  }
+
+  @RequestScoped
+  public static class MyNonSingletonServlet extends HttpServlet { }
+
+  @SessionScoped
+  public static class MyNonSingletonFilter extends DummyFilterImpl { }
+
+  @Singleton
+  public static class MySingletonFilter extends DummyFilterImpl { }
+}

Modified:  
trunk/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
     
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/MultiModuleDispatchIntegrationTest.java
     
Tue Jan  6 04:48:44 2009
@@ -38,7 +38,7 @@
      doFilters = 0;
      destroys = 0;

-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }



Modified:  
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java    
 
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java    
 
Tue Jan  6 04:48:44 2009
@@ -16,21 +16,19 @@

  package com.google.inject.servlet;

-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
+import com.google.inject.Binding;
  import com.google.inject.Injector;
  import com.google.inject.Key;
-
-import junit.framework.TestCase;
-
  import java.io.IOException;
  import java.util.HashMap;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;

  /**
   * Ensures servlet spec compliance for CGI-style variables and general
@@ -61,8 +59,10 @@
      HttpServletRequest request = createMock(HttpServletRequest.class);
      HttpServletResponse response = createMock(HttpServletResponse.class);

-    final boolean[] run = new boolean[1];
+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));

+    final boolean[] run = new boolean[1];
      //get an instance of this servlet
      expect(injector.getInstance(Key.get(HttpServlet.class)))
          .andReturn(new HttpServlet() {
@@ -125,8 +125,10 @@
      HttpServletRequest request = createMock(HttpServletRequest.class);
      HttpServletResponse response = createMock(HttpServletResponse.class);

-    final boolean[] run = new boolean[1];
+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));

+    final boolean[] run = new boolean[1];
      //get an instance of this servlet
      expect(injector.getInstance(Key.get(HttpServlet.class)))
          .andReturn(new HttpServlet() {
@@ -208,8 +210,10 @@
      HttpServletRequest request = createMock(HttpServletRequest.class);
      HttpServletResponse response = createMock(HttpServletResponse.class);

-    final boolean[] run = new boolean[1];
+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));

+    final boolean[] run = new boolean[1];
      //get an instance of this servlet
      expect(injector.getInstance(Key.get(HttpServlet.class)))
          .andReturn(new HttpServlet() {

Modified:  
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
==============================================================================
--- trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java     
 
(original)
+++ trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java     
 
Tue Jan  6 04:48:44 2009
@@ -22,6 +22,7 @@

  import com.google.inject.Injector;
  import com.google.inject.Key;
+import com.google.inject.Binding;
  import junit.framework.TestCase;

  import java.util.Enumeration;
@@ -42,6 +43,8 @@
    public final void testServletInitAndConfig() throws ServletException {
      Injector injector = createMock(Injector.class);

+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));
      final HttpServlet mockServlet = new HttpServlet() {
      };
      expect(injector.getInstance(Key.get(HttpServlet.class)))

Modified:  
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
         
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
         
Tue Jan  6 04:48:44 2009
@@ -52,7 +52,7 @@
      destroys = 0;
      doFilters = 0;

-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }

    public final void testDispatchRequestToManagedPipelineServlets()

Modified:  
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
   
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
   
Tue Jan  6 04:48:44 2009
@@ -73,6 +73,8 @@
        }
      };

+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));
      expect(injector.getInstance(HTTP_SERLVET_KEY))
          .andReturn(mockServlet);

@@ -134,6 +136,9 @@
        }
      };

+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));
+
      expect(injector.getInstance(HTTP_SERLVET_KEY))
          .andReturn(mockServlet);

@@ -199,6 +204,9 @@
          assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
        }
      };
+
+    expect(injector.getBinding(Key.get(HttpServlet.class)))
+        .andReturn(createMock(Binding.class));

      expect(injector.getInstance(Key.get(HttpServlet.class)))
          .andReturn(mockServlet);

Modified: trunk/servlet/test/com/google/inject/servlet/ServletTest.java
==============================================================================
--- trunk/servlet/test/com/google/inject/servlet/ServletTest.java       
(original)
+++ trunk/servlet/test/com/google/inject/servlet/ServletTest.java       Tue Jan 
  
6 04:48:44 2009
@@ -48,7 +48,7 @@
    @Override
    public void setUp() {
      //we need to clear the reference to the pipeline every test =(
-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }

    public void testNewRequestObject()

Modified:  
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
   
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
   
Tue Jan  6 04:48:44 2009
@@ -38,7 +38,7 @@
      doFilters = 0;
      destroys = 0;

-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }



Modified:  
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
==============================================================================
---  
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
  
(original)
+++  
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
  
Tue Jan  6 04:48:44 2009
@@ -52,7 +52,7 @@
      destroys = 0;
      doFilters = 0;

-    GuiceFilter.clearPipeline();
+    GuiceFilter.reset();
    }

    public final void testDispatchRequestToManagedPipelineServlets()

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