以Groovy脚本语言和JDK1.6自带的JavaScrit脚本语言为例。
Groovy
Groovy的模型定义截图如下:

在这里 GroovyAction要实现一个run方法,run方法使用Java编写的,其代码在xworker.actions.GroovyActions,代码如下:
package xworker.actions;
import groovy.lang.Binding;
import groovy.lang.Script;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.MultipleCompilationErrorsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmeta.Action;
import org.xmeta.ActionContext;
import org.xmeta.Bindings;
import org.xmeta.Thing;
import org.xmeta.World;
import org.xmeta.util.UtilAction;
public class GroovyAction {
private static Logger log = LoggerFactory.getLogger(GroovyAction.class);
public static Object run(ActionContext context) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException{
//脚本的上下文
Bindings bindings = context.getScope(context.getScopesSize() - 2);
World world = bindings.world;
Action action = null;
if(bindings.caller instanceof Thing){
Thing actionThing = (Thing) bindings.caller;
action = actionThing.getAction();
if(action.lastModified != actionThing.getMetadata().getLastModified()){
action.changed = true;
}
}else{
action = (Action) bindings.caller;
}
if(action == null){
log.error("er");
}
//log.info("run groovy action : " + action.thing.getMetadata().getPath());
if(action.actionClass == null || action.changed){
//查看代码是否需要重新编译
boolean recompile = false;
if(action.changed){
recompile = true;
}
if(action.actionClass == null){
File classFile = new File(action.classFileName);
if(!classFile.exists()){
recompile = true;
}
}
if(recompile){
//重新编译并装载脚本
org.codehaus.groovy.tools.Compiler compiler;
Properties prop = new Properties();
prop.setProperty("groovy.target.directory", world.getPath()
+ "/actionClasses");
prop.setProperty("groovy.classpath", action.getCompileClassPath());
CompilerConfiguration config = new CompilerConfiguration(prop);
//System.out.println(config.getClasspath());
compiler = new org.codehaus.groovy.tools.Compiler(config);
//更新代码
File codeFile = new File(action.fileName + ".groovy");
if(!codeFile.exists()){
codeFile.getParentFile().mkdirs();
}
FileOutputStream fout = new FileOutputStream(codeFile);
try{
fout.write(("/*path:" + action.getThing().getMetadata().getPath() + "*/
").getBytes());
fout.write(("package " + action.packageName + ";
").getBytes());
fout.write(action.code.getBytes());
}finally{
fout.close();
}
//int dotIndex = action.className.lastIndexOf(".");
//String compileClassName = action.className.substring(dotIndex + 1, action.className.length());
//compiler.compile(file);
try{
compiler.compile(codeFile);
//log.info("compile groovy " + action.getThing().getMetadata().getPath());
action.updateCompileTime();
}catch(MultipleCompilationErrorsException me){
log.error("compile groovy code : " + action.getThing().getMetadata().getPath());
throw me;
}
}
action.changed = false;
}
if(action.actionClass == null){
action.actionClass = action.classLoader.loadClass(action.className);
java.lang.Compiler.compileClass(action.actionClass);
}
if(action.actionClass != null){
Script script = (Script) action.actionClass .newInstance();//(Script) action.getData("script");
Bindings bindings1 = context.push(null);
bindings1.put("actionContext", context);
try{
context.pushAction(action);
Binding binding = new Binding(context);
script.setBinding(binding);
Object result = script.run();
return result;
}finally{
//bindings1.remove("self");
context.popAction();
bindings1.remove("actionContext");
Bindings varBindings = UtilAction.getVarScope(action.getThing(), context);
if(varBindings != null){
varBindings.putAll(bindings1);
}
context.pop();
}
}else{
log.warn("groovy action " + action.getThing().getMetadata().getPath() + " class is null");
}
return null;
}
}
JdkScript
JdkScript的编辑截图:

可以看到和GroovyAction基本是一样的,要实现一个run方法,而JdkScript的run方法的实现是:
package xworker.lang.actions;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import org.xmeta.Action;
import org.xmeta.ActionContext;
import org.xmeta.ActionException;
import org.xmeta.Bindings;
import org.xmeta.Thing;
import org.xmeta.World;
import org.xmeta.util.UtilAction;
public class JdkScriptCreator {
static World world = World.getInstance();
public static Object run(ActionContext actionContext) throws Exception{
ScriptEngineManager manager = (ScriptEngineManager) world.getData("JavaScriptEngineManager");
if(manager == null){
manager = new ScriptEngineManager();
world.setData("JavaScriptEngineManager", manager);
}
Bindings bindings = actionContext.getScope(actionContext.getScopesSize() - 2);
Thing self = null;
Action action = null;
if(bindings.caller instanceof Thing){
self = (Thing) bindings.caller;
action = self.getAction();
}else{
action = (Action) bindings.caller;
self = action.getThing();
}
ScriptEngine engine = manager.getEngineByName(self.getString("language"));
if(engine != null){
String jsFileName = UtilAction.getActionCodeFilePath(self, "js");
File jsFile = new File(jsFileName);
if(!jsFile.exists() || action.changed || self.getMetadata().getLastModified() > jsFile.lastModified()){
action.changed = false;
if(!jsFile.exists()){
jsFile.getParentFile().mkdirs();
}
FileOutputStream fout = new FileOutputStream(jsFile);
fout.write(("/*path:" + action.getThing().getMetadata().getPath() + "*/
").getBytes());
fout.write(action.code.getBytes());
fout.flush();
fout.close();
jsFile = new File(jsFileName);
}
FileReader fr = new FileReader(jsFile);
Bindings topBindings = actionContext.push();
try{
topBindings.put("actionContext", actionContext);
topBindings.put("world", world);
if(actionContext.getScopesSize() >= 5){
Bindings callerBindings = actionContext.getScope(actionContext.getScopesSize() - 5);
Object self1 = callerBindings.get("self");
topBindings.put("self", self1);
}
Object value = engine.eval(fr, new ActionScriptContext(actionContext));
return value;
}finally{
actionContext.pop();
String varScope = self.getString("varScope");
if("Global".equals(varScope)){
actionContext.getScope(0).putAll(topBindings);
}else{
try{
int scopeIndex = Integer.parseInt(varScope);
if(scopeIndex >= 0){
actionContext.getScope(scopeIndex).putAll(topBindings);
}else{
actionContext.getScope(actionContext.getScopesSize() + scopeIndex).putAll(topBindings);
}
}catch(Exception e){
Bindings actionBindings = actionContext.getScope(varScope);
if(actionBindings != null){
actionBindings.putAll(topBindings);
}else{
bindings.putAll(topBindings);
}
}
}
}
}else{
throw new ActionException("Can not find script engine : " + self.getString("language"));
}
}
}
Copyright © 2007-2014 XWorker.org 版权所有