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

main.wisp.moshi.ProviderJsonAdapter.kt Maven / Gradle / Ivy

There is a newer version: 2024.11.22.172133-fe9b482
Show newest version
package wisp.moshi

import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson
import com.squareup.moshi.Types
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.lang.reflect.WildcardType
import com.google.inject.Provider as GuiceProvider
import javax.inject.Provider as JavaxProvider
import jakarta.inject.Provider as JakartaProvider

class GuiceProviderJsonAdapter(private val delegate: JsonAdapter) : JsonAdapter>() {
  @FromJson
  override fun fromJson(reader: JsonReader): GuiceProvider {
    val value = delegate.fromJson(reader)
    return GuiceProvider { value }
  }

  @ToJson
  override fun toJson(writer: JsonWriter, value: GuiceProvider?) {
    delegate.toJson(writer, value?.get())
  }
}

class JavaxProviderJsonAdapter(private val delegate: JsonAdapter) : JsonAdapter>() {
  @FromJson
  override fun fromJson(reader: JsonReader): JavaxProvider {
    val value = delegate.fromJson(reader)
    return JavaxProvider { value }
  }

  @ToJson
  override fun toJson(writer: JsonWriter, value: JavaxProvider?) {
    delegate.toJson(writer, value?.get())
  }
}

class JakartaProviderJsonAdapter(private val delegate: JsonAdapter) : JsonAdapter>() {
  @FromJson
  override fun fromJson(reader: JsonReader): JakartaProvider {
    val value = delegate.fromJson(reader)
    return JakartaProvider { value }
  }

  @ToJson
  override fun toJson(writer: JsonWriter, value: JakartaProvider?) {
    delegate.toJson(writer, value?.get())
  }
}


class ProviderJsonAdapterFactory : JsonAdapter.Factory {
  override fun create(type: Type, annotations: Set, moshi: Moshi): JsonAdapter<*>? {
    // Step 1: Check the raw type is what you want to match against
    val rawType = Types.getRawType(type)
    if (rawType != GuiceProvider::class.java && rawType != JavaxProvider::class.java && rawType != JakartaProvider::class.java) {
      return null
    }

    // Step 2: Check the type is actually parameterized
    if (type !is ParameterizedType) {
      return null
    }

    // Step 3: Extract the parameterized type's upper bound
    val providerType = getParameterUpperBound(0, type)

    // Step 4: Look up the adapter for the parameterized type
    val delegate = moshi.adapter(providerType, annotations)

    // Step 5: Wrap its adapter in the respective provider adapter
    return when (rawType) {
      GuiceProvider::class.java -> GuiceProviderJsonAdapter(delegate)
      JavaxProvider::class.java -> JavaxProviderJsonAdapter(delegate)
      JakartaProvider::class.java -> JakartaProviderJsonAdapter(delegate)
      else -> null
    }
  }

  private fun getParameterUpperBound(index: Int, type: ParameterizedType): Type {
    val types = type.actualTypeArguments
    require(!(index < 0 || index >= types.size)) { "Index " + index + " not in range [0," + types.size + ") for " + type }
    val paramType = types[index]
    if (paramType is WildcardType) {
      return paramType.upperBounds[0]
    }
    return paramType
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy