-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
348 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,4 @@ nbdist/ | |
classes | ||
out/ | ||
.scannerwork/ | ||
|
||
create-order-db.sql | ||
create-sku-db.sql | ||
bench_*.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import kotlinx.kover.gradle.plugin.dsl.MetricType | ||
|
||
dependencies { | ||
api project(":core") | ||
api("org.graalvm.polyglot:polyglot:24.0.1") | ||
api("org.graalvm.polyglot:js-community:24.0.1") | ||
|
||
testImplementation project(":tests") | ||
} | ||
|
||
koverReport { | ||
verify { | ||
rule { | ||
enabled = true | ||
bound { | ||
enabled = true | ||
metric = MetricType.BRANCH | ||
minValue = 80 | ||
} | ||
bound { | ||
enabled = true | ||
metric = MetricType.LINE | ||
minValue = 90 | ||
} | ||
bound { | ||
enabled = true | ||
metric = MetricType.INSTRUCTION | ||
minValue = 90 | ||
} | ||
} | ||
} | ||
|
||
defaults { | ||
html { | ||
onCheck = true | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
...r/src/main/kotlin/com/rapatao/projects/ruleset/engine/evaluator/graaljs/GraalJSContext.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.rapatao.projects.ruleset.engine.evaluator.graaljs | ||
|
||
import com.rapatao.projects.ruleset.engine.context.EvalContext | ||
import com.rapatao.projects.ruleset.engine.types.Expression | ||
import org.graalvm.polyglot.Context | ||
import org.graalvm.polyglot.Source | ||
|
||
/** | ||
* 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. | ||
*/ | ||
class GraalJSContext( | ||
private val context: Context, | ||
) : EvalContext { | ||
|
||
/** | ||
* Processes an expression. | ||
* | ||
* @param expression the expression to process | ||
* @return true if the expression is successfully processed, false otherwise | ||
* @throws Exception if the expression processing fails and onFailure is set to THROW | ||
*/ | ||
override fun process(expression: Expression): Boolean { | ||
return context.eval(expression.asScript()).asBoolean() | ||
} | ||
|
||
/** | ||
* Return the Graal JS context. | ||
* | ||
* @return the Graal JS context. | ||
*/ | ||
fun context() = context | ||
|
||
private fun Expression.asScript(): Source { | ||
val script = Parser.parse(this) | ||
|
||
return Source.newBuilder( | ||
"js", | ||
"true == ($script)", | ||
script | ||
).buildLiteral() | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
...rc/main/kotlin/com/rapatao/projects/ruleset/engine/evaluator/graaljs/GraalJSEvalEngine.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.rapatao.projects.ruleset.engine.evaluator.graaljs | ||
|
||
import com.rapatao.projects.ruleset.engine.context.EvalContext | ||
import com.rapatao.projects.ruleset.engine.context.EvalEngine | ||
import com.rapatao.projects.ruleset.engine.evaluator.graaljs.parameters.MapInjector | ||
import com.rapatao.projects.ruleset.engine.evaluator.graaljs.parameters.TypedInjector | ||
import org.graalvm.polyglot.Context | ||
import org.graalvm.polyglot.Engine | ||
import org.graalvm.polyglot.HostAccess | ||
import org.graalvm.polyglot.Value | ||
|
||
open class GraalJSEvalEngine( | ||
private val engine: Engine = Engine.newBuilder() | ||
.option("engine.WarnInterpreterOnly", "false") | ||
.build(), | ||
private val contextBuilder: Context.Builder = Context.newBuilder() | ||
.engine(engine) | ||
.option("js.ecmascript-version", "2023") | ||
.allowHostAccess(HostAccess.ALL).allowHostClassLookup { true } | ||
.option("js.nashorn-compat", "true").allowExperimentalOptions(true) | ||
) : EvalEngine { | ||
|
||
override fun <T> call(inputData: Any, block: EvalContext.() -> T): T = | ||
createContext().let { | ||
parseParameters( | ||
it.getBindings("js"), | ||
inputData, | ||
) | ||
block(GraalJSContext(it)) | ||
} | ||
|
||
private fun createContext(): Context { | ||
return contextBuilder.build() | ||
} | ||
|
||
override fun name(): String = "GraalJS" | ||
|
||
/** | ||
* Parses parameters and injects them into the given scope based on the input data. | ||
* | ||
* @param bindings the values object where the parameters will be injected | ||
* @param inputData the input data containing the parameters | ||
*/ | ||
open fun parseParameters(bindings: Value, inputData: Any) { | ||
when (inputData) { | ||
is Map<*, *> -> MapInjector.inject(bindings, inputData) | ||
else -> TypedInjector.inject(bindings, inputData) | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
...evaluator/src/main/kotlin/com/rapatao/projects/ruleset/engine/evaluator/graaljs/Parser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.rapatao.projects.ruleset.engine.evaluator.graaljs | ||
|
||
import com.rapatao.projects.ruleset.engine.types.Expression | ||
import com.rapatao.projects.ruleset.engine.types.Operator | ||
|
||
internal object Parser { | ||
|
||
fun parse(expression: Expression): String { | ||
return when (expression.operator) { | ||
Operator.EQUALS -> "==".formatComparison(expression) | ||
Operator.NOT_EQUALS -> "!=".formatComparison(expression) | ||
Operator.GREATER_THAN -> ">".formatComparison(expression) | ||
Operator.GREATER_OR_EQUAL_THAN -> ">=".formatComparison(expression) | ||
Operator.LESS_THAN -> "<".formatComparison(expression) | ||
Operator.LESS_OR_EQUAL_THAN -> "<=".formatComparison(expression) | ||
Operator.STARTS_WITH -> "startsWith".formatWithOperation(expression) | ||
Operator.ENDS_WITH -> "endsWith".formatWithOperation(expression) | ||
Operator.CONTAINS -> formatContainsOperation(expression) | ||
null -> error("when evaluation an expression, the operator cannot be null") | ||
} | ||
} | ||
|
||
private fun String.formatComparison(expression: Expression) = | ||
"(${expression.left}) $this (${expression.right})" | ||
|
||
private fun String.formatWithOperation(expression: Expression) = | ||
"${expression.left}.${this}(${expression.right})" | ||
|
||
private fun formatContainsOperation(expression: Expression) = | ||
""" | ||
(function() { | ||
if (Array.isArray(${expression.left})) { | ||
return ${expression.left}.includes(${expression.right}) | ||
} else { | ||
return ${expression.left}.indexOf(${expression.right}) !== -1 | ||
} | ||
})() | ||
""".trimIndent() | ||
} |
12 changes: 12 additions & 0 deletions
12
...in/kotlin/com/rapatao/projects/ruleset/engine/evaluator/graaljs/parameters/MapInjector.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.rapatao.projects.ruleset.engine.evaluator.graaljs.parameters | ||
|
||
import org.graalvm.polyglot.Value | ||
|
||
internal data object MapInjector : ParameterInjector<Map<*, *>> { | ||
|
||
override fun inject(bindings: Value, input: Map<*, *>) { | ||
input.forEach { | ||
set(bindings, it.key.toString(), it.value) | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...lin/com/rapatao/projects/ruleset/engine/evaluator/graaljs/parameters/ParameterInjector.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.rapatao.projects.ruleset.engine.evaluator.graaljs.parameters | ||
|
||
import org.graalvm.polyglot.Value | ||
|
||
internal interface ParameterInjector<T> { | ||
|
||
fun inject(bindings: Value, input: T) | ||
|
||
fun set(bindings: Value, name: String, value: Any?) { | ||
bindings.putMember(name, value) | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
.../kotlin/com/rapatao/projects/ruleset/engine/evaluator/graaljs/parameters/TypedInjector.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.rapatao.projects.ruleset.engine.evaluator.graaljs.parameters | ||
|
||
import org.graalvm.polyglot.Value | ||
import kotlin.reflect.full.memberProperties | ||
|
||
internal data object TypedInjector : ParameterInjector<Any> { | ||
|
||
override fun inject(bindings: Value, input: Any) { | ||
input.javaClass.kotlin.memberProperties.forEach { | ||
set(bindings, it.name, it.get(input)) | ||
} | ||
} | ||
} |
Oops, something went wrong.