Revision: 1195
Author: sberlin
Date: Sun Aug  1 09:01:16 2010
Log: issue 528 - if a single PrivateModule is supplied to Modules.override, allow the private elements within the module to be overridden.
http://code.google.com/p/google-guice/source/detail?r=1195

Modified:
 /trunk/src/com/google/inject/util/Modules.java
 /trunk/test/com/google/inject/ModulesTest.java

=======================================
--- /trunk/src/com/google/inject/util/Modules.java      Sat Jul  3 08:51:31 2010
+++ /trunk/src/com/google/inject/util/Modules.java      Sun Aug  1 09:01:16 2010
@@ -22,8 +22,10 @@
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.PrivateBinder;
+import com.google.inject.PrivateModule;
 import com.google.inject.Scope;
 import com.google.inject.internal.util.ImmutableSet;
+import com.google.inject.internal.util.Iterables;
 import com.google.inject.internal.util.Lists;
 import com.google.inject.internal.util.Maps;
 import com.google.inject.internal.util.Sets;
@@ -52,6 +54,25 @@
   public static final Module EMPTY_MODULE = new Module() {
     public void configure(Binder binder) {}
   };
+
+  /**
+ * Returns a builder that creates a module that overlays override modules over the given + * PrivateModule. This allows private elements in the module to be overridden. No new keys + * may be exposed. If a key is bound in both sets of modules, only the binding from the override modules + * is kept. This can be used to replace the bindings of a production module with test bindings:
+   * <pre>
+   * Module functionalTestModule
+ * = Modules.override(new PrivateProductionModule()).with(getTestModules());
+   * </pre>
+   *
+ * <p>Prefer to write smaller modules that can be reused and tested without overrides.
+   *
+   * @param modules the modules whose bindings are open to be overridden
+   * @since 3.0
+   */
+ public static PrivateOverriddenModuleBuilder override(PrivateModule privateModule) {
+    return new RealPrivateOverriddenModuleBuilder(privateModule);
+  }

   /**
* Returns a builder that creates a module that overlays override modules over the given
@@ -124,7 +145,53 @@
      */
     Module with(Iterable<? extends Module> overrides);
   }
-
+
+  /**
+ * See the EDSL example at {...@link Modules#override(PrivateModule) override()}.
+   * @since 3.0
+   */
+  public interface PrivateOverriddenModuleBuilder {
+
+    /**
+ * See the EDSL example at {...@link Modules#override(PrivateModule) override()}.
+     */
+    PrivateModule with(Module... overrides);
+
+    /**
+ * See the EDSL example at {...@link Modules#override(PrivateModule) override()}.
+     */
+    PrivateModule with(Iterable<? extends Module> overrides);
+  }
+
+  /**
+   * An override builder specifically for private modules.
+   * This allows elements within a PrivateModule to be overridden.
+   */
+ private static final class RealPrivateOverriddenModuleBuilder implements PrivateOverriddenModuleBuilder {
+    private final PrivateModule baseModule;
+
+ private RealPrivateOverriddenModuleBuilder(PrivateModule privateModule) {
+      this.baseModule = privateModule;
+    }
+
+    public PrivateModule with(Module... overrides) {
+      return with(Arrays.asList(overrides));
+    }
+
+    public PrivateModule with(final Iterable<? extends Module> overrides) {
+      return new PrivateModule() {
+        @Override
+        public void configure() {
+ PrivateElements privateElements = (PrivateElements)Iterables.getOnlyElement(Elements.getElements(baseModule)); + override(Elements.getModule(privateElements.getElements())).with(overrides).configure(binder());
+          for(Key exposed : privateElements.getExposedKeys()) {
+ binder().withSource(privateElements.getExposedSource(exposed)).expose(exposed);
+          }
+        }
+      };
+    }
+  }
+
private static final class RealOverriddenModuleBuilder implements OverriddenModuleBuilder {
     private final ImmutableSet<Module> baseModules;

=======================================
--- /trunk/test/com/google/inject/ModulesTest.java      Sat Feb  7 11:26:08 2009
+++ /trunk/test/com/google/inject/ModulesTest.java      Sun Aug  1 09:01:16 2010
@@ -16,6 +16,9 @@

 package com.google.inject;

+import static com.google.inject.name.Names.named;
+
+import com.google.inject.name.Named;
 import com.google.inject.util.Modules;
 import java.util.Arrays;
 import junit.framework.TestCase;
@@ -64,4 +67,49 @@
       }
     };
   }
-}
+
+  private static final String RESULT = "RESULT";
+  private static final String PRIVATE_INPUT = "PRIVATE_INPUT";
+  private static final String OVERRIDDEN_INPUT = "FOO";
+  private static final String OVERRIDDEN_RESULT = "Size: 3";
+ private static final Key<String> RESULT_KEY = Key.get(String.class, named(RESULT)); + private static final Key<String> INPUT_KEY = Key.get(String.class, named(PRIVATE_INPUT));
+
+
+  public void testExposedBindingOverride() throws Exception {
+    Injector inj = Guice.createInjector(
+        Modules.override(new ExampleModule()).with(
+            new AbstractModule() {
+              @Override protected void configure() {
+                bind(RESULT_KEY).toInstance(OVERRIDDEN_RESULT);
+              }
+            }));
+    assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
+  }
+
+  public void testPrivateBindingOverride() throws Exception {
+    Injector inj = Guice.createInjector(
+        Modules.override(new ExampleModule()).with(
+            new AbstractModule() {
+              @Override protected void configure() {
+                bind(INPUT_KEY).toInstance(OVERRIDDEN_INPUT);
+              }
+            }));
+    assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
+  }
+
+  public static class ExampleModule extends PrivateModule {
+    @Provides @Exposed @Named(RESULT)
+    public String provideResult(@Named(PRIVATE_INPUT) String input) {
+      return "Size: " + input.length();
+    }
+
+    @Provides @Named(PRIVATE_INPUT)
+    public String provideInput() {
+      return "Hello World";
+    }
+
+    @Override protected void configure() {
+    }
+  }
+}

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