
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