以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 版权所有