TP-60963 add generic lambda implementation (#10161)
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.deserializer
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.CancelCoroutineJobEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.CustomBanksDataFilterHandlingEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.DelayEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.FailureActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.PreExecutionActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.ReturnPastApiResponseEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.SetClonedScreenDefinitionStateEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.SuccessActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.TriggerApiEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.UpdateAndTriggerSuccessActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.UpdateScreenDefinitionEvent
|
||||
import com.navi.common.uitron.model.LambdaAppEventType
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class LambdaEventDeserializer : JsonDeserializer<LambdaEventData> {
|
||||
override fun deserialize(
|
||||
json: JsonElement?,
|
||||
typeOfT: Type?,
|
||||
context: JsonDeserializationContext?
|
||||
): LambdaEventData? {
|
||||
json?.let {
|
||||
val jsonObject = it.asJsonObject
|
||||
val type = jsonObject["eventType"] ?: return null
|
||||
return when (type.asString) {
|
||||
LambdaAppEventType.CANCEL_COROUTINE_JOB.name ->
|
||||
context?.deserialize(jsonObject, CancelCoroutineJobEvent::class.java)
|
||||
LambdaAppEventType.PRE_EXECUTION_ACTION.name ->
|
||||
context?.deserialize(jsonObject, PreExecutionActionEvent::class.java)
|
||||
LambdaAppEventType.TRIGGER_API.name ->
|
||||
context?.deserialize(jsonObject, TriggerApiEvent::class.java)
|
||||
LambdaAppEventType.RETURN_PAST_API_RESPONSE.name ->
|
||||
context?.deserialize(jsonObject, ReturnPastApiResponseEvent::class.java)
|
||||
LambdaAppEventType.SUCCESS_ACTION.name ->
|
||||
context?.deserialize(jsonObject, SuccessActionEvent::class.java)
|
||||
LambdaAppEventType.FAILURE_ACTION.name ->
|
||||
context?.deserialize(jsonObject, FailureActionEvent::class.java)
|
||||
LambdaAppEventType.DELAY.name ->
|
||||
context?.deserialize(jsonObject, DelayEvent::class.java)
|
||||
LambdaAppEventType.UPDATE_AND_TRIGGER_SUCCESS_ACTION.name ->
|
||||
context?.deserialize(jsonObject, UpdateAndTriggerSuccessActionEvent::class.java)
|
||||
LambdaAppEventType.UPDATE_SCREEN_DEFINITION.name ->
|
||||
context?.deserialize(jsonObject, UpdateScreenDefinitionEvent::class.java)
|
||||
LambdaAppEventType.SET_CLONED_SCREEN_DEFINITION_STATE.name ->
|
||||
context?.deserialize(
|
||||
jsonObject,
|
||||
SetClonedScreenDefinitionStateEvent::class.java
|
||||
)
|
||||
LambdaAppEventType.CUSTOM_BANKS_DATA_FILTER_HANDLING.name ->
|
||||
context?.deserialize(jsonObject, CustomBanksDataFilterHandlingEvent::class.java)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,14 @@ package com.navi.ap.common.lambda.handler
|
||||
|
||||
import com.navi.ap.common.lambda.definition.Lambda
|
||||
import com.navi.ap.common.lambda.definition.LambdaBridge
|
||||
import com.navi.ap.common.lambda.verticals.generic.GenericLambdaImpl
|
||||
import com.navi.ap.common.models.ApScreenDefinitionStructure
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaData
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_INIT
|
||||
import com.navi.ap.utils.constants.METHOD_NAME
|
||||
import com.navi.ap.utils.logApEvent
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
import com.navi.common.utils.Constants.TYPE
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
@@ -25,9 +30,22 @@ abstract class LambdaHandler(
|
||||
clonedScreenDefinitionState.update { screenDefinitionState }
|
||||
}
|
||||
|
||||
private val lambdaImpl by lazy { GenericLambdaImpl(lambdaHandler = this) }
|
||||
|
||||
fun getClonedScreenDefinitionState() = clonedScreenDefinitionState.value
|
||||
|
||||
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
|
||||
// TODO : Put Common lambda here
|
||||
}
|
||||
|
||||
fun executeGenericLambda(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
|
||||
logApEvent(
|
||||
Pair(TYPE, lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_INIT)
|
||||
)
|
||||
lambdaImpl.executeGenericLambda(
|
||||
lambdaApiAction = lambdaApiAction,
|
||||
resolvedValues = lambadaData.resolvedValue.toMutableMap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ package com.navi.ap.common.lambda.verticals.coins
|
||||
|
||||
import com.navi.ap.common.lambda.definition.LambdaBridge
|
||||
import com.navi.ap.common.lambda.handler.LambdaHandler
|
||||
import com.navi.ap.common.lambda.verticals.generic.isLambdaDefinitionPresent
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaData
|
||||
import com.navi.ap.utils.constants.LambdaType
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
@@ -21,7 +22,10 @@ internal class CoinsLambdaHandler(
|
||||
private val lambdaImpl by lazy { CoinLambdaImpl(lambdaHandler = this@CoinsLambdaHandler) }
|
||||
|
||||
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
|
||||
|
||||
if (isLambdaDefinitionPresent(lambdaApiAction)) {
|
||||
executeGenericLambda(lambdaApiAction, lambadaData)
|
||||
return
|
||||
}
|
||||
when (lambdaApiAction.lambdaType) {
|
||||
LambdaType.VALIDATE_COINS_UPI_ID.name -> {
|
||||
lambdaImpl.validateCoinsUPIId(
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic
|
||||
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.ap.common.lambda.getErrorBottomSheetStructureAndSetLambdaState
|
||||
import com.navi.ap.common.lambda.handler.LambdaHandler
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.LambdaEventFactory
|
||||
import com.navi.ap.common.models.LambdaResponseType
|
||||
import com.navi.ap.common.models.LambdaState
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.ap.network.retrofit.ApRepoResult
|
||||
import com.navi.ap.utils.constants.EVENT
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_HANDLE_LAMBDA_STATE
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_TRIGGER_OUT_OF_SCOPE
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_TRIGGER_SCOPE
|
||||
import com.navi.ap.utils.constants.METHOD_NAME
|
||||
import com.navi.ap.utils.getValueAtJsonPath
|
||||
import com.navi.ap.utils.logApEvent
|
||||
import com.navi.common.uitron.model.LambdaResponseInjectionField
|
||||
import com.navi.common.uitron.model.LambdaStateType
|
||||
import com.navi.common.uitron.model.action.ApiType
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
import com.navi.common.utils.Constants
|
||||
import com.navi.common.utils.log
|
||||
import org.mvel2.MVEL
|
||||
|
||||
class GenericLambdaHelper(
|
||||
val lambdaHandler: LambdaHandler,
|
||||
private val lambdaEventFactory: LambdaEventFactory = LambdaEventFactory()
|
||||
) {
|
||||
|
||||
fun handleOutOfScopeEvents(details: LambdaEventDetails) {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, details.lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_TRIGGER_OUT_OF_SCOPE),
|
||||
Pair(EVENT, details.lambdaEventData?.eventType.orEmpty())
|
||||
)
|
||||
lambdaEventFactory
|
||||
.createOutOfScopeEventExecutor(type = details.lambdaEventData?.eventType)
|
||||
?.handleOutOfScopeEvent(details)
|
||||
}
|
||||
|
||||
suspend fun handleScopeEvents(details: LambdaEventDetails) {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, details.lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_TRIGGER_SCOPE),
|
||||
Pair(EVENT, details.lambdaEventData?.eventType.orEmpty())
|
||||
)
|
||||
details.lambdaEventData?.let {
|
||||
lambdaEventFactory
|
||||
.createScopeEventExecutor(
|
||||
details = details,
|
||||
handleOutOfScopeEvents = ::handleOutOfScopeEvents
|
||||
)
|
||||
?.handleScopeEvent(details)
|
||||
}
|
||||
}
|
||||
|
||||
fun handleLambdaState(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
stateType: String?,
|
||||
lambdaResponse: ApRepoResult<Any> = ApRepoResult()
|
||||
) {
|
||||
stateType?.let {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_HANDLE_LAMBDA_STATE),
|
||||
Pair(EVENT, it)
|
||||
)
|
||||
when (it) {
|
||||
LambdaStateType.LOADING.name -> {
|
||||
lambdaHandler.bridge.setLambdaState(LambdaState.Loading)
|
||||
}
|
||||
LambdaStateType.SUCCESS.name -> {
|
||||
lambdaHandler.bridge.setLambdaState(LambdaState.Success(LambdaResponseType()))
|
||||
}
|
||||
LambdaStateType.ERROR.name -> {
|
||||
lambdaHandler.bridge.setLambdaState(
|
||||
LambdaState.Error(
|
||||
lambdaResponse.statusCode,
|
||||
lambdaResponse.errorBottomSheetStructure,
|
||||
lambdaResponse.genericErrorBottomSheetFields
|
||||
)
|
||||
)
|
||||
}
|
||||
LambdaStateType.CUSTOM_ERROR.name -> {
|
||||
getErrorBottomSheetStructureAndSetLambdaState(
|
||||
lambdaApiAction.definition?.implementation?.apiTag
|
||||
?: ApiType.LambdaApiAction.name,
|
||||
lambdaResponse.statusCode
|
||||
)
|
||||
}
|
||||
LambdaStateType.NOTHING.name -> {
|
||||
lambdaHandler.bridge.setLambdaState(LambdaState.Nothing)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateHandle(
|
||||
handleConfig: List<LambdaResponseInjectionField?>?,
|
||||
resolvedValues: MutableMap<String, Any?>,
|
||||
lambdaResponse: ApRepoResult<Any> = ApRepoResult(),
|
||||
) {
|
||||
handleConfig?.forEach {
|
||||
val key = getValueAtJsonPath(resolvedValues, it?.key.orEmpty()).toString()
|
||||
val value =
|
||||
if (it?.jsonPath.isNullOrEmpty()) {
|
||||
lambdaResponse.data
|
||||
} else {
|
||||
getValueAtJsonPath(lambdaResponse.data ?: Any(), it?.jsonPath.orEmpty())
|
||||
?: lambdaResponse.data
|
||||
}
|
||||
lambdaHandler.bridge.getSaveStateHandle()[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
fun evaluateMvelExpression(
|
||||
expression: String?,
|
||||
updatedResolvedValues: MutableMap<String, Any?>,
|
||||
lambdaResponse: ApRepoResult<Any> = ApRepoResult(),
|
||||
pastApiResponse: HashMap<String, ApRepoResult<Any>?>
|
||||
): Any? {
|
||||
if (expression.isNullOrEmpty()) return null
|
||||
val varsMap =
|
||||
mapOf(
|
||||
Pair("data", lambdaResponse.data),
|
||||
Pair("errors", lambdaResponse.errors),
|
||||
Pair("errorBottomSheetStructure", lambdaResponse.errorBottomSheetStructure),
|
||||
Pair("resolvedValues", updatedResolvedValues),
|
||||
Pair("pastApiResponse", pastApiResponse),
|
||||
Pair("lambdaHandler", lambdaHandler),
|
||||
)
|
||||
try {
|
||||
return MVEL.eval(expression, varsMap)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
NaviTrackEvent.trackEvent(
|
||||
eventName = "dev_evaluate_generic_lambda_mvel_expression_result",
|
||||
eventValues = mapOf(Pair("mvelExpression", expression))
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic
|
||||
|
||||
import com.navi.ap.common.lambda.handler.LambdaHandler
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.ap.network.retrofit.ApRepoResult
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_PAST_API_RESPONSE
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_TRIGGER_POST_LAUNCH
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_TRIGGER_PRE_LAUNCH
|
||||
import com.navi.ap.utils.constants.METHOD_NAME
|
||||
import com.navi.ap.utils.constants.TRUE
|
||||
import com.navi.ap.utils.logApEvent
|
||||
import com.navi.common.CommonLibManager
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
import com.navi.common.utils.Constants
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal class GenericLambdaImpl(private val lambdaHandler: LambdaHandler) {
|
||||
|
||||
private val repository: GenericLambdaRepository =
|
||||
GenericLambdaProvider().getRepository(CommonLibManager.application.applicationContext)
|
||||
|
||||
private val lambdaHelper by lazy { GenericLambdaHelper(lambdaHandler) }
|
||||
|
||||
private val coroutineJobs by lazy { hashMapOf<String, Job>() }
|
||||
|
||||
private val pastApiResponse by lazy { hashMapOf<String, ApRepoResult<Any>?>() }
|
||||
|
||||
fun executeGenericLambda(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>,
|
||||
) {
|
||||
if (areRequiredInputsPresent(lambdaApiAction, resolvedValues).not()) {
|
||||
return
|
||||
}
|
||||
triggerPreLaunchEvents(lambdaApiAction, resolvedValues).let { isLambdaResolved ->
|
||||
if (isLambdaResolved) return
|
||||
}
|
||||
coroutineJobs[lambdaApiAction.lambdaType.orEmpty()] =
|
||||
lambdaHandler.bridge.getViewModelScope().launch(Dispatchers.IO) {
|
||||
val response = triggerPostLaunchEvents(lambdaApiAction, resolvedValues)
|
||||
pastApiResponse[lambdaApiAction.lambdaType.orEmpty()] = response
|
||||
handleLambdaApiResponse(lambdaApiAction, resolvedValues, response)
|
||||
}
|
||||
}
|
||||
|
||||
private fun triggerPreLaunchEvents(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>
|
||||
): Boolean {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_TRIGGER_PRE_LAUNCH)
|
||||
)
|
||||
lambdaApiAction.definition?.implementation?.preLaunchEvents?.forEach { event ->
|
||||
val condition = getImplementationSuccessCondition(lambdaApiAction, event)
|
||||
val status = evaluateExpression(condition, resolvedValues)
|
||||
handlePreLaunchLambdaStateAndAppEvents(event, status, lambdaApiAction, resolvedValues)
|
||||
|
||||
val handleConfig = getResponseState(lambdaApiAction, event, status)?.handleConfig
|
||||
return if (handleConfig.isNullOrEmpty().not()) {
|
||||
lambdaHelper.updateHandle(handleConfig, resolvedValues)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private suspend fun triggerPostLaunchEvents(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>
|
||||
): ApRepoResult<Any> {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_TRIGGER_POST_LAUNCH)
|
||||
)
|
||||
lambdaApiAction.definition?.implementation?.postLaunchEvents?.forEach { event ->
|
||||
val condition = getImplementationSuccessCondition(lambdaApiAction, event)
|
||||
val status = evaluateExpression(condition, resolvedValues)
|
||||
|
||||
handlePostLaunchLambdaStateAndAppEvents(event, status, lambdaApiAction, resolvedValues)
|
||||
|
||||
if (isTriggerApiEvent(lambdaApiAction, event, status) && status == TRUE) {
|
||||
return repository.triggerGenericLambda(lambdaApiAction, resolvedValues)
|
||||
} else if (isPastApiResponseEvent(lambdaApiAction, event, status) && status == TRUE) {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_PAST_API_RESPONSE)
|
||||
)
|
||||
return pastApiResponse[lambdaApiAction.lambdaType.orEmpty()] ?: ApRepoResult()
|
||||
}
|
||||
|
||||
val handleConfig = getResponseState(lambdaApiAction, event, status)?.handleConfig
|
||||
if (handleConfig.isNullOrEmpty().not()) {
|
||||
lambdaHelper.updateHandle(handleConfig, resolvedValues)
|
||||
return ApRepoResult()
|
||||
}
|
||||
}
|
||||
return ApRepoResult()
|
||||
}
|
||||
|
||||
private fun handlePreLaunchLambdaStateAndAppEvents(
|
||||
event: String,
|
||||
status: String,
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>
|
||||
) {
|
||||
val lambdaState = getResponseState(lambdaApiAction, event, status)?.lambdaState
|
||||
lambdaHelper.handleLambdaState(lambdaApiAction, lambdaState?.stateType)
|
||||
|
||||
getResponseState(lambdaApiAction, event, status)?.appEvents?.forEach { eventData ->
|
||||
lambdaHelper.handleOutOfScopeEvents(
|
||||
LambdaEventDetails(
|
||||
lambdaEventData = eventData,
|
||||
lambdaApiAction = lambdaApiAction,
|
||||
resolvedValues = resolvedValues,
|
||||
coroutineJobs = coroutineJobs,
|
||||
lambdaHandler = lambdaHandler
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun handlePostLaunchLambdaStateAndAppEvents(
|
||||
event: String,
|
||||
status: String,
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>
|
||||
) {
|
||||
val lambdaState = getResponseState(lambdaApiAction, event, status)?.lambdaState
|
||||
lambdaHelper.handleLambdaState(lambdaApiAction, lambdaState?.stateType)
|
||||
|
||||
getResponseState(lambdaApiAction, event, status)?.appEvents?.forEach { stateData ->
|
||||
lambdaHelper.handleScopeEvents(
|
||||
LambdaEventDetails(
|
||||
lambdaEventData = stateData,
|
||||
lambdaApiAction = lambdaApiAction,
|
||||
resolvedValues = resolvedValues,
|
||||
coroutineJobs = coroutineJobs,
|
||||
lambdaHandler = lambdaHandler
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun handleLambdaApiResponse(
|
||||
lambdaApiAction: LambdaApiAction?,
|
||||
resolvedValues: MutableMap<String, Any?>,
|
||||
lambdaResponse: ApRepoResult<Any>
|
||||
) {
|
||||
lambdaApiAction?.definition?.implementation?.conditions?.forEach { (event, state) ->
|
||||
if (isEventExecuted(lambdaApiAction, event)) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val status = evaluateExpression(state?.success, resolvedValues, lambdaResponse)
|
||||
|
||||
val handleConfig = getResponseState(lambdaApiAction, event, status)?.handleConfig
|
||||
if (handleConfig.isNullOrEmpty().not()) {
|
||||
lambdaHelper.updateHandle(handleConfig, resolvedValues, lambdaResponse)
|
||||
}
|
||||
|
||||
val appEvents = getResponseState(lambdaApiAction, event, status)?.appEvents
|
||||
appEvents?.forEach { eventData ->
|
||||
lambdaHelper.handleScopeEvents(
|
||||
LambdaEventDetails(
|
||||
lambdaEventData = eventData,
|
||||
lambdaApiAction = lambdaApiAction,
|
||||
resolvedValues = resolvedValues,
|
||||
coroutineJobs = coroutineJobs,
|
||||
lambdaResponse = lambdaResponse,
|
||||
lambdaHandler = lambdaHandler
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val lambdaState = getResponseState(lambdaApiAction, event, status)?.lambdaState
|
||||
lambdaHelper.handleLambdaState(lambdaApiAction, lambdaState?.stateType, lambdaResponse)
|
||||
|
||||
if (status == TRUE) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun evaluateExpression(
|
||||
expression: String?,
|
||||
updatedResolvedValues: MutableMap<String, Any?>,
|
||||
lambdaResponse: ApRepoResult<Any> = ApRepoResult()
|
||||
): String {
|
||||
return lambdaHelper
|
||||
.evaluateMvelExpression(
|
||||
expression,
|
||||
updatedResolvedValues,
|
||||
lambdaResponse,
|
||||
pastApiResponse
|
||||
)
|
||||
.toString()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic
|
||||
|
||||
import android.content.Context
|
||||
import com.navi.ap.di.EntryPoints
|
||||
import dagger.hilt.android.EntryPointAccessors
|
||||
|
||||
internal class GenericLambdaProvider {
|
||||
|
||||
fun getRepository(context: Context): GenericLambdaRepository {
|
||||
val hiltEntryPoint =
|
||||
EntryPointAccessors.fromApplication(
|
||||
context,
|
||||
EntryPoints.GenericLambdaRepositoryEntryPoint::class.java
|
||||
)
|
||||
return hiltEntryPoint.getGenericLambdaRepository()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic
|
||||
|
||||
import com.navi.ap.data.repository.ApplicationPlatformRepositoryImp
|
||||
import com.navi.ap.network.retrofit.ApRepoResult
|
||||
import com.navi.ap.network.retrofit.service.APRetrofitService
|
||||
import com.navi.ap.utils.constants.GENERIC_LAMBDA_TRIGGER_API
|
||||
import com.navi.ap.utils.constants.METHOD_NAME
|
||||
import com.navi.ap.utils.constants.RESULT
|
||||
import com.navi.ap.utils.constants.STATUS_CODE
|
||||
import com.navi.ap.utils.getValueAtJsonPath
|
||||
import com.navi.ap.utils.injectValuesInAStringWithPlaceHolders
|
||||
import com.navi.ap.utils.injector.PathInjector
|
||||
import com.navi.ap.utils.logApEvent
|
||||
import com.navi.common.uitron.model.ApiRequestType
|
||||
import com.navi.common.uitron.model.action.ApiType
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
import com.navi.common.utils.Constants
|
||||
import javax.inject.Inject
|
||||
|
||||
class GenericLambdaRepository @Inject constructor(private val retrofitService: APRetrofitService) :
|
||||
ApplicationPlatformRepositoryImp(retrofitService) {
|
||||
|
||||
suspend fun triggerGenericLambda(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>,
|
||||
): ApRepoResult<Any> {
|
||||
logApEvent(
|
||||
Pair(Constants.TYPE, lambdaApiAction.lambdaType.orEmpty()),
|
||||
Pair(METHOD_NAME, GENERIC_LAMBDA_TRIGGER_API)
|
||||
)
|
||||
val request = lambdaApiAction.definition?.implementation?.request ?: return ApRepoResult()
|
||||
|
||||
val headerMap: MutableMap<String, String> = mutableMapOf()
|
||||
request.headers
|
||||
?.filter { it.value != null }
|
||||
?.forEach {
|
||||
headerMap[it.key] =
|
||||
getValueAtJsonPath(resolvedValues, it.value.orEmpty()).toString()
|
||||
}
|
||||
|
||||
val subUrl = injectValuesInAStringWithPlaceHolders(request.subUrl.orEmpty(), resolvedValues)
|
||||
|
||||
val requestBody =
|
||||
PathInjector<Any, Any?>().injectData(request.body ?: Any(), resolvedValues)
|
||||
|
||||
val response =
|
||||
when (request.method) {
|
||||
ApiRequestType.GET.name -> {
|
||||
retrofitService.getRequest(subUrl, headerMap)
|
||||
}
|
||||
ApiRequestType.POST.name -> {
|
||||
retrofitService.postRequest(subUrl, headerMap, requestBody)
|
||||
}
|
||||
ApiRequestType.PATCH.name -> {
|
||||
retrofitService.patchRequest(subUrl, headerMap, requestBody)
|
||||
}
|
||||
ApiRequestType.DELETE.name -> {
|
||||
retrofitService.deleteRequest(subUrl, headerMap)
|
||||
}
|
||||
ApiRequestType.PUT.name -> {
|
||||
retrofitService.putRequest(subUrl, headerMap, requestBody)
|
||||
}
|
||||
else -> {
|
||||
return ApRepoResult()
|
||||
}
|
||||
}
|
||||
|
||||
logApEvent(
|
||||
Pair(
|
||||
RESULT,
|
||||
"${response.body()?.errors} | ${response.body()?.genericErrorBottomSheetFields}"
|
||||
),
|
||||
Pair(METHOD_NAME, ::triggerGenericLambda.name),
|
||||
Pair(STATUS_CODE, response.code().toString())
|
||||
)
|
||||
return apiResponseCallback(
|
||||
response = response,
|
||||
apiTag =
|
||||
lambdaApiAction.definition?.implementation?.apiTag ?: ApiType.LambdaApiAction.name
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic
|
||||
|
||||
import com.navi.ap.utils.constants.TRUE
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.common.uitron.model.LambdaAppEventType
|
||||
import com.navi.common.uitron.model.LambdaResponse
|
||||
import com.navi.common.uitron.model.LambdaResponseConfig
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
|
||||
fun isLambdaDefinitionPresent(lambdaApiAction: LambdaApiAction): Boolean {
|
||||
return lambdaApiAction.definition != null
|
||||
}
|
||||
|
||||
fun areRequiredInputsPresent(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
resolvedValues: MutableMap<String, Any?>
|
||||
): Boolean {
|
||||
lambdaApiAction.definition?.contract?.input?.forEach {
|
||||
if (it.value?.isRequired.orFalse() && resolvedValues[it.key] == null) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun LambdaResponse?.getSuccessOrFailureState(status: String): LambdaResponseConfig? {
|
||||
return if (status == TRUE) this?.success else this?.failure
|
||||
}
|
||||
|
||||
fun isEventExecuted(lambdaApiAction: LambdaApiAction?, event: String): Boolean {
|
||||
return lambdaApiAction?.definition?.implementation?.preLaunchEvents?.contains(event) == true ||
|
||||
lambdaApiAction?.definition?.implementation?.postLaunchEvents?.contains(event) == true
|
||||
}
|
||||
|
||||
fun isTriggerApiEvent(lambdaApiAction: LambdaApiAction, event: String, status: String): Boolean {
|
||||
val appEvents =
|
||||
getResponseState(lambdaApiAction, event, status)?.appEvents?.map { it?.eventType }
|
||||
return appEvents?.contains(LambdaAppEventType.TRIGGER_API.name).orFalse()
|
||||
}
|
||||
|
||||
fun isPastApiResponseEvent(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
event: String,
|
||||
status: String
|
||||
): Boolean {
|
||||
val appEvents =
|
||||
getResponseState(lambdaApiAction, event, status)?.appEvents?.map { it?.eventType }
|
||||
return appEvents?.contains(LambdaAppEventType.RETURN_PAST_API_RESPONSE.name).orFalse()
|
||||
}
|
||||
|
||||
fun getImplementationSuccessCondition(lambdaApiAction: LambdaApiAction, event: String): String? {
|
||||
return lambdaApiAction.definition?.implementation?.conditions?.get(event)?.success
|
||||
}
|
||||
|
||||
fun getResponseState(
|
||||
lambdaApiAction: LambdaApiAction,
|
||||
event: String,
|
||||
status: String
|
||||
): LambdaResponseConfig? {
|
||||
return lambdaApiAction.definition
|
||||
?.implementation
|
||||
?.response
|
||||
?.get(event)
|
||||
?.getSuccessOrFailureState(status)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class CancelCoroutineJobEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override fun handleOutOfScopeEvent(details: LambdaEventDetails) {
|
||||
details.coroutineJobs[details.lambdaApiAction.lambdaType.orEmpty()]?.cancel()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.ap.common.models.lambdamodels.response.BankDataResponse
|
||||
import com.navi.ap.utils.constants.ALL_BANKS_LIST
|
||||
import com.navi.ap.utils.constants.BANK_SEARCH_QUERY
|
||||
import com.navi.ap.utils.constants.PREFERRED_BANKS_LIST
|
||||
import com.navi.ap.utils.jsonToType
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import com.navi.common.utils.toJsonObject
|
||||
|
||||
class CustomBanksDataFilterHandlingEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
override suspend fun handleScopeEvent(details: LambdaEventDetails) {
|
||||
val preferredBanksKey = details.resolvedValues[PREFERRED_BANKS_LIST]?.toString().orEmpty()
|
||||
val allBanksKey = details.resolvedValues[ALL_BANKS_LIST]?.toString().orEmpty()
|
||||
val query = details.resolvedValues[BANK_SEARCH_QUERY]?.toString().orEmpty().trim()
|
||||
|
||||
val banksResponse =
|
||||
details.lambdaResponse.data.toJsonObject()?.jsonToType<BankDataResponse>()
|
||||
|
||||
details.lambdaHandler.bridge.getSaveStateHandle()[preferredBanksKey] =
|
||||
if (query.isEmpty()) banksResponse?.preferredBanks else emptyList()
|
||||
val filteredBanks =
|
||||
banksResponse?.allSupportedBanks?.filter { it.name?.startsWith(query, true) ?: false }
|
||||
details.lambdaHandler.bridge.getSaveStateHandle()[allBanksKey] = filteredBanks
|
||||
if (filteredBanks?.isNotEmpty() == true) {
|
||||
details.lambdaHandler.bridge.executeActions(details.lambdaApiAction.onSuccess)
|
||||
} else {
|
||||
details.lambdaHandler.bridge.executeActions(details.lambdaApiAction.onFailure)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
class DelayEvent(@SerializedName("delay") val delay: Long? = null) :
|
||||
LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override suspend fun handleScopeEvent(details: LambdaEventDetails) {
|
||||
val event = details.lambdaEventData as DelayEvent
|
||||
delay(event.delay ?: DEFAULT_DELAY)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_DELAY = 200L
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class FailureActionEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override fun handleOutOfScopeEvent(details: LambdaEventDetails) {
|
||||
details.lambdaHandler.bridge.executeActions(details.lambdaApiAction.onFailure)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
|
||||
interface ILambdaEventExecutor {
|
||||
|
||||
fun handleOutOfScopeEvent(details: LambdaEventDetails) {}
|
||||
|
||||
suspend fun handleScopeEvent(details: LambdaEventDetails) {}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaAppEventType
|
||||
|
||||
class LambdaEventFactory {
|
||||
|
||||
fun createOutOfScopeEventExecutor(type: String?): ILambdaEventExecutor? {
|
||||
return when (type) {
|
||||
LambdaAppEventType.CANCEL_COROUTINE_JOB.name -> CancelCoroutineJobEvent()
|
||||
LambdaAppEventType.PRE_EXECUTION_ACTION.name -> PreExecutionActionEvent()
|
||||
LambdaAppEventType.TRIGGER_API.name -> TriggerApiEvent()
|
||||
LambdaAppEventType.SUCCESS_ACTION.name -> SuccessActionEvent()
|
||||
LambdaAppEventType.FAILURE_ACTION.name -> FailureActionEvent()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun createScopeEventExecutor(
|
||||
details: LambdaEventDetails,
|
||||
handleOutOfScopeEvents: (LambdaEventDetails) -> Unit
|
||||
): ILambdaEventExecutor? {
|
||||
return when (details.lambdaEventData?.eventType) {
|
||||
LambdaAppEventType.DELAY.name -> DelayEvent()
|
||||
LambdaAppEventType.UPDATE_AND_TRIGGER_SUCCESS_ACTION.name ->
|
||||
UpdateAndTriggerSuccessActionEvent()
|
||||
LambdaAppEventType.UPDATE_SCREEN_DEFINITION.name -> UpdateScreenDefinitionEvent()
|
||||
LambdaAppEventType.SET_CLONED_SCREEN_DEFINITION_STATE.name ->
|
||||
SetClonedScreenDefinitionStateEvent()
|
||||
LambdaAppEventType.CUSTOM_BANKS_DATA_FILTER_HANDLING.name ->
|
||||
CustomBanksDataFilterHandlingEvent()
|
||||
else -> {
|
||||
handleOutOfScopeEvents.invoke(details)
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class PreExecutionActionEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override fun handleOutOfScopeEvent(details: LambdaEventDetails) {
|
||||
details.lambdaHandler.bridge.executeActions(details.lambdaApiAction.preExecutionAction)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class ReturnPastApiResponseEvent : LambdaEventData(), ILambdaEventExecutor
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class SetClonedScreenDefinitionStateEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
override suspend fun handleScopeEvent(details: LambdaEventDetails) {
|
||||
if (details.lambdaHandler.getClonedScreenDefinitionState() == null) {
|
||||
details.lambdaHandler.setClonedScreenDefinitionState(
|
||||
details.lambdaHandler.bridge.getScreenStructurePreRenderState()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class SuccessActionEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override fun handleOutOfScopeEvent(details: LambdaEventDetails) {
|
||||
details.lambdaHandler.bridge.executeActions(details.lambdaApiAction.onSuccess)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class TriggerApiEvent : LambdaEventData(), ILambdaEventExecutor {}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.ap.utils.injector.PathInjector
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
|
||||
class UpdateAndTriggerSuccessActionEvent : LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override suspend fun handleScopeEvent(details: LambdaEventDetails) {
|
||||
val updatedLambdaApiAction =
|
||||
if (details.lambdaResponse.data != null) {
|
||||
PathInjector<LambdaApiAction, Any?>()
|
||||
.injectData(details.lambdaApiAction, details.lambdaResponse.data)
|
||||
} else details.lambdaApiAction
|
||||
details.lambdaHandler.bridge.executeActions(updatedLambdaApiAction.onSuccess)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.lambda.verticals.generic.event
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.ap.common.models.ApScreenDefinitionState
|
||||
import com.navi.ap.common.models.ApScreenDefinitionStructure
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaEventDetails
|
||||
import com.navi.ap.utils.injector.BasePathInjector
|
||||
import com.navi.ap.utils.injector.PathInjector
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
|
||||
class UpdateScreenDefinitionEvent(
|
||||
@SerializedName("injectorType") val injectorType: String? = null
|
||||
) : LambdaEventData(), ILambdaEventExecutor {
|
||||
|
||||
override suspend fun handleScopeEvent(details: LambdaEventDetails) {
|
||||
val event = details.lambdaEventData as UpdateScreenDefinitionEvent
|
||||
val updatedResponse = getInjectedResponse(event.injectorType, details)
|
||||
updatedResponse?.let {
|
||||
details.lambdaHandler.bridge.setMetaData(
|
||||
updatedResponse.screenData?.metaData ?: mapOf()
|
||||
)
|
||||
details.lambdaHandler.bridge.setScreenDefinitionState(
|
||||
ApScreenDefinitionState.Success(updatedResponse)
|
||||
)
|
||||
}
|
||||
details.lambdaHandler.bridge.setSystemBackAction(
|
||||
updatedResponse?.screenData?.screenStructure?.systemBackCta
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getInjectedResponse(
|
||||
injectorType: String?,
|
||||
details: LambdaEventDetails
|
||||
): ApScreenDefinitionStructure? {
|
||||
return when (injectorType) {
|
||||
PathInjector.TAG -> {
|
||||
PathInjector<ApScreenDefinitionStructure, Any?>()
|
||||
.injectData(
|
||||
details.lambdaHandler.getClonedScreenDefinitionState(),
|
||||
details.lambdaResponse.data
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
BasePathInjector<ApScreenDefinitionStructure, Any?>()
|
||||
.injectData(
|
||||
details.lambdaHandler.getClonedScreenDefinitionState(),
|
||||
details.lambdaResponse.data
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ package com.navi.ap.common.lambda.verticals.personalloan
|
||||
|
||||
import com.navi.ap.common.lambda.definition.LambdaBridge
|
||||
import com.navi.ap.common.lambda.handler.LambdaHandler
|
||||
import com.navi.ap.common.lambda.verticals.generic.isLambdaDefinitionPresent
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaData
|
||||
import com.navi.ap.utils.constants.FILE_TYPE
|
||||
import com.navi.ap.utils.constants.HYPERVERGE_PAN_FLOW_ID
|
||||
@@ -33,6 +34,10 @@ open class PLLambdaHandler(
|
||||
private val lambdaImpl by lazy { PLLambdaImpl(lambdaHandler = this@PLLambdaHandler) }
|
||||
|
||||
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
|
||||
if (isLambdaDefinitionPresent(lambdaApiAction)) {
|
||||
executeGenericLambda(lambdaApiAction, lambadaData)
|
||||
return
|
||||
}
|
||||
when (lambdaApiAction.lambdaType) {
|
||||
LambdaType.TELCO_RESEND_OTP.name -> {
|
||||
lambdaImpl.resendTelcoOtp(lambdaApiAction = lambdaApiAction)
|
||||
|
||||
@@ -9,6 +9,7 @@ package com.navi.ap.common.lambda.verticals.vkyc
|
||||
|
||||
import com.navi.ap.common.lambda.definition.LambdaBridge
|
||||
import com.navi.ap.common.lambda.definition.VkycLambdaBridge
|
||||
import com.navi.ap.common.lambda.verticals.generic.isLambdaDefinitionPresent
|
||||
import com.navi.ap.common.lambda.verticals.personalloan.PLLambdaHandler
|
||||
import com.navi.ap.common.models.lambdamodels.LambdaData
|
||||
import com.navi.ap.utils.constants.LambdaType
|
||||
@@ -21,6 +22,10 @@ internal class VKYCLambdaHandler(
|
||||
private val lambdaImpl by lazy { VKYCLambdaImpl(lambdaHandler = this@VKYCLambdaHandler) }
|
||||
|
||||
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
|
||||
if (isLambdaDefinitionPresent(lambdaApiAction)) {
|
||||
executeGenericLambda(lambdaApiAction, lambadaData)
|
||||
return
|
||||
}
|
||||
when (lambdaApiAction.lambdaType) {
|
||||
LambdaType.CANCEL_VKYC.name -> {
|
||||
(bridge as? VkycLambdaBridge)?.cancelVKYCCall(lambdaApiAction)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.models.lambdamodels
|
||||
|
||||
import com.navi.ap.common.lambda.handler.LambdaHandler
|
||||
import com.navi.ap.network.retrofit.ApRepoResult
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
import kotlinx.coroutines.Job
|
||||
|
||||
data class LambdaEventDetails(
|
||||
val lambdaEventData: LambdaEventData?,
|
||||
val lambdaApiAction: LambdaApiAction,
|
||||
val resolvedValues: MutableMap<String, Any?>,
|
||||
val coroutineJobs: HashMap<String, Job>,
|
||||
val lambdaResponse: ApRepoResult<Any> = ApRepoResult(),
|
||||
val lambdaHandler: LambdaHandler
|
||||
)
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.common.serializer
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.CancelCoroutineJobEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.CustomBanksDataFilterHandlingEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.DelayEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.FailureActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.PreExecutionActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.ReturnPastApiResponseEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.SetClonedScreenDefinitionStateEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.SuccessActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.TriggerApiEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.UpdateAndTriggerSuccessActionEvent
|
||||
import com.navi.ap.common.lambda.verticals.generic.event.UpdateScreenDefinitionEvent
|
||||
import com.navi.common.uitron.model.LambdaAppEventType
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class LambdaEventSerializer : JsonSerializer<LambdaEventData> {
|
||||
override fun serialize(
|
||||
src: LambdaEventData?,
|
||||
typeOfSrc: Type?,
|
||||
context: JsonSerializationContext?
|
||||
): JsonElement? {
|
||||
return when (src?.eventType) {
|
||||
LambdaAppEventType.CANCEL_COROUTINE_JOB.name ->
|
||||
context?.serialize(src, CancelCoroutineJobEvent::class.java)
|
||||
LambdaAppEventType.PRE_EXECUTION_ACTION.name ->
|
||||
context?.serialize(src, PreExecutionActionEvent::class.java)
|
||||
LambdaAppEventType.TRIGGER_API.name ->
|
||||
context?.serialize(src, TriggerApiEvent::class.java)
|
||||
LambdaAppEventType.RETURN_PAST_API_RESPONSE.name ->
|
||||
context?.serialize(src, ReturnPastApiResponseEvent::class.java)
|
||||
LambdaAppEventType.SUCCESS_ACTION.name ->
|
||||
context?.serialize(src, SuccessActionEvent::class.java)
|
||||
LambdaAppEventType.FAILURE_ACTION.name ->
|
||||
context?.serialize(src, FailureActionEvent::class.java)
|
||||
LambdaAppEventType.DELAY.name -> context?.serialize(src, DelayEvent::class.java)
|
||||
LambdaAppEventType.UPDATE_AND_TRIGGER_SUCCESS_ACTION.name ->
|
||||
context?.serialize(src, UpdateAndTriggerSuccessActionEvent::class.java)
|
||||
LambdaAppEventType.UPDATE_SCREEN_DEFINITION.name ->
|
||||
context?.serialize(src, UpdateScreenDefinitionEvent::class.java)
|
||||
LambdaAppEventType.SET_CLONED_SCREEN_DEFINITION_STATE.name ->
|
||||
context?.serialize(src, SetClonedScreenDefinitionStateEvent::class.java)
|
||||
LambdaAppEventType.CUSTOM_BANKS_DATA_FILTER_HANDLING.name ->
|
||||
context?.serialize(src, CustomBanksDataFilterHandlingEvent::class.java)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
package com.navi.ap.di
|
||||
|
||||
import com.navi.ap.common.lambda.verticals.coins.CoinLambdaRepository
|
||||
import com.navi.ap.common.lambda.verticals.generic.GenericLambdaRepository
|
||||
import com.navi.ap.common.lambda.verticals.personalloan.PLLambdaRepository
|
||||
import com.navi.ap.common.usecase.UploadImageToAWSUseCase
|
||||
import dagger.hilt.EntryPoint
|
||||
@@ -28,6 +29,12 @@ class EntryPoints {
|
||||
fun getCoinLambdaRepository(): CoinLambdaRepository
|
||||
}
|
||||
|
||||
@EntryPoint
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface GenericLambdaRepositoryEntryPoint {
|
||||
fun getGenericLambdaRepository(): GenericLambdaRepository
|
||||
}
|
||||
|
||||
@EntryPoint
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface UploadImageToAWSUseCaseEntryPoint {
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.navi.ap.common.serializer.ApUiTronActionSerializer
|
||||
import com.navi.ap.common.serializer.CustomUiTronDataSerializer
|
||||
import com.navi.ap.common.serializer.LambdaEventSerializer
|
||||
import com.navi.ap.di.APGsonDeserializer
|
||||
import com.navi.ap.di.APGsonSerializer
|
||||
import com.navi.ap.network.retrofit.NaviApHttpClient
|
||||
@@ -20,6 +21,7 @@ import com.navi.ap.utils.registerPLSpecificDeSerializers
|
||||
import com.navi.common.CommonLibManager
|
||||
import com.navi.common.model.ModuleNameV2
|
||||
import com.navi.common.network.converter.EmptyBodyHandlingConverterFactory
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import com.navi.common.uitron.model.action.ThirdPartySdkAction
|
||||
import com.navi.common.uitron.model.action.UploadDataConfig
|
||||
import com.navi.common.uitron.serializer.AnySerializer
|
||||
@@ -79,6 +81,7 @@ object APNetworkModule {
|
||||
)
|
||||
.registerTypeAdapter(ThirdPartySdkAction::class.java, UiTronSDKActionSerializer())
|
||||
.registerTypeAdapter(Any::class.java, AnySerializer())
|
||||
.registerTypeAdapter(LambdaEventData::class.java, LambdaEventSerializer())
|
||||
.create()
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.navi.common.utils.Constants.OS_ANDROID
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.*
|
||||
|
||||
interface APRetrofitService : PlLambdaService, CoinsLambdaService {
|
||||
interface APRetrofitService : PlLambdaService, CoinsLambdaService, GenericLambdaService {
|
||||
@POST("/arc-warden/api/v3/application/{applicationId}/screen/{screenId}")
|
||||
suspend fun fetchScreenDefinition(
|
||||
@Path("applicationId") applicationId: String,
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.ap.network.retrofit.service
|
||||
|
||||
import com.navi.common.network.models.GenericResponse
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.DELETE
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.HeaderMap
|
||||
import retrofit2.http.PATCH
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Url
|
||||
|
||||
interface GenericLambdaService {
|
||||
|
||||
@GET
|
||||
suspend fun getRequest(
|
||||
@Url url: String,
|
||||
@HeaderMap headers: Map<String, String>
|
||||
): Response<GenericResponse<Any>>
|
||||
|
||||
@POST
|
||||
suspend fun postRequest(
|
||||
@Url url: String,
|
||||
@HeaderMap headers: Map<String, String>,
|
||||
@Body requestBody: Any
|
||||
): Response<GenericResponse<Any>>
|
||||
|
||||
@PATCH
|
||||
suspend fun patchRequest(
|
||||
@Url url: String,
|
||||
@HeaderMap headers: Map<String, String>,
|
||||
@Body requestBody: Any
|
||||
): Response<GenericResponse<Any>>
|
||||
|
||||
@DELETE
|
||||
suspend fun deleteRequest(
|
||||
@Url url: String,
|
||||
@HeaderMap headers: Map<String, String>
|
||||
): Response<GenericResponse<Any>>
|
||||
|
||||
@PUT
|
||||
suspend fun putRequest(
|
||||
@Url url: String,
|
||||
@HeaderMap headers: Map<String, String>,
|
||||
@Body body: Any,
|
||||
): Response<GenericResponse<Any>>
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import com.google.gson.reflect.TypeToken
|
||||
import com.navi.ap.common.deserializer.ApUiTronActionDeserializer
|
||||
import com.navi.ap.common.deserializer.CustomUiTronDataDeserializer
|
||||
import com.navi.ap.common.deserializer.KYCSDKSettingsDataDeserializer
|
||||
import com.navi.ap.common.deserializer.LambdaEventDeserializer
|
||||
import com.navi.ap.common.sdk.model.KycSdkSettingData
|
||||
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
|
||||
import com.navi.ap.utils.constants.APP_FROM_SCREEN_ID
|
||||
@@ -20,6 +21,7 @@ import com.navi.ap.utils.constants.DEFAULT_SOURCE_SCREEN
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.utils.EMPTY
|
||||
import com.navi.base.utils.orElse
|
||||
import com.navi.common.uitron.model.LambdaEventData
|
||||
import com.navi.common.utils.log
|
||||
import com.navi.common.utils.registerUiTronDeSerializers
|
||||
import com.navi.payment.model.clientmodels.PaymentEvent
|
||||
@@ -97,6 +99,7 @@ fun GsonBuilder.registerApUiTronDeSerializers(): GsonBuilder {
|
||||
return registerUiTronDeSerializers().apply {
|
||||
registerTypeAdapter(UiTronData::class.java, CustomUiTronDataDeserializer())
|
||||
registerTypeAdapter(UiTronAction::class.java, ApUiTronActionDeserializer())
|
||||
registerTypeAdapter(LambdaEventData::class.java, LambdaEventDeserializer())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,14 +27,19 @@ import com.navi.ap.common.ui.ApplicationPlatformActivity
|
||||
import com.navi.ap.network.di.APNetworkModule.providesDeserializer
|
||||
import com.navi.ap.network.di.APNetworkModule.providesSerializer
|
||||
import com.navi.ap.screens.genericscreen.vm.ApGenericScreenVM
|
||||
import com.navi.ap.utils.constants.CODE
|
||||
import com.navi.ap.utils.constants.DEFAULT_SCREEN_STATE_ID
|
||||
import com.navi.ap.utils.constants.DEFAULT_SOURCE_SCREEN
|
||||
import com.navi.ap.utils.constants.DOT_SDK_DOT
|
||||
import com.navi.ap.utils.constants.JOURNEY_SOURCE
|
||||
import com.navi.ap.utils.constants.KEY_PAYMENT_GATEWAY_EVENT_NAME
|
||||
import com.navi.ap.utils.constants.KEY_PAYMENT_SDK_VERSION
|
||||
import com.navi.ap.utils.constants.LATITUDE
|
||||
import com.navi.ap.utils.constants.LAYOUT_ID
|
||||
import com.navi.ap.utils.constants.LONGITUDE
|
||||
import com.navi.ap.utils.constants.METHOD_NAME
|
||||
import com.navi.ap.utils.constants.PARENT
|
||||
import com.navi.ap.utils.constants.PAYMENT_DOT_GATEWAY_DOT
|
||||
import com.navi.ap.utils.constants.SOURCE_AP
|
||||
import com.navi.ap.utils.constants.VIEW_ID
|
||||
import com.navi.ap.utils.constants.WIDGET_ID
|
||||
@@ -47,6 +52,8 @@ import com.navi.common.utils.CommonUtils
|
||||
import com.navi.common.utils.EMPTY
|
||||
import com.navi.common.utils.getDeviceData
|
||||
import com.navi.common.utils.log
|
||||
import com.navi.payment.utils.Constants
|
||||
import com.navi.payment.utils.PaymentAnalytics.PROVIDER
|
||||
import com.navi.uitron.model.UiTronResponse
|
||||
import com.navi.uitron.utils.getInputId
|
||||
import com.navi.uitron.utils.isNull
|
||||
@@ -177,6 +184,15 @@ fun getResolvedFieldValue(
|
||||
val output: String? = handle[name]
|
||||
map[item.sourceProperty.orEmpty()] = "${output.orEmpty()}$valueSuffix"
|
||||
}
|
||||
SourceType.DEVICE_PROPERTY.name -> {
|
||||
val value =
|
||||
getDeviceData(
|
||||
sourceProperty = item.sourceProperty.orEmpty(),
|
||||
context = CommonLibManager.application.applicationContext,
|
||||
additionalValues = item.additionalParameters
|
||||
)
|
||||
map[name] = value
|
||||
}
|
||||
SourceType.PRE_DEFINED.name -> {
|
||||
map[name] = "${item.value.orEmpty()}$valueSuffix"
|
||||
}
|
||||
@@ -185,14 +201,16 @@ fun getResolvedFieldValue(
|
||||
val output = readJsonPath(obj.toJson(), item.jsonPath.orEmpty())
|
||||
map[item.sourceProperty.orEmpty()] = "$output$valueSuffix"
|
||||
}
|
||||
SourceType.DEVICE_PROPERTY.name -> {
|
||||
val value =
|
||||
getDeviceData(
|
||||
sourceProperty = item.sourceProperty.orEmpty(),
|
||||
context = CommonLibManager.application.applicationContext,
|
||||
additionalValues = item.additionalParameters
|
||||
)
|
||||
map[item.name.orEmpty()] = value
|
||||
SourceType.CONSTANTS.name -> {
|
||||
map[name] =
|
||||
when (item.sourceProperty) {
|
||||
KEY_PAYMENT_SDK_VERSION -> Constants.PAYMENT_SDK_VERSION
|
||||
else -> EMPTY
|
||||
}
|
||||
}
|
||||
SourceType.CUSTOM_LOGIC.name -> {
|
||||
val value = getCustomFieldData(item.sourceProperty.orEmpty(), map)
|
||||
map[name] = value
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
@@ -323,3 +341,38 @@ fun buildFillParametersUsingWidgetOutput(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getCustomFieldData(sourceProperty: String, map: MutableMap<String, Any?>? = null): String {
|
||||
return when (sourceProperty) {
|
||||
KEY_PAYMENT_GATEWAY_EVENT_NAME -> {
|
||||
getPaymentGatewayEventName(map?.get(CODE).toString(), map?.get(PROVIDER).toString())
|
||||
}
|
||||
else -> EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPaymentGatewayEventName(code: String, provider: String): String {
|
||||
return "$PAYMENT_DOT_GATEWAY_DOT$provider$DOT_SDK_DOT$code"
|
||||
}
|
||||
|
||||
fun injectValuesInAStringWithPlaceHolders(text: String, dataObj: Any): String {
|
||||
val placeholders = text.split("{").drop(1).map { it.split("}")[0] }
|
||||
var result = text
|
||||
|
||||
placeholders.forEach { placeholder ->
|
||||
val value = (getValueAtJsonPath(dataObj, placeholder) ?: EMPTY).toString()
|
||||
result = result.replace("{$placeholder}", value)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun getValueAtJsonPath(dataObj: Any, jsonPath: String): Any? {
|
||||
return try {
|
||||
val dataObject = JSONObject(dataObj.toJson())
|
||||
readJsonPath(dataObject.toString(), jsonPath)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ const val WIDGET_ID = "widgetId"
|
||||
const val PARENT = "parent"
|
||||
const val INVALID_IFSC_CODE = "INVALID_IFSC_CODE"
|
||||
const val SOURCE = "source"
|
||||
const val EVENT = "event"
|
||||
|
||||
val noLoaderScreenTypes: MutableSet<String> =
|
||||
mutableSetOf(
|
||||
@@ -85,3 +86,7 @@ const val SELECTED_DATE_WITH_SUFFIX = "selectedDateWithSuffix"
|
||||
const val SELECTED_FORMATTED_DATE = "selectedFormattedDate"
|
||||
const val SHOW = "show"
|
||||
const val INVALID_PIN_CODE = "INVALID_PIN_CODE"
|
||||
const val KEY_PAYMENT_SDK_VERSION = "KEY_PAYMENT_SDK_VERSION"
|
||||
const val KEY_PAYMENT_GATEWAY_EVENT_NAME = "paymentGatewayEventName"
|
||||
const val PAYMENT_DOT_GATEWAY_DOT = "payments.gateway."
|
||||
const val DOT_SDK_DOT = ".sdk."
|
||||
|
||||
@@ -62,3 +62,13 @@ const val DIGILOCKER = "digilocker"
|
||||
// HYPERVERGE PAN
|
||||
const val HYPERVERGE_PAN_CAPTURE_SUCCESS = "hyperverge_pan_capture_success"
|
||||
const val HYPERVERGE_PAN_CAPTURE_ERROR = "hyperverge_pan_capture_error"
|
||||
|
||||
// GENERIC LAMBDA
|
||||
const val GENERIC_LAMBDA_INIT = "generic_lambda_init"
|
||||
const val GENERIC_LAMBDA_TRIGGER_PRE_LAUNCH = "generic_lambda_trigger_pre_launch"
|
||||
const val GENERIC_LAMBDA_TRIGGER_POST_LAUNCH = "generic_lambda_trigger_post_launch"
|
||||
const val GENERIC_LAMBDA_TRIGGER_API = "generic_lambda_trigger_api"
|
||||
const val GENERIC_LAMBDA_PAST_API_RESPONSE = "generic_lambda_past_api_response"
|
||||
const val GENERIC_LAMBDA_TRIGGER_OUT_OF_SCOPE = "generic_lambda_trigger_out_of_scope"
|
||||
const val GENERIC_LAMBDA_TRIGGER_SCOPE = "generic_lambda_trigger_scope"
|
||||
const val GENERIC_LAMBDA_HANDLE_LAMBDA_STATE = "generic_lambda_handle_lambda_state"
|
||||
|
||||
@@ -13,6 +13,11 @@ import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
class PathInjector<U, V> : BasePathInjector<U, V>() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "PATH_INJECTOR"
|
||||
}
|
||||
|
||||
override fun inject(currentObject: JSONObject, key: String, type: JSON_TYPE) {
|
||||
when (type) {
|
||||
JSON_TYPE.JSONArray -> {
|
||||
|
||||
Reference in New Issue
Block a user