10910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber/**
20910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Copyright (C) 2015 Google Inc.
30910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
40910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Licensed under the Apache License, Version 2.0 (the "License");
50910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * you may not use this file except in compliance with the License.
60910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * You may obtain a copy of the License at
70910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
80910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * http://www.apache.org/licenses/LICENSE-2.0
90910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
100910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * Unless required by applicable law or agreed to in writing, software
110910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * distributed under the License is distributed on an "AS IS" BASIS,
120910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * See the License for the specific language governing permissions and
140910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * limitations under the License.
150910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber */
160910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberpackage com.google.inject.daggeradapter;
170910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
180910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.common.base.Objects;
190910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.Binder;
200910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.Module;
210910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.internal.ProviderMethodsModule;
220910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport com.google.inject.spi.ModuleAnnotatedMethodScanner;
230910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
240910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberimport java.util.Arrays;
250910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
260910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber/**
270910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * A utility to adapt classes annotated with {@link @dagger.Module} such that their
280910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * {@link @dagger.Provides} methods can be properly invoked by Guice to perform their
290910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * provision operations.
300910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
310910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * <p>Simple example: <pre>{@code
320910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *   Guice.createInjector(...other modules..., DaggerAdapter.from(new SomeDaggerAdapter()));
330910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * }</pre>
340910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
350910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * <p>Some notes on usage and compatibility.
360910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *   <ul>
370910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *     <li>Dagger provider methods have a "SET_VALUES" provision mode not supported by Guice.
380910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *     <li>MapBindings are not yet implemented (pending).
390910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *     <li>Be careful about stateful modules. In contrast to Dagger (where components are
400910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         expected to be recreated on-demand with new Module instances), Guice typically
410910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         has a single injector with a long lifetime, so your module instance will be used
420910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         throughout the lifetime of the entire app.
430910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *     <li>Dagger 1.x uses {@link @Singleton} for all scopes, including shorter-lived scopes
440910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         like per-request or per-activity.  Using modules written with Dagger 1.x usage
450910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         in mind may result in mis-scoped objects.
460910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *     <li>Dagger 2.x supports custom scope annotations, but for use in Guice, a custom scope
470910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         implementation must be registered in order to support the custom lifetime of that
480910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *         annotation.
490910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *   </ul>
500910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber *
510910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber * @author cgruber@google.com (Christian Gruber)
520910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber */
530910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruberpublic final class DaggerAdapter {
540910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  /**
550910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   * Returns a guice module from a dagger module.
560910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   *
570910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   * <p>Note: At present, it does not honor {@code @Module(includes=...)} directives.
580910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   */
590910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  public static Module from(Object... daggerModuleObjects) {
600910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    // TODO(cgruber): Gather injects=, dedupe, factor out instances, instantiate the rest, and go.
610910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    return new DaggerCompatibilityModule(daggerModuleObjects);
620910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  }
630910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
640910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  /**
650910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   * A Module that adapts Dagger {@code @Module}-annotated types to contribute configuration
660910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   * to an {@link com.google.inject.Injector} using a dagger-specific
670910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   * {@link ModuleAnnotatedMethodScanner}.
680910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber   */
690910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  private static final class DaggerCompatibilityModule implements Module {
700910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    private final Object[] daggerModuleObjects;
710910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
720910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    private DaggerCompatibilityModule(Object... daggerModuleObjects) {
730910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      this.daggerModuleObjects = daggerModuleObjects;
740910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    }
750910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
760910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    @Override public void configure(Binder binder) {
770910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      for (Object module : daggerModuleObjects) {
780910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber        binder.install(ProviderMethodsModule.forModule(module, DaggerMethodScanner.INSTANCE));
790910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      }
800910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    }
810910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
820910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    @Override public String toString() {
830910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber      return Objects.toStringHelper(this)
840910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber          .add("modules", Arrays.asList(daggerModuleObjects))
850910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber          .toString();
860910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber    }
870910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  }
880910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber
890910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber  private DaggerAdapter() {}
900910c1e69ee2b0587f898cb292d4e9f8d9338e28cgruber}
91