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

com.testerum.file_service.caches.resolved.resolvers.StepsResolver.kt Maven / Gradle / Ivy

package com.testerum.file_service.caches.resolved.resolvers

import com.testerum.model.step.BasicStepDef
import com.testerum.model.step.ComposedStepDef
import com.testerum.model.step.StepDef
import com.testerum.model.step.UndefinedStepDef
import com.testerum.model.util.StepHashUtil
import java.nio.file.Path as JavaPath

class StepsResolver(private val argsResolver: ArgsResolver) {

    fun resolve(basicStepsMap: Map,
                unresolvedComposedStepsMap: Map,
                resourcesDir: JavaPath): MutableMap {
        val stepsToResolve   = HashMap(unresolvedComposedStepsMap)
        val stepsInResolving = LinkedHashMap()
        val resolvedSteps    = HashMap(basicStepsMap)

        for ((hashOfStepToResolve, stepToResolve) in unresolvedComposedStepsMap) {
            resolve(stepToResolve, hashOfStepToResolve, stepsToResolve, stepsInResolving, resolvedSteps, resourcesDir)
        }

        if (resolvedSteps.values.any { it is UndefinedStepDef }) {
            throw IllegalStateException(
                    "detected ${UndefinedStepDef::class.java.simpleName} after step resolving" +
                    "; this indicates a problem in step resolving" +
                    "; throwing exception to prevent cache pollution"
            )
        }

        return resolvedSteps
    }

    private fun resolve(stepToResolve: StepDef,
                        hashOfStepToResolve: String,
                        stepsToResolve: MutableMap,
                        stepsInResolving: MutableMap,
                        resolvedSteps: MutableMap,
                        resourcesDir: JavaPath) {
        if (stepsInResolving.containsKey(hashOfStepToResolve)) {
            throw RuntimeException("detected cycle while resolving steps: ${stepsInResolving.values.joinToString(prefix = "[", postfix = "]", separator = "], [")}")
        }

        stepsInResolving[hashOfStepToResolve] = stepToResolve

        // already resolved
        val alreadyResolvedStep: StepDef? = resolvedSteps[hashOfStepToResolve]
        if (alreadyResolvedStep != null) {
            stepsToResolve.remove(hashOfStepToResolve)
            stepsInResolving.remove(hashOfStepToResolve)

            return
        }

        // cannot resolve
        val notYetResolvedStepDef = stepsToResolve[hashOfStepToResolve]
        if (notYetResolvedStepDef == null) {
            // cannot resolve (e.g. UndefinedStep)
            stepsToResolve.remove(hashOfStepToResolve)
            stepsInResolving.remove(hashOfStepToResolve)

            return
        }

        // resolve recursively all children
        for (stepCall in notYetResolvedStepDef.stepCalls) {
            val stepDef = stepCall.stepDef
            val hash = StepHashUtil.calculateStepHash(stepDef)

            resolve(stepDef, hash, stepsToResolve, stepsInResolving, resolvedSteps, resourcesDir)
        }

        // all children are resolved, we need to attach them
        val resolvedCalls = notYetResolvedStepDef.stepCalls.map { stepCall ->
            val stepDef: StepDef = stepCall.stepDef
            val hash = StepHashUtil.calculateStepHash(stepDef)

            var resolvedStepDef: StepDef? = resolvedSteps[hash]
            if (resolvedStepDef == null) {
                // could not resolve
                resolvedStepDef = stepDef
            }

            stepCall.copy(
                    stepDef = resolvedStepDef,
                    args = argsResolver.resolveArgs(stepCall.args, resolvedStepDef, resourcesDir)
            )
        }

        resolvedSteps[hashOfStepToResolve] = notYetResolvedStepDef.copy(stepCalls = resolvedCalls)
        stepsToResolve.remove(hashOfStepToResolve)
        stepsInResolving.remove(hashOfStepToResolve)
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy