1 /* 2 * Copyright (C) 2016 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.internal; 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.internal.Errors.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.common.collect.Iterables; 29 import com.google.inject.Binder; 30 import com.google.inject.Binding; 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.internal.InternalProviderInstanceBindingImpl.InitializationTiming; 38 import com.google.inject.multibindings.MultibindingsTargetVisitor; 39 import com.google.inject.multibindings.OptionalBinderBinding; 40 import com.google.inject.spi.BindingTargetVisitor; 41 import com.google.inject.spi.Dependency; 42 import com.google.inject.spi.Element; 43 import com.google.inject.spi.ProviderInstanceBinding; 44 import com.google.inject.spi.ProviderWithExtensionVisitor; 45 import com.google.inject.util.Types; 46 import java.io.Serializable; 47 import java.lang.annotation.Annotation; 48 import java.lang.annotation.Retention; 49 import java.lang.reflect.InvocationTargetException; 50 import java.lang.reflect.Method; 51 import java.lang.reflect.Type; 52 import java.util.Set; 53 import javax.inject.Qualifier; 54 55 /** 56 * The actual OptionalBinder plays several roles. It implements Module to hide that fact from the 57 * public API, and installs the various bindings that are exposed to the user. 58 */ 59 public final class RealOptionalBinder<T> implements Module { newRealOptionalBinder(Binder binder, Key<T> type)60 public static <T> RealOptionalBinder<T> newRealOptionalBinder(Binder binder, Key<T> type) { 61 binder = binder.skipSources(RealOptionalBinder.class); 62 RealOptionalBinder<T> optionalBinder = new RealOptionalBinder<>(binder, type); 63 binder.install(optionalBinder); 64 return optionalBinder; 65 } 66 67 /* Reflectively capture java 8's Optional types so we can bind them if we're running in java8. */ 68 private static final Class<?> JAVA_OPTIONAL_CLASS; 69 private static final Object JAVA_OPTIONAL_EMPTY; 70 private static final Method JAVA_OPTIONAL_OF_METHOD; 71 72 static { 73 Class<?> optional = null; 74 Object emptyObject = null; 75 Method of = null; 76 boolean useJavaOptional = false; 77 try { 78 optional = Class.forName("java.util.Optional"); 79 emptyObject = optional.getDeclaredMethod("empty").invoke(null); 80 of = optional.getDeclaredMethod("of", Object.class); 81 // only use optional support if all our reflection succeeded 82 useJavaOptional = true; 83 } catch (ClassNotFoundException ignored) { 84 } catch (NoSuchMethodException ignored) { 85 } catch (SecurityException ignored) { 86 } catch (IllegalAccessException ignored) { 87 } catch (InvocationTargetException ignored) { 88 } 89 JAVA_OPTIONAL_CLASS = useJavaOptional ? optional : null; 90 JAVA_OPTIONAL_EMPTY = useJavaOptional ? emptyObject : null; 91 JAVA_OPTIONAL_OF_METHOD = useJavaOptional ? of : null; 92 } 93 94 /** 95 * Returns java.util.Optional.empty() if the parameter is null, calls {@link 96 * #invokeJavaOptionalOf} otherwise. 97 */ invokeJavaOptionalOfNullable(Object o)98 private static Object invokeJavaOptionalOfNullable(Object o) { 99 if (o == null) { 100 return JAVA_OPTIONAL_EMPTY; 101 } 102 return invokeJavaOptionalOf(o); 103 } 104 105 /** Invokes java.util.Optional.of. */ invokeJavaOptionalOf(Object o)106 private static Object invokeJavaOptionalOf(Object o) { 107 try { 108 return JAVA_OPTIONAL_OF_METHOD.invoke(null, o); 109 } catch (IllegalAccessException e) { 110 throw new SecurityException(e); 111 } catch (IllegalArgumentException e) { 112 throw new IllegalStateException(e); 113 } catch (InvocationTargetException e) { 114 throw Throwables.propagate(e.getCause()); 115 } 116 } 117 118 @SuppressWarnings("unchecked") optionalOf(TypeLiteral<T> type)119 static <T> TypeLiteral<Optional<T>> optionalOf(TypeLiteral<T> type) { 120 return (TypeLiteral<Optional<T>>) 121 TypeLiteral.get(Types.newParameterizedType(Optional.class, type.getType())); 122 } 123 javaOptionalOf(TypeLiteral<T> type)124 static <T> TypeLiteral<?> javaOptionalOf(TypeLiteral<T> type) { 125 checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found"); 126 return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS, type.getType())); 127 } 128 129 @SuppressWarnings("unchecked") optionalOfJavaxProvider( TypeLiteral<T> type)130 static <T> TypeLiteral<Optional<javax.inject.Provider<T>>> optionalOfJavaxProvider( 131 TypeLiteral<T> type) { 132 return (TypeLiteral<Optional<javax.inject.Provider<T>>>) 133 TypeLiteral.get( 134 Types.newParameterizedType( 135 Optional.class, newParameterizedType(javax.inject.Provider.class, type.getType()))); 136 } 137 javaOptionalOfJavaxProvider(TypeLiteral<T> type)138 static <T> TypeLiteral<?> javaOptionalOfJavaxProvider(TypeLiteral<T> type) { 139 checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found"); 140 return TypeLiteral.get( 141 Types.newParameterizedType( 142 JAVA_OPTIONAL_CLASS, 143 newParameterizedType(javax.inject.Provider.class, type.getType()))); 144 } 145 146 @SuppressWarnings("unchecked") optionalOfProvider(TypeLiteral<T> type)147 static <T> TypeLiteral<Optional<Provider<T>>> optionalOfProvider(TypeLiteral<T> type) { 148 return (TypeLiteral<Optional<Provider<T>>>) 149 TypeLiteral.get( 150 Types.newParameterizedType( 151 Optional.class, newParameterizedType(Provider.class, type.getType()))); 152 } 153 javaOptionalOfProvider(TypeLiteral<T> type)154 static <T> TypeLiteral<?> javaOptionalOfProvider(TypeLiteral<T> type) { 155 checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found"); 156 return TypeLiteral.get( 157 Types.newParameterizedType( 158 JAVA_OPTIONAL_CLASS, newParameterizedType(Provider.class, type.getType()))); 159 } 160 161 @SuppressWarnings("unchecked") providerOf(Key<T> key)162 static <T> Key<Provider<T>> providerOf(Key<T> key) { 163 Type providerT = Types.providerOf(key.getTypeLiteral().getType()); 164 return (Key<Provider<T>>) key.ofType(providerT); 165 } 166 167 enum Source { 168 DEFAULT, 169 ACTUAL 170 } 171 172 @Retention(RUNTIME) 173 @Qualifier 174 @interface Default { value()175 String value(); 176 } 177 178 @Retention(RUNTIME) 179 @Qualifier 180 @interface Actual { value()181 String value(); 182 } 183 184 private final BindingSelection<T> bindingSelection; 185 private final Binder binder; 186 RealOptionalBinder(Binder binder, Key<T> typeKey)187 private RealOptionalBinder(Binder binder, Key<T> typeKey) { 188 this.bindingSelection = new BindingSelection<>(typeKey); 189 this.binder = binder; 190 } 191 192 /** 193 * Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate 194 * bindings. 195 */ addDirectTypeBinding(Binder binder)196 private void addDirectTypeBinding(Binder binder) { 197 binder 198 .bind(bindingSelection.getDirectKey()) 199 .toProvider(new RealDirectTypeProvider<T>(bindingSelection)); 200 } 201 202 /** 203 * Returns the key to use for the default binding. 204 * 205 * <p>As a side effect this installs support for the 'direct type', so a binding for {@code T} 206 * will be made available. 207 */ getKeyForDefaultBinding()208 Key<T> getKeyForDefaultBinding() { 209 bindingSelection.checkNotInitialized(); 210 addDirectTypeBinding(binder); 211 return bindingSelection.getKeyForDefaultBinding(); 212 } 213 setDefault()214 public LinkedBindingBuilder<T> setDefault() { 215 return binder.bind(getKeyForDefaultBinding()); 216 } 217 218 /** 219 * Returns the key to use for the actual binding, overrides the default if set. 220 * 221 * <p>As a side effect this installs support for the 'direct type', so a binding for {@code T} 222 * will be made available. 223 */ getKeyForActualBinding()224 Key<T> getKeyForActualBinding() { 225 bindingSelection.checkNotInitialized(); 226 addDirectTypeBinding(binder); 227 return bindingSelection.getKeyForActualBinding(); 228 } 229 setBinding()230 public LinkedBindingBuilder<T> setBinding() { 231 return binder.bind(getKeyForActualBinding()); 232 } 233 234 @Override configure(Binder binder)235 public void configure(Binder binder) { 236 bindingSelection.checkNotInitialized(); 237 Key<T> key = bindingSelection.getDirectKey(); 238 // Every OptionalBinder get's the following types bound 239 // * Optional<Provider<T>> 240 // * Optional<javax.inject.Provider<T>> 241 // * Optional<T> 242 // If setDefault() or setBinding() is called then also 243 // * T is bound 244 // If java.util.Optional is on the classpath (because this is a jdk8+ vm), then you also get 245 // * java.util.Optional<Provider<T>> 246 // * java.util.Optional<javax.inject.Provider<T>> 247 // * java.util.Optional<T> 248 InternalProviderInstanceBindingImpl.Factory<Optional<Provider<T>>> optionalProviderFactory = 249 new RealOptionalProviderProvider<T>(bindingSelection); 250 binder 251 .bind(key.ofType(optionalOfProvider(key.getTypeLiteral()))) 252 .toProvider(optionalProviderFactory); 253 254 // Provider is assignable to javax.inject.Provider and the provider that the factory contains 255 // cannot be modified so we can use some rawtypes hackery to share the same implementation. 256 @SuppressWarnings("unchecked") 257 InternalProviderInstanceBindingImpl.Factory<Optional<javax.inject.Provider<T>>> 258 optionalJavaxProviderFactory = 259 (InternalProviderInstanceBindingImpl.Factory) optionalProviderFactory; 260 binder 261 .bind(key.ofType(optionalOfJavaxProvider(key.getTypeLiteral()))) 262 .toProvider(optionalJavaxProviderFactory); 263 264 Key<Optional<T>> optionalKey = key.ofType(optionalOf(key.getTypeLiteral())); 265 binder 266 .bind(optionalKey) 267 .toProvider(new RealOptionalKeyProvider<T>(bindingSelection, optionalKey)); 268 269 // Bind the java-8 types if we know them. 270 bindJava8Optional(binder); 271 } 272 273 @SuppressWarnings("unchecked") bindJava8Optional(Binder binder)274 private void bindJava8Optional(Binder binder) { 275 if (JAVA_OPTIONAL_CLASS != null) { 276 Key<?> key = bindingSelection.getDirectKey(); 277 TypeLiteral<?> typeLiteral = key.getTypeLiteral(); 278 InternalProviderInstanceBindingImpl.Factory<Object> javaOptionalProviderFactory = 279 new JavaOptionalProviderProvider(bindingSelection); 280 binder 281 .bind(key.ofType(javaOptionalOfProvider(typeLiteral))) 282 .toProvider((Provider) javaOptionalProviderFactory); 283 // Provider is assignable to javax.inject.Provider and the provider that the factory contains 284 // cannot be modified so we can use some rawtypes hackery to share the same implementation. 285 binder 286 .bind(key.ofType(javaOptionalOfJavaxProvider(typeLiteral))) 287 .toProvider((Provider) javaOptionalProviderFactory); 288 Key<?> javaOptionalKey = key.ofType(javaOptionalOf(typeLiteral)); 289 binder 290 .bind(javaOptionalKey) 291 .toProvider(new JavaOptionalProvider(bindingSelection, javaOptionalKey)); 292 } 293 } 294 295 /** Provides the binding for java.util.Optional<T>. */ 296 @SuppressWarnings({"rawtypes", "unchecked"}) 297 private static final class JavaOptionalProvider extends RealOptionalBinderProviderWithDependencies 298 implements ProviderWithExtensionVisitor, OptionalBinderBinding { 299 300 private final Key<?> optionalKey; 301 302 private Dependency<?> targetDependency; 303 private InternalFactory<?> target; 304 JavaOptionalProvider(BindingSelection<?> bindingSelection, Key<?> optionalKey)305 JavaOptionalProvider(BindingSelection<?> bindingSelection, Key<?> optionalKey) { 306 super(bindingSelection); 307 this.optionalKey = optionalKey; 308 } 309 310 @Override doInitialize()311 void doInitialize() { 312 if (bindingSelection.getBinding() != null) { 313 target = bindingSelection.getBinding().getInternalFactory(); 314 targetDependency = bindingSelection.getDependency(); 315 } 316 } 317 318 @Override doProvision(InternalContext context, Dependency dependency)319 protected Object doProvision(InternalContext context, Dependency dependency) 320 throws InternalProvisionException { 321 InternalFactory<?> local = target; 322 if (local == null) { 323 return JAVA_OPTIONAL_EMPTY; 324 } 325 Dependency<?> localDependency = targetDependency; 326 Object result; 327 Dependency previous = context.pushDependency(localDependency, getSource()); 328 329 try { 330 // See comments in RealOptionalKeyProvider, about how localDependency may be more specific 331 // than what we actually need. 332 result = local.get(context, localDependency, false); 333 } catch (InternalProvisionException ipe) { 334 throw ipe.addSource(localDependency); 335 } finally { 336 context.popStateAndSetDependency(previous); 337 338 } 339 return invokeJavaOptionalOfNullable(result); 340 } 341 342 @Override getDependencies()343 public Set<Dependency<?>> getDependencies() { 344 return bindingSelection.dependencies; 345 } 346 347 @SuppressWarnings("unchecked") 348 @Override acceptExtensionVisitor( BindingTargetVisitor visitor, ProviderInstanceBinding binding)349 public Object acceptExtensionVisitor( 350 BindingTargetVisitor visitor, ProviderInstanceBinding binding) { 351 if (visitor instanceof MultibindingsTargetVisitor) { 352 return ((MultibindingsTargetVisitor) visitor).visit(this); 353 } else { 354 return visitor.visit(binding); 355 } 356 } 357 358 @Override containsElement(Element element)359 public boolean containsElement(Element element) { 360 return bindingSelection.containsElement(element); 361 } 362 363 @Override getActualBinding()364 public Binding<?> getActualBinding() { 365 return bindingSelection.getActualBinding(); 366 } 367 368 @Override getDefaultBinding()369 public Binding<?> getDefaultBinding() { 370 return bindingSelection.getDefaultBinding(); 371 } 372 373 @Override getKey()374 public Key getKey() { 375 return optionalKey; 376 } 377 } 378 379 /** Provides the binding for java.util.Optional<Provider<T>>. */ 380 @SuppressWarnings({"rawtypes", "unchecked"}) 381 private static final class JavaOptionalProviderProvider 382 extends RealOptionalBinderProviderWithDependencies { 383 private Object value; 384 JavaOptionalProviderProvider(BindingSelection<?> bindingSelection)385 JavaOptionalProviderProvider(BindingSelection<?> bindingSelection) { 386 super(bindingSelection); 387 } 388 389 @Override doInitialize()390 void doInitialize() { 391 if (bindingSelection.getBinding() == null) { 392 value = JAVA_OPTIONAL_EMPTY; 393 } else { 394 value = invokeJavaOptionalOf(bindingSelection.getBinding().getProvider()); 395 } 396 } 397 398 @Override doProvision(InternalContext context, Dependency dependency)399 protected Object doProvision(InternalContext context, Dependency dependency) { 400 return value; 401 } 402 403 @Override getDependencies()404 public Set<Dependency<?>> getDependencies() { 405 return bindingSelection.providerDependencies(); 406 } 407 } 408 409 /** Provides the binding for T, conditionally installed by calling setBinding/setDefault. */ 410 private static final class RealDirectTypeProvider<T> 411 extends RealOptionalBinderProviderWithDependencies<T, T> { 412 private Key<? extends T> targetKey; 413 414 private Object targetSource; 415 416 private InternalFactory<? extends T> targetFactory; 417 RealDirectTypeProvider(BindingSelection<T> bindingSelection)418 RealDirectTypeProvider(BindingSelection<T> bindingSelection) { 419 super(bindingSelection); 420 } 421 422 @Override doInitialize()423 void doInitialize() { 424 BindingImpl<T> targetBinding = bindingSelection.getBinding(); 425 // we only install this factory if they call setBinding()/setDefault() so we know that 426 // targetBinding will be non-null. 427 this.targetKey = targetBinding.getKey(); 428 this.targetSource = targetBinding.getSource(); 429 this.targetFactory = targetBinding.getInternalFactory(); 430 } 431 432 @Override doProvision(InternalContext context, Dependency<?> dependency)433 protected T doProvision(InternalContext context, Dependency<?> dependency) 434 throws InternalProvisionException { 435 // This is what linked bindings do (see FactoryProxy), and we are pretty similar. 436 context.pushState(targetKey, targetSource); 437 438 try { 439 return targetFactory.get(context, dependency, true); 440 } catch (InternalProvisionException ipe) { 441 throw ipe.addSource(targetKey); 442 } finally { 443 context.popState(); 444 445 } 446 } 447 448 @Override getDependencies()449 public Set<Dependency<?>> getDependencies() { 450 return bindingSelection.dependencies; 451 } 452 } 453 454 /** Provides the binding for Optional<Provider<T>>. */ 455 private static final class RealOptionalProviderProvider<T> 456 extends RealOptionalBinderProviderWithDependencies<T, Optional<Provider<T>>> { 457 private Optional<Provider<T>> value; 458 RealOptionalProviderProvider(BindingSelection<T> bindingSelection)459 RealOptionalProviderProvider(BindingSelection<T> bindingSelection) { 460 super(bindingSelection); 461 } 462 463 @Override doInitialize()464 void doInitialize() { 465 if (bindingSelection.getBinding() == null) { 466 value = Optional.absent(); 467 } else { 468 value = Optional.of(bindingSelection.getBinding().getProvider()); 469 } 470 } 471 472 @Override doProvision(InternalContext context, Dependency<?> dependency)473 protected Optional<Provider<T>> doProvision(InternalContext context, Dependency<?> dependency) { 474 return value; 475 } 476 477 @Override getDependencies()478 public Set<Dependency<?>> getDependencies() { 479 return bindingSelection.providerDependencies(); 480 } 481 } 482 483 /** Provides the binding for Optional<T>. */ 484 private static final class RealOptionalKeyProvider<T> 485 extends RealOptionalBinderProviderWithDependencies<T, Optional<T>> 486 implements ProviderWithExtensionVisitor<Optional<T>>, OptionalBinderBinding<Optional<T>> { 487 488 private final Key<Optional<T>> optionalKey; 489 490 // These are assigned to non-null values during initialization if and only if we have a binding 491 // to delegate to. 492 private Dependency<?> targetDependency; 493 private InternalFactory<? extends T> delegate; 494 RealOptionalKeyProvider(BindingSelection<T> bindingSelection, Key<Optional<T>> optionalKey)495 RealOptionalKeyProvider(BindingSelection<T> bindingSelection, Key<Optional<T>> optionalKey) { 496 super(bindingSelection); 497 this.optionalKey = optionalKey; 498 } 499 500 @Override doInitialize()501 void doInitialize() { 502 if (bindingSelection.getBinding() != null) { 503 delegate = bindingSelection.getBinding().getInternalFactory(); 504 targetDependency = bindingSelection.getDependency(); 505 } 506 } 507 508 @Override doProvision(InternalContext context, Dependency<?> currentDependency)509 protected Optional<T> doProvision(InternalContext context, Dependency<?> currentDependency) 510 throws InternalProvisionException { 511 InternalFactory<? extends T> local = delegate; 512 if (local == null) { 513 return Optional.absent(); 514 } 515 Dependency<?> localDependency = targetDependency; 516 T result; 517 Dependency previous = context.pushDependency(localDependency, getSource()); 518 519 try { 520 // currentDependency is Optional<? super T>, so we really just need to set the target 521 // dependency to ? super T, but we are currently setting it to T. We could hypothetically 522 // make it easier for our delegate to generate proxies by modifying the dependency, but that 523 // would also require us to rewrite the key on each call. So for now we don't do it. 524 result = local.get(context, localDependency, false); 525 } catch (InternalProvisionException ipe) { 526 throw ipe.addSource(localDependency); 527 } finally { 528 context.popStateAndSetDependency(previous); 529 530 } 531 return Optional.fromNullable(result); 532 } 533 534 @Override getDependencies()535 public Set<Dependency<?>> getDependencies() { 536 return bindingSelection.dependencies(); 537 } 538 539 @SuppressWarnings("unchecked") 540 @Override acceptExtensionVisitor( BindingTargetVisitor<B, R> visitor, ProviderInstanceBinding<? extends B> binding)541 public <B, R> R acceptExtensionVisitor( 542 BindingTargetVisitor<B, R> visitor, ProviderInstanceBinding<? extends B> binding) { 543 if (visitor instanceof MultibindingsTargetVisitor) { 544 return ((MultibindingsTargetVisitor<Optional<T>, R>) visitor).visit(this); 545 } else { 546 return visitor.visit(binding); 547 } 548 } 549 550 @Override getKey()551 public Key<Optional<T>> getKey() { 552 return optionalKey; 553 } 554 555 @Override getActualBinding()556 public Binding<?> getActualBinding() { 557 return bindingSelection.getActualBinding(); 558 } 559 560 @Override getDefaultBinding()561 public Binding<?> getDefaultBinding() { 562 return bindingSelection.getDefaultBinding(); 563 } 564 565 @Override containsElement(Element element)566 public boolean containsElement(Element element) { 567 return bindingSelection.containsElement(element); 568 } 569 } 570 571 /** 572 * A helper object that implements the core logic for deciding what the implementation of the 573 * binding will be. 574 * 575 * <p>This also implements the main OptionalBinderBinding logic. 576 */ 577 private static final class BindingSelection<T> { 578 private static final ImmutableSet<Dependency<?>> MODULE_DEPENDENCIES = 579 ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class))); 580 581 /*@Nullable */ BindingImpl<T> actualBinding; 582 /*@Nullable */ BindingImpl<T> defaultBinding; 583 /*@Nullable */ BindingImpl<T> binding; 584 private boolean initialized; 585 private final Key<T> key; 586 587 // Until the injector initializes us, we don't know what our dependencies are, 588 // so initialize to the whole Injector (like Multibinder, and MapBinder indirectly). 589 private ImmutableSet<Dependency<?>> dependencies = MODULE_DEPENDENCIES; 590 private ImmutableSet<Dependency<?>> providerDependencies = MODULE_DEPENDENCIES; 591 592 /** lazily allocated, by {@link #getBindingName}. */ 593 private String bindingName; 594 595 /** lazily allocated, by {@link #getKeyForDefaultBinding}. */ 596 private Key<T> defaultBindingKey; 597 598 /** lazily allocated, by {@link #getKeyForActualBinding}. */ 599 private Key<T> actualBindingKey; 600 BindingSelection(Key<T> key)601 BindingSelection(Key<T> key) { 602 this.key = key; 603 } 604 checkNotInitialized()605 void checkNotInitialized() { 606 checkConfiguration(!initialized, "already initialized"); 607 } 608 initialize(InjectorImpl injector)609 void initialize(InjectorImpl injector) { 610 // Every one of our providers will call this method, so only execute the logic once. 611 if (initialized) { 612 return; 613 } 614 615 actualBinding = injector.getExistingBinding(getKeyForActualBinding()); 616 defaultBinding = injector.getExistingBinding(getKeyForDefaultBinding()); 617 // We should never create Jit bindings, but we can use them if some other binding created it. 618 BindingImpl<T> userBinding = injector.getExistingBinding(key); 619 if (actualBinding != null) { 620 // TODO(sameb): Consider exposing an option that will allow 621 // ACTUAL to fallback to DEFAULT if ACTUAL's provider returns null. 622 // Right now, an ACTUAL binding can convert from present -> absent 623 // if it's bound to a provider that returns null. 624 binding = actualBinding; 625 } else if (defaultBinding != null) { 626 binding = defaultBinding; 627 } else if (userBinding != null) { 628 // If neither the actual or default is set, then we fallback 629 // to the value bound to the type itself and consider that the 630 // "actual binding" for the SPI. 631 binding = userBinding; 632 actualBinding = userBinding; 633 } 634 if (binding != null) { 635 dependencies = ImmutableSet.<Dependency<?>>of(Dependency.get(binding.getKey())); 636 providerDependencies = 637 ImmutableSet.<Dependency<?>>of(Dependency.get(providerOf(binding.getKey()))); 638 } else { 639 dependencies = ImmutableSet.of(); 640 providerDependencies = ImmutableSet.of(); 641 } 642 initialized = true; 643 } 644 getKeyForDefaultBinding()645 Key<T> getKeyForDefaultBinding() { 646 if (defaultBindingKey == null) { 647 defaultBindingKey = Key.get(key.getTypeLiteral(), new DefaultImpl(getBindingName())); 648 } 649 return defaultBindingKey; 650 } 651 getKeyForActualBinding()652 Key<T> getKeyForActualBinding() { 653 if (actualBindingKey == null) { 654 actualBindingKey = Key.get(key.getTypeLiteral(), new ActualImpl(getBindingName())); 655 } 656 return actualBindingKey; 657 } 658 getDirectKey()659 Key<T> getDirectKey() { 660 return key; 661 } 662 getBindingName()663 private String getBindingName() { 664 // Lazily allocated, most instantiations will never need this because they are deduped during 665 // module installation. 666 if (bindingName == null) { 667 bindingName = Annotations.nameOf(key); 668 } 669 return bindingName; 670 } 671 getBinding()672 BindingImpl<T> getBinding() { 673 return binding; 674 } 675 676 // Provide default implementations for most of the OptionalBinderBinding interface getDefaultBinding()677 BindingImpl<T> getDefaultBinding() { 678 return defaultBinding; 679 } 680 getActualBinding()681 BindingImpl<T> getActualBinding() { 682 return actualBinding; 683 } 684 providerDependencies()685 ImmutableSet<Dependency<?>> providerDependencies() { 686 return providerDependencies; 687 } 688 dependencies()689 ImmutableSet<Dependency<?>> dependencies() { 690 return dependencies; 691 } 692 693 /** 694 * Returns the Dependency for the target binding, throws NoSuchElementException if no target 695 * exists. 696 * 697 * <p>Calls to this method should typically be guarded by checking if {@link #getBinding()} 698 * returns {@code null}. 699 */ getDependency()700 Dependency<?> getDependency() { 701 return Iterables.getOnlyElement(dependencies); 702 } 703 704 /** Implementation of {@link OptionalBinderBinding#containsElement}. */ containsElement(Element element)705 boolean containsElement(Element element) { 706 // All of our bindings are ProviderInstanceBindings whose providers extend 707 // RealOptionalBinderProviderWithDependencies and have 'this' as its binding selection. 708 if (element instanceof ProviderInstanceBinding) { 709 javax.inject.Provider<?> providerInstance = 710 ((ProviderInstanceBinding<?>) element).getUserSuppliedProvider(); 711 if (providerInstance instanceof RealOptionalBinderProviderWithDependencies) { 712 return ((RealOptionalBinderProviderWithDependencies<?, ?>) providerInstance) 713 .bindingSelection.equals(this); 714 } 715 } 716 if (element instanceof Binding) { 717 Key<?> elementKey = ((Binding) element).getKey(); 718 // if it isn't one of the things we bound directly it might be an actual or default key 719 return elementKey.equals(getKeyForActualBinding()) 720 || elementKey.equals(getKeyForDefaultBinding()); 721 } 722 return false; // cannot match; 723 } 724 725 @Override equals(Object o)726 public boolean equals(Object o) { 727 return o instanceof BindingSelection && ((BindingSelection) o).key.equals(key); 728 } 729 730 @Override hashCode()731 public int hashCode() { 732 return key.hashCode(); 733 } 734 } 735 736 @Override equals(Object o)737 public boolean equals(Object o) { 738 return o instanceof RealOptionalBinder 739 && ((RealOptionalBinder<?>) o).bindingSelection.equals(bindingSelection); 740 } 741 742 @Override hashCode()743 public int hashCode() { 744 return bindingSelection.hashCode(); 745 } 746 747 /** A base class for ProviderWithDependencies that need equality based on a specific object. */ 748 private abstract static class RealOptionalBinderProviderWithDependencies<T, P> 749 extends InternalProviderInstanceBindingImpl.Factory<P> { 750 protected final BindingSelection<T> bindingSelection; 751 RealOptionalBinderProviderWithDependencies(BindingSelection<T> bindingSelection)752 RealOptionalBinderProviderWithDependencies(BindingSelection<T> bindingSelection) { 753 // We need delayed initialization so we can detect jit bindings created by other bindings 754 // while not also creating jit bindings ourselves. This ensures we only pick up user bindings 755 // if the binding would have existed in the injector statically. 756 super(InitializationTiming.DELAYED); 757 this.bindingSelection = bindingSelection; 758 } 759 760 @Override initialize(InjectorImpl injector, Errors errors)761 final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException { 762 bindingSelection.initialize(injector); 763 doInitialize(); 764 } 765 766 /** 767 * Initialize the factory. BindingSelection is guaranteed to be initialized at this point and 768 * this will be called prior to any provisioning. 769 */ doInitialize()770 abstract void doInitialize(); 771 772 @Override equals(Object obj)773 public boolean equals(Object obj) { 774 return obj != null 775 && this.getClass() == obj.getClass() 776 && bindingSelection.equals( 777 ((RealOptionalBinderProviderWithDependencies<?, ?>) obj).bindingSelection); 778 } 779 780 @Override hashCode()781 public int hashCode() { 782 return bindingSelection.hashCode(); 783 } 784 } 785 786 static class DefaultImpl extends BaseAnnotation implements Default { DefaultImpl(String value)787 public DefaultImpl(String value) { 788 super(Default.class, value); 789 } 790 } 791 792 static class ActualImpl extends BaseAnnotation implements Actual { ActualImpl(String value)793 public ActualImpl(String value) { 794 super(Actual.class, value); 795 } 796 } 797 798 abstract static class BaseAnnotation implements Serializable, Annotation { 799 800 private final String value; 801 private final Class<? extends Annotation> clazz; 802 BaseAnnotation(Class<? extends Annotation> clazz, String value)803 BaseAnnotation(Class<? extends Annotation> clazz, String value) { 804 this.clazz = checkNotNull(clazz, "clazz"); 805 this.value = checkNotNull(value, "value"); 806 } 807 value()808 public String value() { 809 return this.value; 810 } 811 812 @Override hashCode()813 public int hashCode() { 814 // This is specified in java.lang.Annotation. 815 return (127 * "value".hashCode()) ^ value.hashCode(); 816 } 817 818 @Override equals(Object o)819 public boolean equals(Object o) { 820 // We check against each annotation type instead of BaseAnnotation 821 // so that we can compare against generated annotation implementations. 822 if (o instanceof Actual && clazz == Actual.class) { 823 Actual other = (Actual) o; 824 return value.equals(other.value()); 825 } else if (o instanceof Default && clazz == Default.class) { 826 Default other = (Default) o; 827 return value.equals(other.value()); 828 } 829 return false; 830 } 831 832 @Override toString()833 public String toString() { 834 return "@" + clazz.getName() + (value.isEmpty() ? "" : "(value=" + value + ")"); 835 } 836 837 @Override annotationType()838 public Class<? extends Annotation> annotationType() { 839 return clazz; 840 } 841 842 private static final long serialVersionUID = 0; 843 } 844 } 845