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

com.twitter.finatra.jackson.caseclass.GuiceInjectableValues.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.finatra.jackson.caseclass

import com.fasterxml.jackson.annotation.JacksonInject
import com.fasterxml.jackson.databind.BeanProperty
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.InjectableValues
import com.google.inject.ConfigurationException
import com.google.inject.Injector
import com.google.inject.Key
import com.twitter.finatra.jackson.caseclass.exceptions.InjectableValuesException
import com.twitter.util.logging.Logger
import java.lang.annotation.Annotation

private[finatra] object GuiceInjectableValues {
  type HasAnnotationType = (BeanProperty, Seq[Class[_ <: Annotation]])

  private val logger: Logger = Logger(GuiceInjectableValues.getClass)

  /**
   * We support the same annotations as the jackson-module-guice `com.fasterxml.jackson.module.guice.DefaultAnnotationIntrospector`:
   * [[JacksonInject]], [[javax.inject.Inject]], and [[com.google.inject.Inject]].
   *
   * @see [[https://github.com/FasterXML/jackson-modules-base/blob/master/guice/src/main/java/com/fasterxml/jackson/module/guice/GuiceAnnotationIntrospector.java]]
   * */
  val InjectionAnnotations: Set[Class[_ <: Annotation]] = Set(
    classOf[JacksonInject],
    classOf[javax.inject.Inject],
    classOf[com.google.inject.Inject]
  )
}

/**
 * Based on the jackson-module-guice GuiceInjectableValues but with a few differences.
 * - ensure the injector is not null before attempting to inject a value
 * - ensure that the given valueId is a com.google.inject.Key type before attempting to inject a value
 *
 * @see [[https://github.com/FasterXML/jackson-module-guice/blob/master/src/main/java/com/fasterxml/jackson/module/guice/GuiceInjectableValues.java]]
 */
private[finatra] class GuiceInjectableValues(injector: Injector) extends InjectableValues {
  import GuiceInjectableValues._

  override def findInjectableValue(
    valueId: Any,
    ctxt: DeserializationContext,
    forProperty: BeanProperty,
    beanInstance: Any
  ): AnyRef = valueId match {
    case key: Key[_] if isInjectable(forProperty) =>
      try {
        this.injector.getInstance(key).asInstanceOf[Object]
      } catch {
        case ex: ConfigurationException =>
          logger.debug(ex.getMessage, ex)
          throw InjectableValuesException(
            forProperty.getMember.getDeclaringClass,
            forProperty.getName,
            key,
            ex)
      }
    case _ =>
      null
  }

  // ensure the property is annotated with something that signals it should be injected
  private[this] def isInjectable(forProperty: BeanProperty): Boolean =
    this.injector != null && Annotations.hasAnnotation(forProperty, InjectionAnnotations.toSeq)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy