vipx / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 0 forks source link

Support rewriting bindings (change annotations, scopes) #460

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
See thread
http://groups.google.com/group/google-guice/browse_thread/thread/6045a424b1873f6
2?hl=en
for background.

The premise behind this patch is to give people a way to programatically
alter bindings in a module.  An example of needing to do this could be if
you have a Module supplied from a 3rd party vendor, or legacy code, and it
uses an out-of-date scope that you would like to upgrade to a newer scope,
or it expects a certain annotation that your code doesn't use.

The patch exposes a new 'rewrite' method in Modules that allows the user to
chain combinations of Matcher<? super Binding<?>> and either a Scope or
Annotation.  If the matcher returns true, the rewritten module will update
the binding in question to use the new scope or annotation.

Example:

Module newModule = Modules.rewrite(Modules.replace(new LegacyModule())
  .withAnnotation(new DeprecatedAnnotationMatcher(), NewAnnotation.class)
  .build());

Or to upgrade no-scope bindings to a Singleton (as the thread on the
mailing list asked for) --

Module newModule = Modules.rewrite(Modules.replace(new MyModule())
  .withScope(new NoScopeMatcher(), Scopes.SINGLETON)
  .build());

where NoScopeMatcher is something as simple as:
   private static class NoScopeMatcher extends AbstractMatcher<Binding<?>>
implements BindingScopingVisitor<Boolean> {
    public Boolean visitEagerSingleton() { return false; };
    public Boolean visitNoScoping() { return true; };
    public Boolean visitScope(Scope scope) { return scope == null; };
    public Boolean visitScopeAnnotation(java.lang.Class<? extends
java.lang.annotation.Annotation> scopeAnnotation) { return false; };
    public boolean matches(Binding<?> t) {
      return t.acceptScopingVisitor(this);
    }
  }

This needs to be applied to core guice (and not be an extension) because of
the BindingRewriter class that must be in the internal package, as it uses
package-private methods to upgrade the bindings.

New tests are in the ModulesTest class.

Original issue reported on code.google.com by sberlin on 17 Jan 2010 at 5:37

Attachments:

GoogleCodeExporter commented 9 years ago
Fixed javadoc in Modules.rewrite -- the API is used as:

Module newModule = Modules.rewrite(new LegacyModule())
  .withAnnotation(new DeprecatedAnnotationMatcher(), NewAnnotation.class)
  .build());

or

Module newModule = Modules.rewrite(new MyModule())
  .withScope(new NoScopeMatcher(), Scopes.SINGLETON)
  .build());

(The additional Modules.replace snuck in there accidentally, since I wasn't 
sure what
I wanted to call the method, replace or rewrite.)

Original comment by sberlin on 17 Jan 2010 at 5:42

Attachments: