Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.inject.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.inject.internal.Errors.checkConfiguration;
import static com.google.inject.util.Types.newParameterizedType;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.internal.InternalProviderInstanceBindingImpl.InitializationTiming;
import com.google.inject.multibindings.MultibindingsTargetVisitor;
import com.google.inject.multibindings.OptionalBinderBinding;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.Element;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.util.Types;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Set;
import javax.inject.Qualifier;
/**
* The actual OptionalBinder plays several roles. It implements Module to hide that fact from the
* public API, and installs the various bindings that are exposed to the user.
*/
public final class RealOptionalBinder implements Module {
public static RealOptionalBinder newRealOptionalBinder(Binder binder, Key type) {
binder = binder.skipSources(RealOptionalBinder.class);
RealOptionalBinder optionalBinder = new RealOptionalBinder<>(binder, type);
binder.install(optionalBinder);
return optionalBinder;
}
/* Reflectively capture java 8's Optional types so we can bind them if we're running in java8. */
private static final Class> JAVA_OPTIONAL_CLASS;
private static final Object JAVA_OPTIONAL_EMPTY;
private static final Method JAVA_OPTIONAL_OF_METHOD;
static {
Class> optional = null;
Object emptyObject = null;
Method of = null;
boolean useJavaOptional = false;
try {
optional = Class.forName("java.util.Optional");
emptyObject = optional.getDeclaredMethod("empty").invoke(null);
of = optional.getDeclaredMethod("of", Object.class);
// only use optional support if all our reflection succeeded
useJavaOptional = true;
} catch (ClassNotFoundException ignored) {
} catch (NoSuchMethodException ignored) {
} catch (SecurityException ignored) {
} catch (IllegalAccessException ignored) {
} catch (InvocationTargetException ignored) {
}
JAVA_OPTIONAL_CLASS = useJavaOptional ? optional : null;
JAVA_OPTIONAL_EMPTY = useJavaOptional ? emptyObject : null;
JAVA_OPTIONAL_OF_METHOD = useJavaOptional ? of : null;
}
/**
* Returns java.util.Optional.empty() if the parameter is null, calls {@link
* #invokeJavaOptionalOf} otherwise.
*/
private static Object invokeJavaOptionalOfNullable(Object o) {
if (o == null) {
return JAVA_OPTIONAL_EMPTY;
}
return invokeJavaOptionalOf(o);
}
/** Invokes java.util.Optional.of. */
private static Object invokeJavaOptionalOf(Object o) {
try {
return JAVA_OPTIONAL_OF_METHOD.invoke(null, o);
} catch (IllegalAccessException e) {
throw new SecurityException(e);
} catch (IllegalArgumentException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw Throwables.propagate(e.getCause());
}
}
@SuppressWarnings("unchecked")
static TypeLiteral> optionalOf(TypeLiteral type) {
return (TypeLiteral>)
TypeLiteral.get(Types.newParameterizedType(Optional.class, type.getType()));
}
static TypeLiteral> javaOptionalOf(TypeLiteral type) {
checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS, type.getType()));
}
@SuppressWarnings("unchecked")
static TypeLiteral>> optionalOfJavaxProvider(
TypeLiteral type) {
return (TypeLiteral>>)
TypeLiteral.get(
Types.newParameterizedType(
Optional.class, newParameterizedType(javax.inject.Provider.class, type.getType())));
}
static TypeLiteral> javaOptionalOfJavaxProvider(TypeLiteral type) {
checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
return TypeLiteral.get(
Types.newParameterizedType(
JAVA_OPTIONAL_CLASS,
newParameterizedType(javax.inject.Provider.class, type.getType())));
}
@SuppressWarnings("unchecked")
static TypeLiteral>> optionalOfProvider(TypeLiteral type) {
return (TypeLiteral>>)
TypeLiteral.get(
Types.newParameterizedType(
Optional.class, newParameterizedType(Provider.class, type.getType())));
}
static TypeLiteral> javaOptionalOfProvider(TypeLiteral type) {
checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
return TypeLiteral.get(
Types.newParameterizedType(
JAVA_OPTIONAL_CLASS, newParameterizedType(Provider.class, type.getType())));
}
@SuppressWarnings("unchecked")
static Key> providerOf(Key key) {
Type providerT = Types.providerOf(key.getTypeLiteral().getType());
return (Key>) key.ofType(providerT);
}
enum Source {
DEFAULT,
ACTUAL
}
@Retention(RUNTIME)
@Qualifier
@interface Default {
String value();
}
@Retention(RUNTIME)
@Qualifier
@interface Actual {
String value();
}
private final BindingSelection bindingSelection;
private final Binder binder;
private RealOptionalBinder(Binder binder, Key typeKey) {
this.bindingSelection = new BindingSelection<>(typeKey);
this.binder = binder;
}
/**
* Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate
* bindings.
*/
private void addDirectTypeBinding(Binder binder) {
binder
.bind(bindingSelection.getDirectKey())
.toProvider(new RealDirectTypeProvider(bindingSelection));
}
/**
* Returns the key to use for the default binding.
*
*
As a side effect this installs support for the 'direct type', so a binding for {@code T}
* will be made available.
*/
Key getKeyForDefaultBinding() {
bindingSelection.checkNotInitialized();
addDirectTypeBinding(binder);
return bindingSelection.getKeyForDefaultBinding();
}
public LinkedBindingBuilder setDefault() {
return binder.bind(getKeyForDefaultBinding());
}
/**
* Returns the key to use for the actual binding, overrides the default if set.
*
*
As a side effect this installs support for the 'direct type', so a binding for {@code T}
* will be made available.
*/
Key getKeyForActualBinding() {
bindingSelection.checkNotInitialized();
addDirectTypeBinding(binder);
return bindingSelection.getKeyForActualBinding();
}
public LinkedBindingBuilder setBinding() {
return binder.bind(getKeyForActualBinding());
}
@Override
public void configure(Binder binder) {
bindingSelection.checkNotInitialized();
Key key = bindingSelection.getDirectKey();
// Every OptionalBinder get's the following types bound
// * Optional>
// * Optional>
// * Optional
// If setDefault() or setBinding() is called then also
// * T is bound
// If java.util.Optional is on the classpath (because this is a jdk8+ vm), then you also get
// * java.util.Optional>
// * java.util.Optional>
// * java.util.Optional
InternalProviderInstanceBindingImpl.Factory>> optionalProviderFactory =
new RealOptionalProviderProvider(bindingSelection);
binder
.bind(key.ofType(optionalOfProvider(key.getTypeLiteral())))
.toProvider(optionalProviderFactory);
// Provider is assignable to javax.inject.Provider and the provider that the factory contains
// cannot be modified so we can use some rawtypes hackery to share the same implementation.
@SuppressWarnings("unchecked")
InternalProviderInstanceBindingImpl.Factory>>
optionalJavaxProviderFactory =
(InternalProviderInstanceBindingImpl.Factory) optionalProviderFactory;
binder
.bind(key.ofType(optionalOfJavaxProvider(key.getTypeLiteral())))
.toProvider(optionalJavaxProviderFactory);
Key> optionalKey = key.ofType(optionalOf(key.getTypeLiteral()));
binder
.bind(optionalKey)
.toProvider(new RealOptionalKeyProvider(bindingSelection, optionalKey));
// Bind the java-8 types if we know them.
bindJava8Optional(binder);
}
@SuppressWarnings("unchecked")
private void bindJava8Optional(Binder binder) {
if (JAVA_OPTIONAL_CLASS != null) {
Key> key = bindingSelection.getDirectKey();
TypeLiteral> typeLiteral = key.getTypeLiteral();
InternalProviderInstanceBindingImpl.Factory