with(instance) api for servlet module. Thanks to isaac.shum

git-svn-id: https://google-guice.googlecode.com/svn/trunk@1121 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java b/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
index 1c49797..68797ef 100755
--- a/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
+++ b/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
@@ -34,10 +34,16 @@
  */
 class FiltersModuleBuilder extends AbstractModule {
   private final List<FilterDefinition> filterDefinitions = Lists.newArrayList();
+  private final List<FilterInstanceBindingEntry> filterInstanceEntries = Lists.newArrayList();
 
   //invoked on injector config
   @Override
   protected void configure() {
+    // Create bindings for filter instances
+    for (FilterInstanceBindingEntry entry : filterInstanceEntries) {
+      bind(entry.key).toInstance(entry.filter);
+    }
+
     // Bind these filter definitions to a unique random key. Doesn't matter what it is,
     // coz it's never used.
     bind(Key.get(new TypeLiteral<List<FilterDefinition>>() {}, UniqueAnnotations.create()))
@@ -52,6 +58,16 @@
     return new FilterKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
   }
 
+  private static class FilterInstanceBindingEntry {
+    final Key<Filter> key;
+    final Filter filter;
+
+    FilterInstanceBindingEntry(Key<Filter> key, Filter filter) {
+      this.key = key;
+      this.filter = filter;
+    }
+  }
+
   //non-static inner class so it can access state of enclosing module class
   class FilterKeyBindingBuilderImpl implements ServletModule.FilterKeyBindingBuilder {
     private final List<String> uriPatterns;
@@ -70,6 +86,10 @@
       through(filterKey, new HashMap<String, String>());
     }
 
+    public void through(Filter filter) {
+      through(filter, new HashMap<String, String>());
+    }
+
     public void through(Class<? extends Filter> filterKey,
         Map<String, String> contextParams) {
       
@@ -86,5 +106,12 @@
                 contextParams));
       }
     }
+
+    public void through(Filter filter,
+        Map<String, String> contextParams) {
+      Key<Filter> filterKey = Key.get(Filter.class, UniqueAnnotations.create());
+      filterInstanceEntries.add(new FilterInstanceBindingEntry(filterKey, filter));
+      through(filterKey, contextParams);
+    }
   }
 }
diff --git a/servlet/src/com/google/inject/servlet/ServletModule.java b/servlet/src/com/google/inject/servlet/ServletModule.java
index 5ff187a..379c5a7 100644
--- a/servlet/src/com/google/inject/servlet/ServletModule.java
+++ b/servlet/src/com/google/inject/servlet/ServletModule.java
@@ -90,10 +90,12 @@
    *     protected void configureServlets() {
    *       filter("/*").through(MyFilter.class);
    *       filter("*.css").through(MyCssFilter.class);
+   *       filter("*.jpg").through(new MyJpgFilter());
    *       // etc..
    *
    *       serve("*.html").with(MyServlet.class);
    *       serve("/my/*").with(MyServlet.class);
+   *       serve("*.jpg").with(new MyServlet());
    *       // etc..
    *      }
    *    }
