在java中使用scriptenengine,我如何提取函数列表
Using ScriptEngine in java, How can I extract function list?
使用Jsoup,我提取html文件中的JavaScript部分。并将其存储为java字符串对象
和我想提取函数列表,变量列表在js的函数使用javax.script.ScriptEngine
JavaScript部分有几个函数段。
特异)
function a() {
var a_1;
var a_2
...
}
function b() {
var b_1;
var b_2;
...
}
function c() {
var c_1;
var c_2;
...
}
我的目标就在下面
列表funcList
bc
列表varListA
a_1a₂…
列表varListB
b_1b_2…
列表varListC
c₁c₂…
我如何提取函数列表和变量列表(或值)?
我认为你可以通过在引擎中加载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脚本引擎的内部机制(因此使用不安全)。
这很棘手。ScriptEngine
API似乎不适合检查代码。所以,我有这样一个很难看的解用instance of
和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);
}
}
我也有类似的问题。也许它会对别人有帮助。我使用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();
}
}
从脚本中获取函数。我没有找到其他方法如何从脚本中获得所有可调用的方法,除了反射。是的,我知道这种方法取决于ScriptEngine实现,但它是唯一的一个:)
public List getInvokableList() throws ScriptException {
List list = new ArrayList();
try {
Class compiledClass = compiledScript.getClass();
Field clasz = compiledClass.getDeclaredField("clasz");
clasz.setAccessible(true);
Class scrClass = (Class)clasz.get(compiledScript);
Method[] methods = scrClass.getDeclaredMethods();
clasz.setAccessible(false);
for (int i = 0, j = methods.length; i < j; i++) {
Annotation[] annotations = methods[i].getDeclaredAnnotations();
boolean ok = false;
for (int k = 0, m = annotations.length; k < m; k++) {
ok = annotations[k] instanceof CalculatedField;
if (ok) break;
}
if (ok)
list.add(methods[i].getName());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
}
return list;
}
在我的任务中,我不需要所有的函数,为此我创建了自定义注释并在脚本中使用它:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CalculatedField {
}
Script example:
import com.vssk.CalculatedField;
def utilFunc(s) {
s
}
@CalculatedField
def func3() {
utilFunc('Testing func from groovy')
}
调用脚本函数的方法:
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
相关文章:
- 在数据提取完成之前进行页面渲染
- 如何在Javascript中从字符串中提取某些单词
- RegEx JavaScript:数字后的符号提取
- 如何在内联依赖项并将图像转换为dataURI的情况下完全提取网页
- Regex提取URL返回数组的一部分;未定义”;
- 如何提取“;href"最近列表项中的属性值
- 使用时刻.js从日期时间中提取时间
- 通过javascript从会话中提取用户名
- HTML页面如何提取通过表单传递的参数
- 是否可以自动拉取“随机”;标签“;从一长串文本中提取
- innerHTML的子字符串可以在初始调用时提取吗
- 如何使用phonegap从安卓设备中提取联系人的字母顺序
- 如何从特定页面中提取php变量值
- 从字符串中提取年份的Javascript正则表达式
- 如何使用JavaScript提取此url的一部分
- 使用BeautifulSoup从Javascript中提取文本以获得关注者数量
- 使用javascript从字符串中提取浮点数
- 如何使用另一个字符串作为模板从字符串中提取数据
- 如何使用angular js从2个表(在sql server中)中提取数据
- 在不使用lodash-get的情况下从json中提取深层属性