All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.inject.assistedinject.Parameter Maven / Gradle / Ivy

/*
 * Copyright (C) 2007 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.assistedinject;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.internal.Annotations;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Models a method or constructor parameter.
 *
 * @author [email protected] (Jerome Mourits)
 * @author [email protected] (Jesse Wilson)
 */
class Parameter {

  private final Type type;
  private final boolean isAssisted;
  private final Annotation bindingAnnotation;
  private final boolean isProvider;

  private volatile Provider provider;

  public Parameter(Type type, Annotation[] annotations) {
    this.type = type;
    this.bindingAnnotation = getBindingAnnotation(annotations);
    this.isAssisted = hasAssistedAnnotation(annotations);
    this.isProvider = isProvider(type);
  }

  public boolean isProvidedByFactory() {
    return isAssisted;
  }

  public Type getType() {
    return type;
  }

  @Override
  public String toString() {
    StringBuilder result = new StringBuilder();
    if (isAssisted) {
      result.append("@Assisted ");
    }
    if (bindingAnnotation != null) {
      result.append(bindingAnnotation).append(" ");
    }
    return result.append(type).toString();
  }

  private boolean hasAssistedAnnotation(Annotation[] annotations) {
    for (Annotation annotation : annotations) {
      if (annotation.annotationType().equals(Assisted.class)) {
        return true;
      }
    }
    return false;
  }

  /** Returns the Guice {@link Key} for this parameter. */
  public Object getValue(Injector injector) {
    if (null == provider) {
      synchronized (this) {
        if (null == provider) {
          provider =
              isProvider
                  ? injector.getProvider(getBindingForType(getProvidedType(type)))
                  : injector.getProvider(getPrimaryBindingKey());
        }
      }
    }

    return isProvider ? provider : provider.get();
  }

  public boolean isBound(Injector injector) {
    return isBound(injector, getPrimaryBindingKey())
        || isBound(injector, fixAnnotations(getPrimaryBindingKey()));
  }

  private boolean isBound(Injector injector, Key key) {
    // This method is particularly lame - we really need an API that can test
    // for any binding, implicit or explicit
    try {
      return injector.getBinding(key) != null;
    } catch (ConfigurationException e) {
      return false;
    }
  }

  /**
   * Replace annotation instances with annotation types, this is only appropriate for testing if a
   * key is bound and not for injecting.
   *
   * 

See Guice bug 125, https://github.com/google/guice/issues/125 */ public Key fixAnnotations(Key key) { return key.getAnnotation() == null ? key : Key.get(key.getTypeLiteral(), key.getAnnotation().annotationType()); } Key getPrimaryBindingKey() { return isProvider ? getBindingForType(getProvidedType(type)) : getBindingForType(type); } private Type getProvidedType(Type type) { return ((ParameterizedType) type).getActualTypeArguments()[0]; } private boolean isProvider(Type type) { return type instanceof ParameterizedType && ((ParameterizedType) type).getRawType() == Provider.class; } private Key getBindingForType(Type type) { return bindingAnnotation != null ? Key.get(type, bindingAnnotation) : Key.get(type); } /** * Returns the unique binding annotation from the specified list, or {@code null} if there are * none. * * @throws IllegalStateException if multiple binding annotations exist. */ private Annotation getBindingAnnotation(Annotation[] annotations) { Annotation bindingAnnotation = null; for (Annotation annotation : annotations) { if (Annotations.isBindingAnnotation(annotation.annotationType())) { checkArgument( bindingAnnotation == null, "Parameter has multiple binding annotations: %s and %s", bindingAnnotation, annotation); bindingAnnotation = annotation; } } return bindingAnnotation; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy