Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: inject evaluator in the context to allow using it in custom operators #28

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
package com.rapatao.projects.ruleset.engine.context

import com.rapatao.projects.ruleset.engine.Evaluator
import com.rapatao.projects.ruleset.engine.types.operators.Operator

/**
* Represents an evaluation context for processing expressions.
*/
fun interface EvalContext {
interface EvalContext {

/**
* Process the expression using the given operator
* Processes the expression using the given operator.
*
* @return true if the expression is successfully processed, false otherwise
* @param left The left-hand side of the expression. Can be any type.
* @param operator The operator to use for processing the expression. This is an instance of [Operator].
* @param right The right-hand side of the expression. Can be any type.
*
* @return `true` if the expression is successfully processed, `false` otherwise.
*/
fun process(left: Any?, operator: Operator, right: Any?): Boolean

/**
* Returns the Evaluator instance used to build this evaluation context.
*
* @return The Evaluator implementation that was used to create this EvalContext.
*/
fun engine(): Evaluator
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.rapatao.projects.ruleset.engine.evaluator.graaljs

import com.rapatao.projects.ruleset.engine.Evaluator
import com.rapatao.projects.ruleset.engine.context.EvalContext
import com.rapatao.projects.ruleset.engine.types.operators.Operator
import org.graalvm.polyglot.Context
Expand All @@ -8,16 +9,20 @@ import org.graalvm.polyglot.Context
* GraalJSContext is a class that implements the EvalContext interface.
* It provides the ability to process expressions using the Graal JS engine.
*
* @property context the GraalJS context object.
* @param evaluator the evaluator implementation instance
* @param context the GraalJS context object.
*/
class GraalJSContext(
private val evaluator: Evaluator,
private val context: Context,
) : EvalContext {

override fun process(left: Any?, operator: Operator, right: Any?): Boolean {
return operator.process(this, left, right)
}

override fun engine(): Evaluator = evaluator

/**
* Return the Graal JS context.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ open class GraalJSEvaluator(
it.getBindings("js"),
inputData,
)
block(GraalJSContext(it))
block(GraalJSContext(this, it))
}

private fun createContext(): Context {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.rapatao.projects.ruleset.engine.evaluator.kotlin

import com.rapatao.projects.ruleset.engine.Evaluator
import com.rapatao.projects.ruleset.engine.context.EvalContext
import com.rapatao.projects.ruleset.engine.types.operators.Operator
import java.math.BigDecimal
Expand All @@ -8,16 +9,20 @@ import java.math.BigDecimal
* KotlinContext is a class that implements the EvalContext interface.
* It provides the ability to process expressions using Kotlin operations.
*
* @param evaluator the evaluator implementation instance
* @param inputData the map containing the input data to be used during expression evaluation
*/
class KotlinContext(
private val evaluator: Evaluator,
private val inputData: Map<String, Any?>
) : EvalContext {

override fun process(left: Any?, operator: Operator, right: Any?): Boolean {
return operator.process(this, left.asValue(), right.asValue())
}

override fun engine(): Evaluator = evaluator

private fun Any?.asValue(): Any? {
val result = when {
this is String && !this.trim().matches(Regex("^\".*\"$")) -> rawValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ open class KotlinEvaluator(

override fun <T> call(inputData: Any, block: (context: EvalContext) -> T): T {
return block(KotlinContext(
this,
mutableMapOf<String, Any?>().apply {
parseKeys("", inputData)
}
Expand Down Expand Up @@ -63,6 +64,8 @@ open class KotlinEvaluator(
val currNode = node.childNode()

input.forEach { key, value ->
this["${currNode}${key}"] = value

parseKeys("${currNode}${key}", value)
}
}
Expand All @@ -71,6 +74,8 @@ open class KotlinEvaluator(
val currNode = node.childNode()

input?.javaClass?.kotlin?.memberProperties?.forEach {
this["${currNode}${it.name}"] = it.get(input)

parseKeys("${currNode}${it.name}", it.get(input))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.rapatao.projects.ruleset.engine.evaluator.rhino

import com.rapatao.projects.ruleset.engine.Evaluator
import com.rapatao.projects.ruleset.engine.context.EvalContext
import com.rapatao.projects.ruleset.engine.types.operators.Operator
import org.mozilla.javascript.Context
Expand All @@ -9,17 +10,21 @@ import org.mozilla.javascript.ScriptableObject
* RhinoContext is a class that implements the EvalContext interface.
* It provides the ability to process expressions using the Rhino JavaScript engine.
*
* @property context The Rhino Context object.
* @property scope The ScriptableObject representing the scope in which the expressions will be executed.
* @param evaluator the evaluator implementation instance
* @param context The Rhino Context object.
* @param scope The ScriptableObject representing the scope in which the expressions will be executed.
*/
class RhinoContext(
private val evaluator: Evaluator,
private val context: Context,
private val scope: ScriptableObject,
) : EvalContext {

override fun process(left: Any?, operator: Operator, right: Any?): Boolean =
operator.process(this, left, right)

override fun engine(): Evaluator = evaluator

/**
* Returns the Rhino context.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ open class RhinoEvaluator(

parseParameters(scope, context, inputData)

block(RhinoContext(context, scope))
block(RhinoContext(this, context, scope))
}
}

Expand Down
Loading