Home | History | Annotate | Download | only in multibindings
      1 /**
      2  * Copyright (C) 2014 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.inject.multibindings;
     18 
     19 import static com.google.common.base.Preconditions.checkNotNull;
     20 import static com.google.common.base.Preconditions.checkState;
     21 import static com.google.inject.multibindings.Multibinder.checkConfiguration;
     22 import static com.google.inject.util.Types.newParameterizedType;
     23 import static java.lang.annotation.RetentionPolicy.RUNTIME;
     24 
     25 import com.google.common.base.Optional;
     26 import com.google.common.base.Throwables;
     27 import com.google.common.collect.ImmutableSet;
     28 import com.google.inject.Binder;
     29 import com.google.inject.Binding;
     30 import com.google.inject.Inject;
     31 import com.google.inject.Injector;
     32 import com.google.inject.Key;
     33 import com.google.inject.Module;
     34 import com.google.inject.Provider;
     35 import com.google.inject.TypeLiteral;
     36 import com.google.inject.binder.LinkedBindingBuilder;
     37 import com.google.inject.spi.BindingTargetVisitor;
     38 import com.google.inject.spi.Dependency;
     39 import com.google.inject.spi.Element;
     40 import com.google.inject.spi.ProviderInstanceBinding;
     41 import com.google.inject.spi.ProviderLookup;
     42 import com.google.inject.spi.ProviderWithDependencies;
     43 import com.google.inject.spi.ProviderWithExtensionVisitor;
     44 import com.google.inject.spi.Toolable;
     45 import com.google.inject.util.Types;
     46 
     47 import java.io.Serializable;
     48 import java.lang.annotation.Annotation;
     49 import java.lang.annotation.Retention;
     50 import java.lang.reflect.InvocationTargetException;
     51 import java.lang.reflect.Method;
     52 import java.lang.reflect.Type;
     53 import java.util.Set;
     54 
     55 import javax.inject.Qualifier;
     56 
     57 
     58 /**
     59  * An API to bind optional values, optionally with a default value.
     60  * OptionalBinder fulfills two roles: <ol>
     61  * <li>It allows a framework to define an injection point that may or
     62  *     may not be bound by users.
     63  * <li>It allows a framework to supply a default value that can be changed
     64  *     by users.
     65  * </ol>
     66  *
     67  * <p>When an OptionalBinder is added, it will always supply the bindings:
     68  * {@code Optional<T>} and {@code Optional<Provider<T>>}.  If
     69  * {@link #setBinding} or {@link #setDefault} are called, it will also
     70  * bind {@code T}.
     71  *
     72  * <p>{@code setDefault} is intended for use by frameworks that need a default
     73  * value.  User code can call {@code setBinding} to override the default.
     74  * <b>Warning: Even if setBinding is called, the default binding
     75  * will still exist in the object graph.  If it is a singleton, it will be
     76  * instantiated in {@code Stage.PRODUCTION}.</b>
     77  *
     78  * <p>If setDefault or setBinding are linked to Providers, the Provider may return
     79  * {@code null}.  If it does, the Optional bindings will be absent.  Binding
     80  * setBinding to a Provider that returns null will not cause OptionalBinder
     81  * to fall back to the setDefault binding.
     82  *
     83  * <p>If neither setDefault nor setBinding are called, it will try to link to a
     84  * user-supplied binding of the same type.  If no binding exists, the optionals
     85  * will be absent.  Otherwise, if a user-supplied binding of that type exists,
     86  * or if setBinding or setDefault are called, the optionals will return present
     87  * if they are bound to a non-null value.
     88  *
     89  * <p>Values are resolved at injection time. If a value is bound to a
     90  * provider, that provider's get method will be called each time the optional
     91  * is injected (unless the binding is also scoped, or an optional of provider is
     92  * injected).
     93  *
     94  * <p>Annotations are used to create different optionals of the same key/value
     95  * type. Each distinct annotation gets its own independent binding.
     96  *
     97  * <pre><code>
     98  * public class FrameworkModule extends AbstractModule {
     99  *   protected void configure() {
    100  *     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
    101  *   }
    102  * }</code></pre>
    103  *
    104  * <p>With this module, an {@link Optional}{@code <Renamer>} can now be
    105  * injected.  With no other bindings, the optional will be absent.
    106  * Users can specify bindings in one of two ways:
    107  *
    108  * <p>Option 1:
    109  * <pre><code>
    110  * public class UserRenamerModule extends AbstractModule {
    111  *   protected void configure() {
    112  *     bind(Renamer.class).to(ReplacingRenamer.class);
    113  *   }
    114  * }</code></pre>
    115  *
    116  * <p>or Option 2:
    117  * <pre><code>
    118  * public class UserRenamerModule extends AbstractModule {
    119  *   protected void configure() {
    120  *     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
    121  *         .setBinding().to(ReplacingRenamer.class);
    122  *   }
    123  * }</code></pre>
    124  * With both options, the {@code Optional<Renamer>} will be present and supply the
    125  * ReplacingRenamer.
    126  *
    127  * <p>Default values can be supplied using:
    128  * <pre><code>
    129  * public class FrameworkModule extends AbstractModule {
    130  *   protected void configure() {
    131  *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
    132  *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
    133  *   }
    134  * }</code></pre>
    135  * With the above module, code can inject an {@code @LookupUrl String} and it
    136  * will supply the DEFAULT_LOOKUP_URL.  A user can change this value by binding
    137  * <pre><code>
    138  * public class UserLookupModule extends AbstractModule {
    139  *   protected void configure() {
    140  *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
    141  *         .setBinding().toInstance(CUSTOM_LOOKUP_URL);
    142  *   }
    143  * }</code></pre>
    144  * ... which will override the default value.
    145  *
    146  * <p>If one module uses setDefault the only way to override the default is to use setBinding.
    147  * It is an error for a user to specify the binding without using OptionalBinder if
    148  * setDefault or setBinding are called.  For example,
    149  * <pre><code>
    150  * public class FrameworkModule extends AbstractModule {
    151  *   protected void configure() {
    152  *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
    153  *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
    154  *   }
    155  * }
    156  * public class UserLookupModule extends AbstractModule {
    157  *   protected void configure() {
    158  *     bind(Key.get(String.class, LookupUrl.class)).toInstance(CUSTOM_LOOKUP_URL);
    159  *   }
    160  * }</code></pre>
    161  * ... would generate an error, because both the framework and the user are trying to bind
    162  * {@code @LookupUrl String}.
    163  *
    164  * @author sameb (at) google.com (Sam Berlin)
    165  * @since 4.0
    166  */
    167 public abstract class OptionalBinder<T> {
    168 
    169   /* Reflectively capture java 8's Optional types so we can bind them if we're running in java8. */
    170   private static final Class<?> JAVA_OPTIONAL_CLASS;
    171   private static final Method JAVA_EMPTY_METHOD;
    172   private static final Method JAVA_OF_NULLABLE_METHOD;
    173   static {
    174     Class<?> optional = null;
    175     Method empty = null;
    176     Method ofNullable = null;
    177     boolean useJavaOptional = false;
    178     try {
    179       optional = Class.forName("java.util.Optional");
    180       empty = optional.getDeclaredMethod("empty");
    181       ofNullable = optional.getDeclaredMethod("ofNullable", Object.class);
    182       useJavaOptional = true;
    183     } catch (ClassNotFoundException ignored) {
    184     } catch (NoSuchMethodException ignored) {
    185     } catch (SecurityException ignored) {
    186     }
    187     JAVA_OPTIONAL_CLASS = useJavaOptional ? optional : null;
    188     JAVA_EMPTY_METHOD = useJavaOptional ? empty : null;
    189     JAVA_OF_NULLABLE_METHOD = useJavaOptional ? ofNullable : null;
    190   }
    191 
    192   private OptionalBinder() {}
    193 
    194   public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Class<T> type) {
    195     return newRealOptionalBinder(binder, Key.get(type));
    196   }
    197 
    198   public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, TypeLiteral<T> type) {
    199     return newRealOptionalBinder(binder, Key.get(type));
    200   }
    201 
    202   public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Key<T> type) {
    203     return newRealOptionalBinder(binder, type);
    204   }
    205 
    206   static <T> RealOptionalBinder<T> newRealOptionalBinder(Binder binder, Key<T> type) {
    207     binder = binder.skipSources(OptionalBinder.class, RealOptionalBinder.class);
    208     RealOptionalBinder<T> optionalBinder = new RealOptionalBinder<T>(binder, type);
    209     binder.install(optionalBinder);
    210     return optionalBinder;
    211   }
    212 
    213   @SuppressWarnings("unchecked")
    214   static <T> TypeLiteral<Optional<T>> optionalOf(
    215       TypeLiteral<T> type) {
    216     return (TypeLiteral<Optional<T>>) TypeLiteral.get(
    217         Types.newParameterizedType(Optional.class,  type.getType()));
    218   }
    219 
    220   static <T> TypeLiteral<?> javaOptionalOf(
    221       TypeLiteral<T> type) {
    222     checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
    223     return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS, type.getType()));
    224   }
    225 
    226   @SuppressWarnings("unchecked")
    227   static <T> TypeLiteral<Optional<javax.inject.Provider<T>>> optionalOfJavaxProvider(
    228       TypeLiteral<T> type) {
    229     return (TypeLiteral<Optional<javax.inject.Provider<T>>>) TypeLiteral.get(
    230         Types.newParameterizedType(Optional.class,
    231             newParameterizedType(javax.inject.Provider.class, type.getType())));
    232   }
    233 
    234   static <T> TypeLiteral<?> javaOptionalOfJavaxProvider(
    235       TypeLiteral<T> type) {
    236     checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
    237     return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS,
    238         newParameterizedType(javax.inject.Provider.class, type.getType())));
    239   }
    240 
    241   @SuppressWarnings("unchecked")
    242   static <T> TypeLiteral<Optional<Provider<T>>> optionalOfProvider(TypeLiteral<T> type) {
    243     return (TypeLiteral<Optional<Provider<T>>>) TypeLiteral.get(Types.newParameterizedType(
    244         Optional.class, newParameterizedType(Provider.class, type.getType())));
    245   }
    246 
    247   static <T> TypeLiteral<?> javaOptionalOfProvider(TypeLiteral<T> type) {
    248     checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
    249     return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS,
    250         newParameterizedType(Provider.class, type.getType())));
    251   }
    252 
    253   @SuppressWarnings("unchecked")
    254   static <T> Key<Provider<T>> providerOf(Key<T> key) {
    255     Type providerT = Types.providerOf(key.getTypeLiteral().getType());
    256     return (Key<Provider<T>>) key.ofType(providerT);
    257   }
    258 
    259   /**
    260    * Returns a binding builder used to set the default value that will be injected.
    261    * The binding set by this method will be ignored if {@link #setBinding} is called.
    262    *
    263    * <p>It is an error to call this method without also calling one of the {@code to}
    264    * methods on the returned binding builder.
    265    */
    266   public abstract LinkedBindingBuilder<T> setDefault();
    267 
    268 
    269   /**
    270    * Returns a binding builder used to set the actual value that will be injected.
    271    * This overrides any binding set by {@link #setDefault}.
    272    *
    273    * <p>It is an error to call this method without also calling one of the {@code to}
    274    * methods on the returned binding builder.
    275    */
    276   public abstract LinkedBindingBuilder<T> setBinding();
    277 
    278   enum Source { DEFAULT, ACTUAL }
    279 
    280   @Retention(RUNTIME)
    281   @Qualifier
    282   @interface Default {
    283     String value();
    284   }
    285 
    286   @Retention(RUNTIME)
    287   @Qualifier
    288   @interface Actual {
    289     String value();
    290   }
    291 
    292   /**
    293    * The actual OptionalBinder plays several roles.  It implements Module to hide that
    294    * fact from the public API, and installs the various bindings that are exposed to the user.
    295    */
    296   static final class RealOptionalBinder<T> extends OptionalBinder<T> implements Module {
    297     private final Key<T> typeKey;
    298     private final Key<Optional<T>> optionalKey;
    299     private final Key<Optional<javax.inject.Provider<T>>> optionalJavaxProviderKey;
    300     private final Key<Optional<Provider<T>>> optionalProviderKey;
    301     private final Provider<Optional<Provider<T>>> optionalProviderT;
    302     private final Key<T> defaultKey;
    303     private final Key<T> actualKey;
    304 
    305     private final Key javaOptionalKey;
    306     private final Key javaOptionalJavaxProviderKey;
    307     private final Key javaOptionalProviderKey;
    308 
    309     /** the target injector's binder. non-null until initialization, null afterwards */
    310     private Binder binder;
    311     /** the default binding, for the SPI. */
    312     private Binding<T> defaultBinding;
    313     /** the actual binding, for the SPI */
    314     private Binding<T> actualBinding;
    315 
    316     /** the dependencies -- initialized with defaults & overridden when tooled. */
    317     private Set<Dependency<?>> dependencies;
    318     /** the dependencies -- initialized with defaults & overridden when tooled. */
    319     private Set<Dependency<?>> providerDependencies;
    320 
    321     private RealOptionalBinder(Binder binder, Key<T> typeKey) {
    322       this.binder = binder;
    323       this.typeKey = checkNotNull(typeKey);
    324       TypeLiteral<T> literal = typeKey.getTypeLiteral();
    325       this.optionalKey = typeKey.ofType(optionalOf(literal));
    326       this.optionalJavaxProviderKey = typeKey.ofType(optionalOfJavaxProvider(literal));
    327       this.optionalProviderKey = typeKey.ofType(optionalOfProvider(literal));
    328       this.optionalProviderT = binder.getProvider(optionalProviderKey);
    329       String name = RealElement.nameOf(typeKey);
    330       this.defaultKey = Key.get(typeKey.getTypeLiteral(), new DefaultImpl(name));
    331       this.actualKey = Key.get(typeKey.getTypeLiteral(), new ActualImpl(name));
    332       // Until the injector initializes us, we don't know what our dependencies are,
    333       // so initialize to the whole Injector (like Multibinder, and MapBinder indirectly).
    334       this.dependencies = ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
    335       this.providerDependencies =
    336           ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
    337 
    338       if (JAVA_OPTIONAL_CLASS != null) {
    339         this.javaOptionalKey = typeKey.ofType(javaOptionalOf(literal));
    340         this.javaOptionalJavaxProviderKey = typeKey.ofType(javaOptionalOfJavaxProvider(literal));
    341         this.javaOptionalProviderKey = typeKey.ofType(javaOptionalOfProvider(literal));
    342       } else {
    343         this.javaOptionalKey = null;
    344         this.javaOptionalJavaxProviderKey = null;
    345         this.javaOptionalProviderKey = null;
    346       }
    347     }
    348 
    349     /**
    350      * Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate
    351      * bindings.
    352      */
    353     private void addDirectTypeBinding(Binder binder) {
    354       binder.bind(typeKey).toProvider(new RealDirectTypeProvider());
    355     }
    356 
    357     Key<T> getKeyForDefaultBinding() {
    358       checkConfiguration(!isInitialized(), "already initialized");
    359       addDirectTypeBinding(binder);
    360       return defaultKey;
    361     }
    362 
    363     @Override public LinkedBindingBuilder<T> setDefault() {
    364       return binder.bind(getKeyForDefaultBinding());
    365     }
    366 
    367     Key<T> getKeyForActualBinding() {
    368       checkConfiguration(!isInitialized(), "already initialized");
    369       addDirectTypeBinding(binder);
    370       return actualKey;
    371     }
    372 
    373     @Override public LinkedBindingBuilder<T> setBinding() {
    374       return binder.bind(getKeyForActualBinding());
    375     }
    376 
    377     @Override public void configure(Binder binder) {
    378       checkConfiguration(!isInitialized(), "OptionalBinder was already initialized");
    379 
    380       binder.bind(optionalProviderKey).toProvider(new RealOptionalProviderProvider());
    381 
    382       // Optional is immutable, so it's safe to expose Optional<Provider<T>> as
    383       // Optional<javax.inject.Provider<T>> (since Guice provider implements javax Provider).
    384       @SuppressWarnings({"unchecked", "cast"})
    385       Key massagedOptionalProviderKey = (Key) optionalProviderKey;
    386       binder.bind(optionalJavaxProviderKey).to(massagedOptionalProviderKey);
    387 
    388       binder.bind(optionalKey).toProvider(new RealOptionalKeyProvider());
    389 
    390       // Bind the java-8 types if we know them.
    391       bindJava8Optional(binder);
    392     }
    393 
    394     @SuppressWarnings("unchecked")
    395     private void bindJava8Optional(Binder binder) {
    396       if (JAVA_OPTIONAL_CLASS != null) {
    397         binder.bind(javaOptionalKey).toProvider(new JavaOptionalProvider());
    398         binder.bind(javaOptionalProviderKey).toProvider(new JavaOptionalProviderProvider());
    399         // for the javax version we reuse the guice version since they're type-compatible.
    400         binder.bind(javaOptionalJavaxProviderKey).to(javaOptionalProviderKey);
    401       }
    402     }
    403 
    404     @SuppressWarnings("rawtypes")
    405     final class JavaOptionalProvider extends RealOptionalBinderProviderWithDependencies
    406         implements ProviderWithExtensionVisitor, OptionalBinderBinding {
    407       private JavaOptionalProvider() {
    408         super(typeKey);
    409       }
    410 
    411       @Override public Object get() {
    412         Optional<Provider<T>> optional = optionalProviderT.get();
    413         try {
    414           if (optional.isPresent()) {
    415             return JAVA_OF_NULLABLE_METHOD.invoke(JAVA_OPTIONAL_CLASS, optional.get().get());
    416           } else {
    417             return JAVA_EMPTY_METHOD.invoke(JAVA_OPTIONAL_CLASS);
    418           }
    419         } catch (IllegalAccessException e) {
    420           throw new SecurityException(e);
    421         } catch (IllegalArgumentException e) {
    422           throw new IllegalStateException(e);
    423         } catch (InvocationTargetException e) {
    424           throw Throwables.propagate(e.getCause());
    425         }
    426       }
    427 
    428       @Override public Set<Dependency<?>> getDependencies() {
    429         return dependencies;
    430       }
    431 
    432       @SuppressWarnings("unchecked")
    433       @Override public Object acceptExtensionVisitor(BindingTargetVisitor visitor,
    434           ProviderInstanceBinding binding) {
    435         if (visitor instanceof MultibindingsTargetVisitor) {
    436           return ((MultibindingsTargetVisitor) visitor).visit(this);
    437         } else {
    438           return visitor.visit(binding);
    439         }
    440       }
    441 
    442       @Override public boolean containsElement(Element element) {
    443         return RealOptionalBinder.this.containsElement(element);
    444       }
    445 
    446       @Override public Binding getActualBinding() {
    447         return RealOptionalBinder.this.getActualBinding();
    448       }
    449 
    450       @Override public Binding getDefaultBinding() {
    451         return RealOptionalBinder.this.getDefaultBinding();
    452       }
    453 
    454       @Override public Key getKey() {
    455         return javaOptionalKey;
    456       }
    457     }
    458 
    459     @SuppressWarnings("rawtypes")
    460     final class JavaOptionalProviderProvider extends RealOptionalBinderProviderWithDependencies {
    461       private JavaOptionalProviderProvider() {
    462         super(typeKey);
    463       }
    464 
    465       @Override public Object get() {
    466         Optional<Provider<T>> optional = optionalProviderT.get();
    467         try {
    468           if (optional.isPresent()) {
    469             return JAVA_OF_NULLABLE_METHOD.invoke(JAVA_OPTIONAL_CLASS, optional.get());
    470           } else {
    471             return JAVA_EMPTY_METHOD.invoke(JAVA_OPTIONAL_CLASS);
    472           }
    473         } catch (IllegalAccessException e) {
    474           throw new SecurityException(e);
    475         } catch (IllegalArgumentException e) {
    476           throw new IllegalStateException(e);
    477         } catch (InvocationTargetException e) {
    478           throw Throwables.propagate(e.getCause());
    479         }
    480       }
    481 
    482       @Override public Set<Dependency<?>> getDependencies() {
    483         return providerDependencies;
    484       }
    485     }
    486 
    487     final class RealDirectTypeProvider extends RealOptionalBinderProviderWithDependencies<T> {
    488       private RealDirectTypeProvider() {
    489         super(typeKey);
    490       }
    491 
    492       @Override public T get() {
    493         Optional<Provider<T>> optional = optionalProviderT.get();
    494         if (optional.isPresent()) {
    495           return optional.get().get();
    496         }
    497         // Let Guice handle blowing up if the injection point doesn't have @Nullable
    498         // (If it does have @Nullable, that's fine.  This would only happen if
    499         //  setBinding/setDefault themselves were bound to 'null').
    500         return null;
    501       }
    502 
    503       @Override public Set<Dependency<?>> getDependencies() {
    504         return dependencies;
    505       }
    506     }
    507 
    508     final class RealOptionalProviderProvider
    509         extends RealOptionalBinderProviderWithDependencies<Optional<Provider<T>>> {
    510       private Optional<Provider<T>> optional;
    511 
    512       private RealOptionalProviderProvider() {
    513         super(typeKey);
    514       }
    515 
    516       @Toolable @Inject void initialize(Injector injector) {
    517         RealOptionalBinder.this.binder = null;
    518         actualBinding = injector.getExistingBinding(actualKey);
    519         defaultBinding = injector.getExistingBinding(defaultKey);
    520         Binding<T> userBinding = injector.getExistingBinding(typeKey);
    521         Binding<T> binding = null;
    522         if (actualBinding != null) {
    523           // TODO(sameb): Consider exposing an option that will allow
    524           // ACTUAL to fallback to DEFAULT if ACTUAL's provider returns null.
    525           // Right now, an ACTUAL binding can convert from present -> absent
    526           // if it's bound to a provider that returns null.
    527           binding = actualBinding;
    528         } else if (defaultBinding != null) {
    529           binding = defaultBinding;
    530         } else if (userBinding != null) {
    531           // If neither the actual or default is set, then we fallback
    532           // to the value bound to the type itself and consider that the
    533           // "actual binding" for the SPI.
    534           binding = userBinding;
    535           actualBinding = userBinding;
    536         }
    537 
    538         if (binding != null) {
    539           optional = Optional.of(binding.getProvider());
    540           RealOptionalBinder.this.dependencies =
    541               ImmutableSet.<Dependency<?>>of(Dependency.get(binding.getKey()));
    542           RealOptionalBinder.this.providerDependencies =
    543               ImmutableSet.<Dependency<?>>of(Dependency.get(providerOf(binding.getKey())));
    544         } else {
    545           optional = Optional.absent();
    546           RealOptionalBinder.this.dependencies = ImmutableSet.of();
    547           RealOptionalBinder.this.providerDependencies = ImmutableSet.of();
    548         }
    549       }
    550 
    551       @Override public Optional<Provider<T>> get() {
    552         return optional;
    553       }
    554 
    555       @Override public Set<Dependency<?>> getDependencies() {
    556         return providerDependencies;
    557       }
    558     }
    559 
    560     final class RealOptionalKeyProvider
    561         extends RealOptionalBinderProviderWithDependencies<Optional<T>>
    562         implements ProviderWithExtensionVisitor<Optional<T>>,
    563             OptionalBinderBinding<Optional<T>>,
    564             Provider<Optional<T>> {
    565       private RealOptionalKeyProvider() {
    566         super(typeKey);
    567       }
    568 
    569       @Override public Optional<T> get() {
    570         Optional<Provider<T>> optional = optionalProviderT.get();
    571         if (optional.isPresent()) {
    572           return Optional.fromNullable(optional.get().get());
    573         } else {
    574           return Optional.absent();
    575         }
    576       }
    577 
    578       @Override public Set<Dependency<?>> getDependencies() {
    579         return dependencies;
    580       }
    581 
    582       @SuppressWarnings("unchecked")
    583       @Override
    584       public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
    585           ProviderInstanceBinding<? extends B> binding) {
    586         if (visitor instanceof MultibindingsTargetVisitor) {
    587           return ((MultibindingsTargetVisitor<Optional<T>, R>) visitor).visit(this);
    588         } else {
    589           return visitor.visit(binding);
    590         }
    591       }
    592 
    593       @Override public Key<Optional<T>> getKey() {
    594         return optionalKey;
    595       }
    596 
    597       @Override public Binding<?> getActualBinding() {
    598         return RealOptionalBinder.this.getActualBinding();
    599       }
    600 
    601       @Override public Binding<?> getDefaultBinding() {
    602         return RealOptionalBinder.this.getDefaultBinding();
    603       }
    604 
    605       @Override public boolean containsElement(Element element) {
    606         return RealOptionalBinder.this.containsElement(element);
    607       }
    608     }
    609 
    610     private Binding<?> getActualBinding() {
    611       if (isInitialized()) {
    612         return actualBinding;
    613       } else {
    614         throw new UnsupportedOperationException(
    615             "getActualBinding() not supported from Elements.getElements, requires an Injector.");
    616       }
    617     }
    618 
    619     private Binding<?> getDefaultBinding() {
    620       if (isInitialized()) {
    621         return defaultBinding;
    622       } else {
    623         throw new UnsupportedOperationException(
    624             "getDefaultBinding() not supported from Elements.getElements, requires an Injector.");
    625       }
    626     }
    627 
    628     private boolean containsElement(Element element) {
    629       Key<?> elementKey;
    630       if (element instanceof Binding) {
    631         elementKey = ((Binding<?>) element).getKey();
    632       } else if (element instanceof ProviderLookup) {
    633         elementKey = ((ProviderLookup<?>) element).getKey();
    634       } else {
    635         return false; // cannot match;
    636       }
    637 
    638       return elementKey.equals(optionalKey)
    639           || elementKey.equals(optionalProviderKey)
    640           || elementKey.equals(optionalJavaxProviderKey)
    641           || elementKey.equals(defaultKey)
    642           || elementKey.equals(actualKey)
    643           || matchesJ8Keys(elementKey)
    644           || matchesTypeKey(element, elementKey);
    645     }
    646 
    647     private boolean matchesJ8Keys(Key<?> elementKey) {
    648       if (JAVA_OPTIONAL_CLASS != null) {
    649         return elementKey.equals(javaOptionalKey)
    650             || elementKey.equals(javaOptionalProviderKey)
    651             || elementKey.equals(javaOptionalJavaxProviderKey);
    652       }
    653       return false;
    654     }
    655 
    656     /** Returns true if the key & element indicate they were bound by this OptionalBinder. */
    657     private boolean matchesTypeKey(Element element, Key<?> elementKey) {
    658       // Just doing .equals(typeKey) isn't enough, because the user can bind that themselves.
    659       return elementKey.equals(typeKey)
    660           && element instanceof ProviderInstanceBinding
    661           && (((ProviderInstanceBinding) element)
    662               .getUserSuppliedProvider() instanceof RealOptionalBinderProviderWithDependencies);
    663     }
    664 
    665     private boolean isInitialized() {
    666       return binder == null;
    667     }
    668 
    669     @Override public boolean equals(Object o) {
    670       return o instanceof RealOptionalBinder
    671           && ((RealOptionalBinder<?>) o).typeKey.equals(typeKey);
    672     }
    673 
    674     @Override public int hashCode() {
    675       return typeKey.hashCode();
    676     }
    677 
    678     /**
    679      * A base class for ProviderWithDependencies that need equality based on a specific object.
    680      */
    681     private abstract static class RealOptionalBinderProviderWithDependencies<T> implements
    682         ProviderWithDependencies<T> {
    683       private final Object equality;
    684 
    685       public RealOptionalBinderProviderWithDependencies(Object equality) {
    686         this.equality = equality;
    687       }
    688 
    689       @Override public boolean equals(Object obj) {
    690         return this.getClass() == obj.getClass()
    691             && equality.equals(((RealOptionalBinderProviderWithDependencies<?>) obj).equality);
    692       }
    693 
    694       @Override public int hashCode() {
    695         return equality.hashCode();
    696       }
    697     }
    698   }
    699 
    700   static class DefaultImpl extends BaseAnnotation implements Default {
    701     public DefaultImpl(String value) {
    702       super(Default.class, value);
    703     }
    704   }
    705 
    706   static class ActualImpl extends BaseAnnotation implements Actual {
    707     public ActualImpl(String value) {
    708       super(Actual.class, value);
    709     }
    710   }
    711 
    712   abstract static class BaseAnnotation implements Serializable, Annotation {
    713 
    714     private final String value;
    715     private final Class<? extends Annotation> clazz;
    716 
    717     BaseAnnotation(Class<? extends Annotation> clazz, String value) {
    718       this.clazz = checkNotNull(clazz, "clazz");
    719       this.value = checkNotNull(value, "value");
    720     }
    721 
    722     public String value() {
    723       return this.value;
    724     }
    725 
    726     @Override public int hashCode() {
    727       // This is specified in java.lang.Annotation.
    728       return (127 * "value".hashCode()) ^ value.hashCode();
    729     }
    730 
    731     @Override public boolean equals(Object o) {
    732       // We check against each annotation type instead of BaseAnnotation
    733       // so that we can compare against generated annotation implementations.
    734       if (o instanceof Actual && clazz == Actual.class) {
    735         Actual other = (Actual) o;
    736         return value.equals(other.value());
    737       } else if (o instanceof Default && clazz == Default.class) {
    738         Default other = (Default) o;
    739         return value.equals(other.value());
    740       }
    741       return false;
    742     }
    743 
    744     @Override public String toString() {
    745       return "@" + clazz.getName() + (value.isEmpty() ? "" : "(value=" + value + ")");
    746     }
    747 
    748     @Override public Class<? extends Annotation> annotationType() {
    749       return clazz;
    750     }
    751 
    752     private static final long serialVersionUID = 0;
    753   }
    754 }
    755