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

com.trendyol.kediatr.Registrar.kt Maven / Gradle / Ivy

package com.trendyol.kediatr

import java.lang.reflect.*

@Suppress("UNCHECKED_CAST")
abstract class Registrar {
  protected inline fun  registerFor(
    dependencyProvider: DependencyProvider,
    registrar: (key: Class, value: Class) -> Unit
  ) = dependencyProvider.getSubTypesOf(THandler::class.java).forEach {
    registerFor(it) { key, value ->
      registrar(key as Class, value as Class)
    }
  }

  protected inline fun  registerFor(
    handler: Class<*>,
    registrar: (key: Class<*>, value: Class<*>) -> Unit
  ) {
    val interfaceOrBaseClass = THandler::class.java
    if (!interfaceOrBaseClass.isAssignableFrom(handler)) return

    handler.genericInterfaces
      .filterIsInstance()
      .map { extractParameter(it) }
      .forEach { registrar(it, handler) }

    when (handler.genericSuperclass) {
      is ParameterizedType -> {
        val inheritedHandler = (handler.genericSuperclass as ParameterizedType).rawType as Class<*>
        inheritedHandler.genericInterfaces
          .filterIsInstance()
          .map { extractParameter(handler.genericSuperclass as ParameterizedType) }
          .forEach { registrar(it, handler) }
      }

      is Class<*> -> {
        val inheritedHandler = handler.genericSuperclass as Class<*>
        if (interfaceOrBaseClass.isAssignableFrom(inheritedHandler)) {
          inheritedHandler.genericInterfaces
            .filterIsInstance()
            .map { extractParameter(it) }
            .forEach { registrar(it, handler) }
        }
      }
    }
  }

  protected inline fun  registerFor(
    dependencyProvider: DependencyProvider,
    registrar: (value: Class) -> Unit
  ) = dependencyProvider.getSubTypesOf(T::class.java).forEach { handler ->
    registerFor(handler) { value -> registrar(value as Class) }
  }

  protected inline fun  registerFor(
    handler: Class<*>,
    registrar: (value: Class<*>) -> Unit
  ) {
    val interfaceOrBaseClass = T::class.java
    if (!interfaceOrBaseClass.isAssignableFrom(handler)) return
    registrar(handler)
  }

  protected fun extractParameter(genericInterface: ParameterizedType): Class<*> =
    when (val typeArgument = genericInterface.actualTypeArguments[0]) {
      is ParameterizedType -> typeArgument.rawType as Class<*>
      is TypeVariable<*> -> {
        val rawType = (genericInterface.rawType as Class<*>)
        when {
          rawType.genericInterfaces.any() -> extractParameter(rawType.genericInterfaces[0] as ParameterizedType)
          else -> rawType
        }
      }

      else -> typeArgument as Class<*>
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy