在java中使用ScriptEngine,如何提取函数列表?

在java中使用ScriptEngine,如何提取函数列表?,java,javascript,scriptengine,Java,Javascript,Scriptengine,使用Jsoup,我提取html文件中的JavaScript部分。并将其存储为java字符串对象 我想使用javax.script.ScriptEngine JavaScript部分有几个功能部分 ex) 我的目标就在下面 列表函数列表 a B c 列表varListA a_1 a_2 列表varListB b_1 b_2 列表varListC c_1 c_2 如何提取函数列表和变量列表(或者可能是值)?我认为您可以在引擎中加载javascript后使用javascript自省来实现这一点-

使用Jsoup,我提取html文件中的JavaScript部分。并将其存储为java字符串对象

我想使用javax.script.ScriptEngine

JavaScript部分有几个功能部分

ex)

我的目标就在下面

列表函数列表 a B c

列表varListA a_1 a_2

列表varListB b_1 b_2

列表varListC c_1 c_2


如何提取函数列表和变量列表(或者可能是值)?

我认为您可以在引擎中加载javascript后使用javascript自省来实现这一点-例如,对于函数:

ScriptEngine engine;
// create the engine and have it load your javascript
Bindings bind = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Set<String> allAttributes = bind.keySet();
Set<String> allFunctions = new HashSet<String>();
for ( String attr : allAttributes ) {
    if ( "function".equals( engine.eval("typeof " + attr) ) ) {
        allFunctions.add(attr);
    }
}
System.out.println(allFunctions);
脚本引擎;
//创建引擎并让它加载javascript
Bindings bind=engine.getBindings(ScriptContext.engine\u范围);
设置allAttributes=bind.keySet();
Set allFunctions=new HashSet();
for(字符串属性:allAttributes){
if(“function.”等于(engine.eval(“typeof”+attr))){
allFunctions.add(attr);
}
}
System.out.println(所有函数);

我还没有找到一种方法来提取函数中的变量(局部变量),而不深入研究javascript脚本引擎的内部机制(因此使用起来不安全)

我认为您可以在引擎中加载javascript后使用javascript内省来实现这一点,例如,对于函数:

ScriptEngine engine;
// create the engine and have it load your javascript
Bindings bind = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Set<String> allAttributes = bind.keySet();
Set<String> allFunctions = new HashSet<String>();
for ( String attr : allAttributes ) {
    if ( "function".equals( engine.eval("typeof " + attr) ) ) {
        allFunctions.add(attr);
    }
}
System.out.println(allFunctions);
脚本引擎;
//创建引擎并让它加载javascript
Bindings bind=engine.getBindings(ScriptContext.engine\u范围);
设置allAttributes=bind.keySet();
Set allFunctions=new HashSet();
for(字符串属性:allAttributes){
if(“function.”等于(engine.eval(“typeof”+attr))){
allFunctions.add(attr);
}
}
System.out.println(所有函数);

我还没有找到一种方法来提取函数中的变量(局部变量),而不深入研究javascript脚本引擎的内部机制(因此使用起来不安全)

这相当棘手<代码>脚本引擎API似乎不适合检查代码。所以,我有这样一个非常丑陋的解决方案,使用
实例
cast
操作符

       Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
       for (Map.Entry<String, Object> scopeEntry : bindings.entrySet()) {
           Object value = scopeEntry.getValue();
           String name = scopeEntry.getKey();
           if (value instanceof NativeFunction) {
               log.info("Function -> " + name);
               NativeFunction function = NativeFunction.class.cast(value);
               DebuggableScript debuggableFunction = function.getDebuggableView();
               for (int i = 0; i < debuggableFunction.getParamAndVarCount(); i++) {
                   log.info("First level arg: " + debuggableFunction.getParamOrVarName(i));
               }
           } else if (value instanceof Undefined
                   || value instanceof String
                   || value instanceof Number) {
               log.info("Global arg -> " + name);
           }
       }
Bindings Bindings=engine.getBindings(ScriptContext.engine\u范围);
对于(Map.Entry scopeEntry:bindings.entrySet()){
对象值=scopeEntry.getValue();
字符串名称=scopeEntry.getKey();
if(NativeFunction的值实例){
log.info(“函数->”+名称);
NativeFunction=NativeFunction.class.cast(值);
DebuggableScript debuggableFunction=function.getDebuggableView();
对于(int i=0;i”+名称);
}
}

这相当棘手<代码>脚本引擎API似乎不适合检查代码。所以,我有这样一个非常丑陋的解决方案,使用
实例
cast
操作符

       Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
       for (Map.Entry<String, Object> scopeEntry : bindings.entrySet()) {
           Object value = scopeEntry.getValue();
           String name = scopeEntry.getKey();
           if (value instanceof NativeFunction) {
               log.info("Function -> " + name);
               NativeFunction function = NativeFunction.class.cast(value);
               DebuggableScript debuggableFunction = function.getDebuggableView();
               for (int i = 0; i < debuggableFunction.getParamAndVarCount(); i++) {
                   log.info("First level arg: " + debuggableFunction.getParamOrVarName(i));
               }
           } else if (value instanceof Undefined
                   || value instanceof String
                   || value instanceof Number) {
               log.info("Global arg -> " + name);
           }
       }
Bindings Bindings=engine.getBindings(ScriptContext.engine\u范围);
对于(Map.Entry scopeEntry:bindings.entrySet()){
对象值=scopeEntry.getValue();
字符串名称=scopeEntry.getKey();
if(NativeFunction的值实例){
log.info(“函数->”+名称);
NativeFunction=NativeFunction.class.cast(值);
DebuggableScript debuggableFunction=function.getDebuggableView();
对于(int i=0;i”+名称);
}
}

