Nashorn Javascriptエンジンを使用してJSONロジックルールを実行できるライブラリを作成しようとしています。Nashornが適切なメソッド参照を渡すことができますか?
私の問題は、Java/Kotlinからスクリプティングエンジンへのデータの移動を処理するために作成したJSObjectラッパーに関するものです。
配列が[true]
などに渡された場合、それがラップされているとJSON-ロジックスクリプトは、それを受け取ることが配列であることがわかり、そして次のコードビットを実行しようとします。
if(Array.isArray(logic)) {
return logic.map(function(l) {
return jsonLogic.apply(l, data);
});
}
.map
関数が呼び出されると、Nashornは自分のオブジェクト上でgetMember("map")
を呼び出して、実行可能な関数を返すことを期待します。
これは私が立ち往生している場所です。 Nashornにマップ関数の受信者として呼び出せるメソッドまたはメソッドの参照を与えるための適切な構文を見つけることができませんでした。
コードはここにあります:https://github.com/deinspanjer/json-logic-java 問題を示すものを含むいくつかの基本的なユニットテストがあります:JavaJsonLogicTest.simpleApplyJEJO()
。 破損しているコード行はcom/jsonlogic/JSObjectWrappers.kt:97
です。
ご協力いただきありがとうございます。
UPDATE:受け入れ答えに基づいて 、ここでのコードの作業Kotlinバージョンです:
package com.jsonlogic
import jdk.nashorn.api.scripting.AbstractJSObject
import jdk.nashorn.api.scripting.JSObject
import java.util.function.Function
import javax.script.ScriptEngineManager
fun main(args: Array<String>) {
val m = ScriptEngineManager()
val e = m.getEngineByName("nashorn")
// The following JSObject wraps this list
val l = mutableListOf<Any>()
l.add("hello")
l.add("world")
l.add(true)
l.add(1)
val jsObj = object : AbstractJSObject() {
override fun getMember(name: String?): Any? {
if (name == "map") {
// return a functional interface object - nashorn will treat it like
// script function!
return Function { callback: JSObject ->
val res = l.map {
// call callback on each object and add the result to new list
callback.call(null, it)
}
// return fresh list as result of map (or this could be another wrapper)
res
}
} else {
// unknown property
return null
}
}
}
e.put("obj", jsObj)
// map each String to it's uppercase and print result of map
e.eval("print(obj.map(function(x) '\"'+x.toString()+'\"'))");
}
AbstractJSObject :: getMemberは文字列スイッチで実装できますか? publicメソッドgetMember(String name){switch(name){case "map":return(Function)コールバック - > {...};デフォルト:nullを返します。 }} –
srborlongan
Functionの値は、List <>値に収集することによっても作成できます:callback - > l.stream()。map(obj - > callback.call(null、obj))。 Collectors.toList()); –
srborlongan
私は、提案の本質がはっきりと見られるように、ストリームなどを避けたがっていました。 –