@@ -259,8 +261,10 @@
   public static interface FilterKeyBindingBuilder {
     void through(Class<? extends Filter> filterKey);
     void through(Key<? extends Filter> filterKey);
+    void through(Filter filter);
     void through(Class<? extends Filter> dummyFilterClass, Map<String, String> contextParams);
     void through(Key<? extends Filter> dummyFilterClass, Map<String, String> contextParams);
+    void through(Filter filter, Map<String, String> contextParams);
   }
 
   /**
@@ -271,7 +275,9 @@
   public static interface ServletKeyBindingBuilder {
     void with(Class<? extends HttpServlet> servletKey);
     void with(Key<? extends HttpServlet> servletKey);
+    void with(HttpServlet servlet);
     void with(Class<? extends HttpServlet> servletKey, Map<String, String> contextParams);
     void with(Key<? extends HttpServlet> servletKey, Map<String, String> contextParams);
+    void with(HttpServlet servlet, Map<String, String> contextParams);
   }
 }
diff --git a/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java b/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
index 5afe802..47af60e 100755
--- a/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
+++ b/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
@@ -36,10 +36,15 @@
  */
 class ServletsModuleBuilder extends AbstractModule {
   private final List<ServletDefinition> servletDefinitions = Lists.newArrayList();
+  private final List<ServletInstanceBindingEntry> servletInstanceEntries = Lists.newArrayList();
 
   //invoked on injector config
   @Override
   protected void configure() {
+    // Create bindings for servlet instances
+    for (ServletInstanceBindingEntry entry : servletInstanceEntries) {
+      bind(entry.key).toInstance(entry.servlet);
+    }
 
     // Ensure that servlets are not bound twice to the same pattern.
     Set<String> servletUris = Sets.newHashSet();
@@ -68,6 +73,16 @@
     return new ServletKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
   }
 
+  private static class ServletInstanceBindingEntry {
+    final Key<HttpServlet> key;
+    final HttpServlet servlet;
+
+    ServletInstanceBindingEntry(Key<HttpServlet> key, HttpServlet servlet) {
+      this.key = key;
+      this.servlet = servlet;
+    }
+  }
+
   //non-static inner class so it can access state of enclosing module class
   class ServletKeyBindingBuilderImpl implements ServletModule.ServletKeyBindingBuilder {
     private final List<String> uriPatterns;
@@ -86,6 +101,10 @@
       with(servletKey, new HashMap<String, String>());
     }
 
+    public void with(HttpServlet servlet) {
+      with(servlet, new HashMap<String, String>());
+    }
+
     public void with(Class<? extends HttpServlet> servletKey,
         Map<String, String> contextParams) {
       with(Key.get(servletKey), contextParams);
@@ -100,5 +119,12 @@
                 contextParams));
       }
     }
+
+    public void with(HttpServlet servlet,
+        Map<String, String> contextParams) {
+      Key<HttpServlet> servletKey = Key.get(HttpServlet.class, UniqueAnnotations.create());
+      servletInstanceEntries.add(new ServletInstanceBindingEntry(servletKey, servlet));
+      with(servletKey, contextParams);
+    }
   }
 }
\ No newline at end of file
diff --git a/servlet/test/com/google/inject/servlet/EdslTest.java b/servlet/test/com/google/inject/servlet/EdslTest.java
index 7bb3dd1..2fffd01 100644
--- a/servlet/test/com/google/inject/servlet/EdslTest.java
+++ b/servlet/test/com/google/inject/servlet/EdslTest.java
@@ -39,6 +39,7 @@
         filter("/*").through(DummyFilterImpl.class);
         filter("*.html").through(DummyFilterImpl.class);
         filter("/*").through(Key.get(DummyFilterImpl.class));
+        filter("/*").through(new DummyFilterImpl());
 
         filter("*.html").through(DummyFilterImpl.class,
             new HashMap<String, String>());
@@ -51,10 +52,15 @@
         filterRegex("/person/[0-9]*").through(Key.get(DummyFilterImpl.class),
             new HashMap<String, String>());
 
+        filterRegex("/person/[0-9]*").through(new DummyFilterImpl());
+        filterRegex("/person/[0-9]*").through(new DummyFilterImpl(),
+            new HashMap<String, String>());
+
 
         serve("/1/*").with(DummyServlet.class);
         serve("/2/*").with(Key.get(DummyServlet.class));
-        serve("/3/*").with(DummyServlet.class, new HashMap<String, String>());
+        serve("/3/*").with(new DummyServlet());
+        serve("/4/*").with(DummyServlet.class, new HashMap<String, String>());
 
         serve("*.htm").with(Key.get(DummyServlet.class));
         serve("*.html").with(Key.get(DummyServlet.class),
@@ -67,6 +73,10 @@
         serveRegex("/person/[0-6]*").with(Key.get(DummyServlet.class));
         serveRegex("/person/[0-9]/2/*").with(Key.get(DummyServlet.class),
             new HashMap<String, String>());
+
+        serveRegex("/person/[0-5]*").with(new DummyServlet());
+        serveRegex("/person/[0-9]/3/*").with(new DummyServlet(),
+            new HashMap<String, String>());
       }
     };