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

沪ICP备08000575号