我也有类似的问题。也许这对其他人会有帮助。 我使用groove作为脚本语言。我的任务是从脚本中检索所有可调用的函数。然后根据一些条件过滤这些函数

不幸的是,这种方法只对groovy有用

获取脚本引擎:

public ScriptEngine getEngine() throws Exception {
    if (engine == null)
        engine = new ScriptEngineManager().getEngineByName(scriptType);
    if (engine == null) 
        throw new Exception("Could not find implementation of " + scriptType);
    return engine;
}  
public void evaluateScript(String script) throws Exception {
    Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
    bindings.putAll(binding);
    try {
        if (engine instanceof Compilable)
            compiledScript = ((Compilable)getEngine()).compile(script);
        getEngine().eval(script);
    } catch (Throwable e) {
        e.printStackTrace();
    } 
}
public Object executeFunc(String name) throws Exception {
    return ((Invocable)getEngine()).invokeFunction(name);  
}
编译和评估脚本:

public ScriptEngine getEngine() throws Exception {
    if (engine == null)
        engine = new ScriptEngineManager().getEngineByName(scriptType);
    if (engine == null) 
        throw new Exception("Could not find implementation of " + scriptType);
    return engine;
}  
public void evaluateScript(String script) throws Exception {
    Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
    bindings.putAll(binding);
    try {
        if (engine instanceof Compilable)
            compiledScript = ((Compilable)getEngine()).compile(script);
        getEngine().eval(script);
    } catch (Throwable e) {
        e.printStackTrace();
    } 
}
public Object executeFunc(String name) throws Exception {
    return ((Invocable)getEngine()).invokeFunction(name);  
}
从脚本获取函数。除了反射之外,我没有找到从脚本获取所有可调用方法的其他方法。是的,我知道这种方法依赖于ScriptEngine实现,但这是唯一的一种:)

脚本示例:

import com.vssk.CalculatedField;

def utilFunc(s) {     
    s
}

@CalculatedField
def func3() {     
    utilFunc('Testing func from groovy')
}
通过名称调用脚本函数的方法:

public ScriptEngine getEngine() throws Exception {
    if (engine == null)
        engine = new ScriptEngineManager().getEngineByName(scriptType);
    if (engine == null) 
        throw new Exception("Could not find implementation of " + scriptType);
    return engine;
}  
public void evaluateScript(String script) throws Exception {
    Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
    bindings.putAll(binding);
    try {
        if (engine instanceof Compilable)
            compiledScript = ((Compilable)getEngine()).compile(script);
        getEngine().eval(script);
    } catch (Throwable e) {
        e.printStackTrace();
    } 
}
public Object executeFunc(String name) throws Exception {
    return ((Invocable)getEngine()).invokeFunction(name);  
}

我也有类似的问题。也许这对其他人会有帮助。 我使用groove作为脚本语言。我的任务是从脚本中检索所有可调用的函数。然后根据一些条件过滤这些函数

不幸的是,这种方法只对groovy有用

获取脚本引擎:

public ScriptEngine getEngine() throws Exception {
    if (engine == null)
        engine = new ScriptEngineManager().getEngineByName(scriptType);
    if (engine == null) 
        throw new Exception("Could not find implementation of " + scriptType);
    return engine;
}  
public void evaluateScript(String script) throws Exception {
    Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
    bindings.putAll(binding);
    try {
        if (engine instanceof Compilable)
            compiledScript = ((Compilable)getEngine()).compile(script);
        getEngine().eval(script);
    } catch (Throwable e) {
        e.printStackTrace();
    } 
}
public Object executeFunc(String name) throws Exception {
    return ((Invocable)getEngine()).invokeFunction(name);  
}
编译和评估脚本:

public ScriptEngine getEngine() throws Exception {
    if (engine == null)
        engine = new ScriptEngineManager().getEngineByName(scriptType);
    if (engine == null) 
        throw new Exception("Could not find implementation of " + scriptType);
    return engine;
}  
public void evaluateScript(String script) throws Exception {
    Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
    bindings.putAll(binding);
    try {
        if (engine instanceof Compilable)
            compiledScript = ((Compilable)getEngine()).compile(script);
        getEngine().eval(script);
    } catch (Throwable e) {
        e.printStackTrace();
    } 
}
public Object executeFunc(String name) throws Exception {
    return ((Invocable)getEngine()).invokeFunction(name);  
}
从脚本获取函数。除了反射之外,我没有找到从脚本获取所有可调用方法的其他方法。是的,我知道这种方法依赖于ScriptEngine实现,但这是唯一的一种:)

脚本示例:

import com.vssk.CalculatedField;

def utilFunc(s) {     
    s
}

@CalculatedField
def func3() {     
    utilFunc('Testing func from groovy')
}
通过名称调用脚本函数的方法:

public ScriptEngine getEngine() throws Exception {
    if (engine == null)
        engine = new ScriptEngineManager().getEngineByName(scriptType);
    if (engine == null) 
        throw new Exception("Could not find implementation of " + scriptType);
    return engine;
}  
public void evaluateScript(String script) throws Exception {
    Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
    bindings.putAll(binding);
    try {
        if (engine instanceof Compilable)
            compiledScript = ((Compilable)getEngine()).compile(script);
        getEngine().eval(script);
    } catch (Throwable e) {
        e.printStackTrace();
    } 
}
public Object executeFunc(String name) throws Exception {
    return ((Invocable)getEngine()).invokeFunction(name);  
}

您希望执行代码还是静态检查代码<代码>脚本引擎可能适合执行,尽管它缺少DOM之类的东西。如果您想检查代码,AST解析器更合适(例如Antlr或Mozilla)