我正在写一些可称为工作流引擎的东西。为此,我已根据特定的XML Schema将工作流的数据模型创建为XML。
以下是表示此数据模型的XML示例:
<dm:agentModel xmlns:dm="ProcessObjects" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ProcessObjects agentModel.xsd">
<dm:cfp isList="false" objName="myCFP"></dm:cfp>
<dm:proposal isList="true" objName="receivedProposals"></dm:proposal>
<dm:feedbackList objName="cfpFeedbacks">
<dm:item>
<dm:to>Andrew</dm:to>
<dm:from>Paul</dm:from>
<dm:heading>That is bad</dm:heading>
<dm:body>Fix points a, b and c, please.</dm:body>
</dm:item>
<dm:item>
<dm:to>Frank</dm:to>
<dm:from>Paul</dm:from>
<dm:heading>Very good!</dm:heading>
<dm:body>I see no drawbacks. You can also ask Matthew for additional feedback.</dm:body>
</dm:item>
</dm:feedbackList>
</dm:agentModel>
工作流定义由用户通过Web编辑器定义,是BPMN XML标准。为了不深入细节,我需要让用户定义一些脚本界面。用户需要能够写出如下内容:
/*JavaScript code*/
for(var i=0; i<agentModel.cfpFeedbacks.length; i++) {
if(agentModel.cfpFeedbacks[i].to == "Frank") {
agentModel.cfpFeedbacks[i].to += " Sinatra";
}
}
到目前为止,我编写了Java类(DataModel
),可以访问上面给出的XML构建的数据。因为XML可能包含许多不同的对象,所以getter和setter看起来像:
/*Java code*/
DataModel agentModel = new DataModel(xmlString);
agentModel.getValue("cfpFeedbacks[1].to");
//returns String "Frank"
agentModel.setValue("cfpFeedbacks[0].from", "Paul Anka");
//obvious
要运行用户编写的脚本,我尝试使用Java Scripting API
/*Java code*/
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
//binding object
engine.put("agentModel", agentModel);
String script = "var i = 0;"
+ "println(agentModel.getValue(\"cfpFeedbacks[\" + i + \"].from\"));";
engine.eval(script);
哪个或多或少有效。我想要的就是这样的工作:
/*Java code*/
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
//binding object
engine.put("agentModel", agentModel);
String script = "var i = 0;"
+ "println(agentModel.cfpFeedbacks[i].from);";
/**
* any magic operations here
*/
engine.eval(script);
目标是为最终用户提供最简单的界面来编写脚本。
我有点失落,我会感激任何灵感。就个人而言,我确实考虑了三种情况:
object.field
的同义词调用object.getValue("field")
也许我看不到有一些明显的解决方法。
提前感谢您的回复,
PS。如果我的描述不清楚,或者您发现提供更多源代码是值得的,我会立即澄清问题。完成任务现在是我的首要任务。
答案 0 :(得分:0)
最好的方法是将xml反序列化为java对象,然后将结果放入引擎。
您可以直接操作通过engine.put(..)
方法
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
engine.put("a", 1);
engine.put("b", 5);
engine.eval("a = 2;");
Object result = engine.eval("c = a + b;");
System.out.println("a + b = " + result);
最后从脚本引擎获取对象并将对象序列化为xml,jackson 将非常有用