This commit is contained in:
Horis
2025-05-22 19:39:01 +08:00
parent 7960ed9a06
commit 53dea64715
14 changed files with 171 additions and 61 deletions
@@ -0,0 +1,9 @@
package com.script.rhino
import org.mozilla.javascript.Scriptable
fun interface JavaObjectWrapFactory {
fun wrap(scope: Scriptable?, javaObject: Any, staticType: Class<*>?): Scriptable
}
@@ -0,0 +1,43 @@
package com.script.rhino
import org.mozilla.javascript.NativeJavaObject
import org.mozilla.javascript.Scriptable
class ReadOnlyJavaObject(scope: Scriptable?, javaObject: Any, staticType: Class<*>?) :
NativeJavaObject(scope, javaObject, staticType) {
override fun has(name: String, start: Scriptable): Boolean {
if (name.length > 3 && name.startsWith("set")) {
val name = name.substring(3).replaceFirstChar { it.lowercase() }
if (super.has(name, start)) {
return false
}
}
return super.has(name, start)
}
override fun get(name: String, start: Scriptable): Any? {
if (name.length > 3 && name.startsWith("set")) {
val name = name.substring(3).replaceFirstChar { it.lowercase() }
if (super.has(name, start)) {
return NOT_FOUND
}
}
return super.get(name, start)
}
override fun put(
name: String?,
start: Scriptable?,
value: Any?
) {
// do nothing
}
companion object {
val factory = JavaObjectWrapFactory { scope, javaObject, staticType ->
ReadOnlyJavaObject(scope, javaObject, staticType)
}
}
}
@@ -45,6 +45,8 @@ import org.mozilla.javascript.WrapFactory
*/
object RhinoWrapFactory : WrapFactory() {
private val factories = hashMapOf<Class<*>, JavaObjectWrapFactory>()
override fun wrapAsJavaObject(
cx: Context,
scope: Scriptable?,
@@ -54,7 +56,8 @@ object RhinoWrapFactory : WrapFactory() {
if (!RhinoClassShutter.visibleToScripts(javaObject)) {
return null
}
return super.wrapAsJavaObject(cx, scope, javaObject, staticType)
return wrapOrNull(scope, javaObject, staticType)
?: super.wrapAsJavaObject(cx, scope, javaObject, staticType)
}
override fun wrapJavaClass(
@@ -71,4 +74,18 @@ object RhinoWrapFactory : WrapFactory() {
return RhinoClassShutter.wrapJavaClass(scope, javaClass)
}
private fun wrapOrNull(
scope: Scriptable?,
javaObject: Any,
staticType: Class<*>?
): Scriptable? {
return factories[javaObject.javaClass]?.wrap(scope, javaObject, staticType)
}
fun register(clazz: Class<*>, factory: JavaObjectWrapFactory) {
if (!factories.contains(clazz)) {
factories.put(clazz, factory)
}
}
}