让Rhino的E4X在JDK5下运行

Rhino( http://www.mozilla.org/rhino/)已经被集成在JDK6中的JSR223 Scripting框架中。但是在JDK5中使用Rhino的E4X功能是不行的,因为默认情况下该功能是被关闭的,如果想要在JDK5中使用Rhino的E4X功能,就需要一些额外的代码。

查看Rhino的ContextFactory的源代码可以看到,与E4X相关的Context.FEATURE_E4X是在JDK6的时候才返回true的。所以首先需要实现自己的ContextFactory,做如下修改就可以了:

java 代码
  1. public class E4XContextFactory extends ContextFactory {   
  2.  protected boolean hasFeature(Context cx, int featureIndex) {   
  3.   switch (featureIndex) {   
  4.   case Context.FEATURE_E4X:   
  5.    return true;   
  6.   }   
  7.   return super.hasFeature(cx, featureIndex);   
  8.   
  9.  }   
  10.   
  11. }   

我们需要在自己的ContextFactory生成的Context中执行JavaScript,这个时候需要使用ContextAction,实现该接口:

下面是一个可以运行某个JavaScript文件的ContextAction实现:

java 代码
  1. private static class E4XAction implements ContextAction {   
  2.   private File file;   
  3.   
  4.   public E4XAction(File file) {   
  5.    this.file = file;   
  6.   }   
  7.   
  8.   public Object run(Context context) {   
  9.    try {   
  10.   
  11.     Global global = new Global(context); //参考注意事项2   
  12.     InputStream ins = new FileInputStream(file);   
  13.   
  14.     Reader reader = new InputStreamReader(ins);   
  15.     Object result = context.evaluateReader(global, reader, file   
  16.       .getName(), 1null);   
  17.     return Context.toString(result);   
  18.   
  19.    } catch (Exception e) {   
  20.     e.printStackTrace();   
  21.    }   
  22.    return “!!!ERROR!!!”;   
  23.   }   
  24.   
  25.  }   
  26.   

接下来就是使用此ContextAction了:

java 代码
  1. File file = new File(”e4xsimple.js”);   
  2. E4XContextFactory ecf = new E4XContextFactory();   
  3. System.out.println(ecf.call(new E4XAction(file))).toString());  
测试文件e4xsimple.js的内容为:
js 代码
  1. var a = <order><person>alex</person></order>;   
  2.   
  3. print (a.person);   
  4.     

输出是:alex

注意事项

1.把下载到的XMLBeans的lib下面的xbean.jar和jsr173_1.0_api.jar都放到classpath中,否则会报错,说找不到XML这个名字。如果你只放了xbean.jar的话,也会出错。我一开始只放了xbean.jar,出错提示不明显,后来我debug跟踪到 org.mozilla.javascript.xmlimpl.XMLLib在初始化的时候出现了javax.xml.stream的相关类的ClassNotFound的错误,导致XML相关的名称没有被加载。这是因为xbean.jar依赖于jsr173_1.0_api.jar。而网上的教程都说只放xbean.jar就可以,在JDK6中是可以的,因为JDK6的rt.jar中已经添加了JSR173,即javax.xml.stream包,而JDK5中是没有的。

2.如果你想在JavaScript中使用print命令,可以把org.mozilla.javascript.tools.shell.Global拷贝过来加以修改就可以了。我就是这么做的,在执行脚本的时候使用该Global对象。需要去掉一些不用的名称使得编译通过。

你可能感兴趣的:(JavaScript,xml,框架,脚本)