| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
- package com.script.rhino
- import com.script.*
- import org.mozilla.javascript.*
- import org.mozilla.javascript.Function
- import java.io.IOException
- import java.io.Reader
- import java.io.StringReader
- import java.lang.reflect.Method
- import java.security.*
- /**
- * Implementation of `ScriptEngine` using the Mozilla Rhino
- * interpreter.
- *
- * @author Mike Grogan
- * @author A. Sundararajan
- * @since 1.6
- */
- @Suppress("MemberVisibilityCanBePrivate")
- class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
- var accessContext: AccessControlContext? = null
- private var topLevel: RhinoTopLevel? = null
- private val indexedProps: MutableMap<Any, Any?>
- private val implementor: InterfaceImplementor
- fun run(function: (Context) -> Any?): Any? {
- return try {
- val context = Context.enter()
- function.invoke(context)
- } finally {
- Context.exit()
- }
- }
- @Throws(ScriptException::class)
- override fun eval(reader: Reader, scope: Scriptable): Any? {
- val cx = Context.enter()
- val ret: Any?
- try {
- var filename = this["javax.script.filename"] as? String
- filename = filename ?: "<Unknown source>"
- ret = cx.evaluateReader(scope, reader, filename, 1, null)
- } catch (re: RhinoException) {
- val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
- val msg: String = if (re is JavaScriptException) {
- re.value.toString()
- } else {
- re.toString()
- }
- val se = ScriptException(msg, re.sourceName(), line)
- se.initCause(re)
- throw se
- } catch (var14: IOException) {
- throw ScriptException(var14)
- } finally {
- Context.exit()
- }
- return unwrapReturnValue(ret)
- }
- override fun createBindings(): Bindings {
- return SimpleBindings()
- }
- @Throws(ScriptException::class, NoSuchMethodException::class)
- override fun invokeFunction(name: String, vararg args: Any): Any? {
- return this.invoke(null, name, *args)
- }
- @Throws(ScriptException::class, NoSuchMethodException::class)
- override fun invokeMethod(obj: Any?, name: String, vararg args: Any): Any? {
- return if (obj == null) {
- throw IllegalArgumentException("脚本对象不能为空")
- } else {
- this.invoke(obj, name, *args)
- }
- }
- @Suppress("UNCHECKED_CAST")
- @Throws(ScriptException::class, NoSuchMethodException::class)
- private operator fun invoke(thiz: Any?, name: String?, vararg args: Any?): Any? {
- var thiz1 = thiz
- val cx = Context.enter()
- val var11: Any?
- try {
- if (name == null) {
- throw NullPointerException("方法名为空")
- }
- if (thiz1 != null && thiz1 !is Scriptable) {
- thiz1 = Context.toObject(thiz1, topLevel)
- }
- val engineScope = getRuntimeScope(context)
- val localScope = if (thiz1 != null) thiz1 as Scriptable else engineScope
- val obj = ScriptableObject.getProperty(localScope, name) as? Function
- ?: throw NoSuchMethodException("no such method: $name")
- var scope = obj.parentScope
- if (scope == null) {
- scope = engineScope
- }
- val result = obj.call(cx, scope, localScope, wrapArguments(args as? Array<Any?>))
- var11 = unwrapReturnValue(result)
- } catch (re: RhinoException) {
- val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
- val se = ScriptException(re.toString(), re.sourceName(), line)
- se.initCause(re)
- throw se
- } finally {
- Context.exit()
- }
- return var11
- }
- override fun <T> getInterface(clazz: Class<T>): T? {
- return try {
- implementor.getInterface(null, clazz)
- } catch (var3: ScriptException) {
- null
- }
- }
- override fun <T> getInterface(obj: Any?, paramClass: Class<T>): T? {
- return if (obj == null) {
- throw IllegalArgumentException("脚本对象不能为空")
- } else {
- try {
- implementor.getInterface(obj, paramClass)
- } catch (var4: ScriptException) {
- null
- }
- }
- }
- override fun getRuntimeScope(context: ScriptContext): Scriptable {
- val newScope: Scriptable = ExternalScriptable(context, indexedProps)
- newScope.prototype = topLevel
- newScope.put("context", newScope, context)
- return newScope
- }
- @Throws(ScriptException::class)
- override fun compile(script: String): CompiledScript {
- return this.compile(StringReader(script) as Reader)
- }
- @Throws(ScriptException::class)
- override fun compile(script: Reader): CompiledScript {
- val cx = Context.enter()
- val ret: RhinoCompiledScript
- try {
- var fileName = this["javax.script.filename"] as? String
- if (fileName == null) {
- fileName = "<Unknown Source>"
- }
- val scr = cx.compileReader(script, fileName, 1, null)
- ret = RhinoCompiledScript(this, scr)
- } catch (var9: Exception) {
- throw ScriptException(var9)
- } finally {
- Context.exit()
- }
- return ret
- }
- fun wrapArguments(args: Array<Any?>?): Array<Any?> {
- return if (args == null) {
- Context.emptyArgs
- } else {
- val res = arrayOfNulls<Any>(args.size)
- for (i in res.indices) {
- res[i] = Context.javaToJS(args[i], topLevel)
- }
- res
- }
- }
- fun unwrapReturnValue(result: Any?): Any? {
- var result1 = result
- if (result1 is Wrapper) {
- result1 = result1.unwrap()
- }
- return if (result1 is Undefined) null else result1
- }
- init {
- if (System.getSecurityManager() != null) {
- try {
- AccessController.checkPermission(AllPermission())
- } catch (var6: AccessControlException) {
- accessContext = AccessController.getContext()
- }
- }
- val cx = Context.enter()
- try {
- topLevel = RhinoTopLevel(cx, this)
- } finally {
- Context.exit()
- }
- indexedProps = HashMap()
- implementor = object : InterfaceImplementor(this) {
- override fun isImplemented(obj: Any?, clazz: Class<*>): Boolean {
- var obj1 = obj
- return try {
- if (obj1 != null && obj1 !is Scriptable) {
- obj1 = Context.toObject(obj1, topLevel)
- }
- val engineScope = getRuntimeScope(context)
- val localScope = if (obj1 != null) obj1 as Scriptable else engineScope
- val methods = clazz.methods
- val methodsSize = methods.size
- for (index in 0 until methodsSize) {
- val method = methods[index]
- if (method.declaringClass != Any::class.java) {
- if (ScriptableObject.getProperty(
- localScope,
- method.name
- ) !is Function
- ) {
- return false
- }
- }
- }
- true
- } finally {
- Context.exit()
- }
- }
- override fun convertResult(method: Method?, res: Any?): Any? {
- method ?: return null
- val desiredType = method.returnType
- if (desiredType == Void.TYPE) return null
- return Context.jsToJava(res, desiredType)
- }
- }
- }
- @Suppress("unused")
- companion object {
- init {
- ContextFactory.initGlobal(object : ContextFactory() {
- override fun makeContext(): Context {
- val cx = super.makeContext()
- cx.languageVersion = 200
- cx.optimizationLevel = -1
- cx.setClassShutter(RhinoClassShutter)
- cx.wrapFactory = RhinoWrapFactory
- return cx
- }
- override fun hasFeature(cx: Context, featureIndex: Int): Boolean {
- return when (featureIndex) {
- Context.FEATURE_ENABLE_JAVA_MAP_ACCESS -> true
- else -> super.hasFeature(cx, featureIndex)
- }
- }
- override fun doTopCall(
- callable: Callable,
- cx: Context,
- scope: Scriptable,
- thisObj: Scriptable,
- args: Array<Any>
- ): Any? {
- var accContext: AccessControlContext? = null
- val global = ScriptableObject.getTopLevelScope(scope)
- val globalProto = global.prototype
- if (globalProto is RhinoTopLevel) {
- accContext = globalProto.accessContext
- }
- return if (accContext != null) AccessController.doPrivileged(
- PrivilegedAction {
- superDoTopCall(callable, cx, scope, thisObj, args)
- }, accContext
- ) else superDoTopCall(
- callable,
- cx,
- scope,
- thisObj,
- args
- )
- }
- private fun superDoTopCall(
- callable: Callable,
- cx: Context,
- scope: Scriptable,
- thisObj: Scriptable,
- args: Array<Any>
- ): Any? {
- return super.doTopCall(callable, cx, scope, thisObj, args)
- }
- })
- }
- }
- }
|